Selection with rich:extendedDataTable via <a4j:ajax listener> not called when an <rich:table required="true"> is in the table
jmsjr Nov 27, 2012 2:41 AMRichFaces 4.2.3-Final
JBoss 7.1.1 (Brontes)
I need to have input elements within the each row of the a rich:extendedDataTable. However, as soon as I have any input field in a rich:column, the a4j:ajax call is no longer made.
Here is a sample where the selection DOES work, as everything inside a rich:column is just a h:outputText
testExtendedDataTable.xhtml
{code}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j">
<h:head></h:head>
<body>
<h:form id="aForm">
<rich:extendedDataTable id="sampleTable" value="#{tableBean.rows}" var="row"
selectionMode="single"
selection="#{tableBean.selection}">
<a4j:ajax execute="sampleTable" event="selectionchange" render="outputSelection" listener="#{tableBean.selectionListener}"/>
<rich:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{row.name}"/>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Required"/>
</f:facet>
<h:outputText value="#{row.required}"/>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Some Date"/>
</f:facet>
<h:outputText value="#{row.someDate}"/>
</rich:column>
</rich:extendedDataTable>
<a4j:outputPanel id="outputSelection">
Current Selection: <h:outputText value="#{tableBean.selectedRow.name}" />
</a4j:outputPanel>
</h:form>
</body>
</html>
{code}
Here is the backing bean which stores the collection ( The sample code was based off the showcases in RichFaces )
{code}
package test;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.AjaxBehaviorEvent;
import org.richfaces.component.UIExtendedDataTable;
@ManagedBean
@ViewScoped
public class TableBean implements Serializable {
private List<RowBean> rows;
private Collection<Object> selection;
private RowBean selectedRow;
public RowBean getSelectedRow() {
return selectedRow;
}
public void setSelectedRow(RowBean selectedRow) {
this.selectedRow = selectedRow;
}
public List<RowBean> getRows() {
return rows;
}
public void setRows(List<RowBean> rows) {
this.rows = rows;
}
public Collection<Object> getSelection() {
return selection;
}
public void setSelection(Collection<Object> selection) {
this.selection = selection;
}
public void selectionListener(AjaxBehaviorEvent event) {
UIExtendedDataTable dataTable = (UIExtendedDataTable) event.getComponent();
Object originalKey = dataTable.getRowKey();
setSelectedRow( null );
for (Object selectionKey : selection) {
dataTable.setRowKey(selectionKey);
if (dataTable.isRowAvailable()) {
setSelectedRow( (RowBean) dataTable.getRowData() );
}
}
dataTable.setRowKey(originalKey);
}
@PostConstruct
public void init() {
setRows( new ArrayList<RowBean>() );
RowBean row1 = new RowBean();
row1.setName("John Smith");
row1.setRequired(true);
row1.setSomeDate(null);
RowBean row2 = new RowBean();
row2.setName("Jane Smith");
row2.setRequired(false);
row2.setSomeDate(new Date());
getRows().add(row1);
getRows().add(row2);
}
}
{code}
Here is the backing bean which stores the row:
{code}
package test;
import java.io.Serializable;
import java.util.Date;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
public class RowBean implements Serializable {
public String name;
public boolean required;
public Date someDate;
public String getName() {
return name;
}
public boolean isRequired() {
return required;
}
public Date getSomeDate() {
return someDate;
}
public void setName(String name) {
this.name = name;
}
public void setRequired(boolean required) {
this.required = required;
}
public void setSomeDate(Date someDate) {
this.someDate = someDate;
}
}
{code}
Deploy, and selecting between the two rows will update the lower panel to show the currently selected row.
However, if I change a rich:column so that it now has an h:selectBooleanCheckbox, or the date becomes a rich:calendar, then the selection listener specified by the listener attribute in a4j:ajax is no longer called:
{code}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j">
<h:head></h:head>
<body>
<h:form id="aForm">
<rich:extendedDataTable id="sampleTable" value="#{tableBean.rows}" var="row"
selectionMode="single"
selection="#{tableBean.selection}">
<a4j:ajax execute="sampleTable" event="selectionchange" render="outputSelection" listener="#{tableBean.selectionListener}"/>
<rich:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{row.name}"/>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Required"/>
</f:facet>
<h:selectBooleanCheckbox id="contactIntentionToClaim" value="#{row.required}"/>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Some Date"/>
</f:facet>
<h:outputText value="#{row.someDate}"/>
</rich:column>
</rich:extendedDataTable>
<a4j:outputPanel id="outputSelection">
Current Selection: <h:outputText value="#{tableBean.selectedRow.name}" />
</a4j:outputPanel>
</h:form>
</body>
</html>
{code}
Putting in logging messages into TableBean.selectionListener() method shows that the method is no longer being called.
Anyone seen this before ?