I am trying to get an h:textInput to rerender on change, I have tried it with a4j:ajax and f:ajax.
When using a4j:ajax:
<h:panelGroup id="xyzPG">
<ui:repeat var="var" ... >
...
<h:inputText id="#{idController.getIdXYZ(var.id)}"
value="#{someModel.value}"
size="3"
styleClass="#{errorController.getErrorStateStyleId(idController.getIdXYZ())}">
<a4j:ajax event="change" render="xyzPG" listener="#{listener.doSomeStuff}" />
</h:inputText>
...
</ui:repeat>
</h:panelGroup>
This works the first time, after the panel has updated the first time it stops updating the modell and the listener isn't called either. However the render is triggered causing the old values to be displayed.
Now when I replace a4j:ajax with f:ajax I get the error message that the id xyzPG cannot be found within xyzInput.
<f:ajax event="change" render="@this" listener="#{listener.doSomeStuff}" />
When I try limiting the rerender to the inputText it always updates the model and the listener is called, however the h:inputText is not rerendered.
I have already tried placing another panelGroup around the inputText but that didn't work either.
The reason why we are not using h:dataTable is because we have to produce a Table with the following layout:
----------------------------
| dataSet1 | dataSet 2 |
----------------------------
| dataSet3 | dataSet 4 |
etc...
Hence we are using the offset and step attributes of ui:repeat.
id
attributes using a render-time tag like <ui:repeat/>
Compile-time V Render-time tags
For the purposes of view construction and ajax-updates, the id
s of components must be available during view construction before a view is rendered. <ui:repeat/>
already caters for uniqueness in the ids of it's child components. But if you require control of the ids, you need to use a compile-time tag handler like <c:forEach/>
:
<c:forEach items="#{idController.itemsList}" var="theVar">
<h:inputText id="#{idController.getIdXYZ(theVar.id)}" value="#{someModel.value}" size="3" styleClass="#{errorController.getErrorStateStyleId(idController.getIdXYZ())}">
<a4j:ajax event="change" render="xyzPG" listener="#{listener.doSomeStuff}" />
</h:inputText>
<c:forEach/>
It's unlikely that you'll be able to reach xyzPG
from within the <ui:repeat/>
because the <ui:repeat/>
is also a naming container, just like <h:panelGrid/>
and so forth. The ajax update works with Richfaces because they've made special provisions for such use cases. <f:ajax/>
however will not tolerate it. xyzPG
is outside the scope of the <ui:repeat/>
so to reach that component, you need to use a qualified naming convention:
<f:ajax event="change" render=":form1:xyzPG" listener="#{listener.doSomeStuff}"/>
This assumes that xyzPG
is directly contained within an <h:form id="form1"/>