try to write a composite component that allows mutltiple text inputs. I read that it is possible to define a backing component for a composite component, so I don't have to write a renderer nor a handler. What I couldn't figure out is how to delegate actions declared in composite's xhtml to the backing component. I guess i did not yet quite understand the concept of this. Does anybody has an Idea?
I am using Tomcat 7, EL 2.2, Spring 3, Mojarra 2.1.7
This is the way i'd like to use the component:
<custom:multiInput value="#{backingBean.inputList}"/>
Where the BackingBean.java holds a list of objects:
@Component
@Scope(value="view")
public class BackingBean {
...
private List<Foo> inputList;
....
}
The composite component multiInput.xhtml looks like this:
<cc:interface componentType="MultiInput">
<cc:attribute name="value" required="true" type="java.util.List" />
</cc:interface>
<cc:implementation>
<div id="#{cc.clientId}">
<h:dataTable value="#{cc.attrs.rows}" var="row">
<h:column>
<!-- here will be a selector component in order to select a foo object -->
</h:column>
<h:column>
<h:commandButton value="Remove Row">
<f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" listener="#{cc.removeRow(row)}" />
</h:commandButton>
</h:column>
<h:column>
<h:commandButton value="Add Row" rendered="#{cc.lastRow}">
<f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" listener="#{cc.addEmptyRow()}" />
</h:commandButton>
</h:column>
</h:dataTable>
</div>
</cc:implementation>
And here the backing component MultiInput.java:
@FacesComponent(value="MultiInput")
public class MultiInput extends UIInput implements NamingContainer, Serializable{
...
@Override
public String getFamily() {
return "javax.faces.NamingContainer";
}
@Override
public void encodeBegin(FacesContext context) throws IOException {
initRowsFromValueAttribute();
super.encodeBegin(context);
}
public void removeRow(MultiInputRow row) {
// why is this method is never reached when clicking remove button?
}
public void addEmptyRow() {
// why is this method is never reached when clicking add button?
}
public ListDataModel<MultiSelectRow> getRows() {
return (ListDataModel<MultiSelectRow>) getStateHelper().eval(PropertyKeys.rows, null);
}
private void setRows(ListDataModel<MultiSelectRow> rows) {
getStateHelper().put(PropertyKeys.rows, rows);
}
...
}
Now - removeRow
and addEmptyRow
is never called on MultiInput. An ajax request is triggered but it gets lost somewhere. Why?