a4j:commandLink action not executed in datatable

I have an <a4j:commandLink> in a <rich:datatable>. The same problem applies to <a4j:commandButton> and <a4j:repeat>. The bean action specified was not executed, and the <a4j:actionparam> values were not bound.

For example this was not working:

<a4j:form>
   <rich:dataTable id="searchResults" value="#{myBean.searchResults}" var="item">
            <rich:column>
               <a4j:commandLink value="#{item.code}" action="#{myBean.myAction}"
                reRender="myRegion">
                    <a4j:actionparam name="code" value="#{item.code}"
                     assignTo="#{myBean.selectedCode}"/>
                </a4j:commandLink>
              </rich:column>
   </rich:dataTable>
</a4j:form>

The region was getting rerendered, but myBean.myAction was not executed.

Then I tried moving the <a4j:form> inside the table, so there was a form on each row:

   <rich:dataTable id="searchResults" value="#{myBean.searchResults}" var="item">
      <rich:column>
              <a4j:form>
               <a4j:commandLink value="#{item.code}" action="#{myBean.myAction}"
                reRender="myRegion">
                    <a4j:actionparam name="code" value="#{item.code}"
                     assignTo="#{myBean.selectedCode}"/>
                </a4j:commandLink>
                </a4j:form>
              </rich:column>
   </rich:dataTable>

This seemed to work for the first row, but not any subsequent ones.

The answer seems to be to base the dataTable on a session scoped bean. I didn’t want my orignal bean session scoped, so I split it into two like this:

 <rich:dataTable id="searchResults" value="#{mySessionBean.searchResults}" var="item">
      <rich:column>
              <a4j:form>
               <a4j:commandLink value="#{item.code}" action="#{myBean.myAction}"
                reRender="myRegion">
                    <a4j:actionparam name="code" value="#{item.code}"
                     assignTo="#{myBean.selectedCode}"/>
                </a4j:commandLink>
                </a4j:form>
              </rich:column>
   </rich:dataTable>

And it works. The actions are still carried out on my request bean as I wanted and I just have to be careful about how I update the session bean.

6 degrees

As a slight digression from the intended subject matter of this blog, I have been reading Six Degrees: Our Future on a Hotter Planet, by Mark Lynas. I’m struggling a bit to finish it – I’m up to 3 degrees now, and already I’m quite upset. Its kind of preaching to the converted, and I guess I knew this stuff already but how depressing. He has just described Polar Bears as becoming the ‘Living dead’, the word scientists use for species where there are some left, but not enough to save them from extinction. What a responsibility for humankind.

Then I read some reviews of the book by people still in denial about Climate Change, which made me cross! I haven’t personally got time to study all the evidence, but it seems to me that we can’t increase the Greenhouse Gas levels in the atmosphere that much without expecting some kind of consequence. The book is quite wordy and detailed, and you have to concentrate quite hard or all the bad things seem to blur into one, but it is definitely worth a read.

And after that, why not write to Ed Miliband, and see if we can do something about it?

http://e-activist.com/ea-campaign/clientcampaign.do?ea.client.id=18&ea.campaign.id=1569

Please? Poor Polar bears :(

NoClassDefFoundError com.sun.activation.registries.LogSupport

I’m trying to run a single Junit test via Eclipse and getting this error. But I don ‘t get the error if I run the whole suite of junit tests using ant. The jars activation.jar and mail.jar are definitely in my Project classpath.

The answer: go to Project > Properties > Java Build Path > Order and Export. Move activation.jar up the list.

JSF – rich:datatable and HashMap

I wanted to display the data from a Map using a rich:datatable. You can do this by using an array of the Map keys as the value for the table, and then using this to access the rest of the data in the Map.

Here is the java:

public Map<Integer,MyObject> getItems() {
   return items;
}
public List<Integer> getItemKeys() {
   List keys = new ArrayList();
   keys.addAll(getItems().keySet());
   return keys;
}

and here is the JSF:

<rich:dataTable value="#{myBean.itemKeys}" var="key" >
   <rich:column>
      <h:outputText value="#{myBean.items[key].myObjProperty}"/>
   </rich:column>
</rich:dataTable>

Obviously somewhat simplified but I think this shows how to do it!