Another "No component found to process as 'ajaxSingle' for clientId"
sstair Mar 10, 2011 6:07 PMI've seen people asking about this warning before, but none of the responses are applicable.
I'm using Rich Faces 3.3.2 SR1 (I know, but there is overhead involved in moving to JSF 2).
I've tried to abstract this issue down to the simplest possible reproducible set of code.
I've got a rich:dataTable displaying a list of objects and a checkbox for each object. If the object's key is an Integer, everything works fine and I see something like "setSelected[3](false)" in the output. If the object's key is a String, I get the "WARN AjaxViewRoot:241 - No component found to process as 'ajaxSingle' for clientId..." warning and my setSelected method isn't called. The output in the a4j:log in the page are essentially identical, with no warnings.
Here is my data object, IntegerClass. StringClass is exactly the same, only every occurance of "Integer" is replaced with "String".
{code}
package com;
public class IntegerClass {
private int id;
private boolean selected;
public IntegerClass(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
System.out.println("setSelected[" + getId() + "](" + selected + ")");
this.selected = selected;
}
}
{code}
Here is my class which extends ExtendedDataModel. StringModel is exactly the same, except the objects are instantiated with the Strings "1", "2", etc...
{code}
package com;
import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import javax.faces.context.FacesContext;
import org.ajax4jsf.model.DataVisitor;
import org.ajax4jsf.model.ExtendedDataModel;
import org.ajax4jsf.model.Range;
import com.nvidia.webui.base.sort.SortField;
public class IntegerModel extends ExtendedDataModel implements Serializable {
private static final int NUMBER = 10;
private static final IntegerClass[] objects = new IntegerClass[NUMBER];
static {
for (int i = 0; i < NUMBER; i++) {
objects[i] = new IntegerClass(i);
}
}
// The current primary key
protected Object currentRowKey;
// The data corresponding to the current primary key
protected IntegerClass currentRow;
protected List<IntegerClass> getData(int from, int count, List<SortField> sorts) {
return Arrays.asList(objects);
}
/**
* Gets the primary key of the current row
*/
@Override
public Object getRowKey() {
return currentRowKey;
}
/**
* Sets the primary key of the current row
*/
@Override
public void setRowKey(Object key) {
currentRowKey = key;
if (key != null) {
for (IntegerClass obj : objects) {
if (key.equals(obj.getId())) {
currentRow = obj;
}
}
}
}
@Override
public void walk(FacesContext context, DataVisitor visitor, Range range, Object argument) throws IOException {
// Allow the RichFaces visitor implementation to process the data
for (IntegerClass obj : objects) {
visitor.process(context, obj.getId(), argument);
}
}
@Override
public int getRowCount() {
return objects.length;
}
@Override
public Object getRowData() {
return currentRow;
}
@Override
public boolean isRowAvailable() {
return !(currentRow == null);
}
@Override
public int getRowIndex() {
throw new UnsupportedOperationException();
}
@Override
public Object getWrappedData() {
throw new UnsupportedOperationException();
}
@Override
public void setRowIndex(int arg0) {
throw new UnsupportedOperationException();
}
@Override
public void setWrappedData(Object arg0) {
throw new UnsupportedOperationException();
}
}
{code}
Here is the Integer display page, once again the String version is identical except for the name changes.
{code:xml}
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html" xmlns:rich="http://richfaces.org/rich" xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j">
<ui:composition template="/view/layout/base.xhtml">
<ui:define name="body">
<h:form id="IntegerForm">
<rich:dataTable id="IntegerTable" value="#{IntegerModel}" var="rowItem">
<rich:column>
<h:selectBooleanCheckbox value="#{rowItem.selected}">
<a4j:support event="onchange" ajaxSingle="true" />
</h:selectBooleanCheckbox>
</rich:column>
<rich:column>
<f:facet name="header">
Object
</f:facet>
<h:outputText value="#{rowItem.id}" />
</rich:column>
</rich:dataTable>
<a4j:log popup="false" />
</h:form>
</ui:define>
</ui:composition>
</html>
{code:xml}
The bean configuration looks like this
{code:xml}
<managed-bean>
<description>StringClass data model</description>
<managed-bean-name>StringModel</managed-bean-name>
<managed-bean-class>com.StringModel</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<description>IntegerClass data model</description>
<managed-bean-name>IntegerModel</managed-bean-name>
<managed-bean-class>com.IntegerModel</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
{code:xml}