Sunday, April 1, 2012

How to use a4j:repeat and a4j:commandLink to have expandable data rows that brings contents via Ajax


We will discuss a way to use a4j:repeat to create a tabular structure on a JSF page, where each row can be further expanded via Ajax. I am assuming that you have Ajax4JSF installed in your web application. If not, refer this link to install Ajax4JSF in your web application.

This is the requirement. User selects a state from the dropdown, and based on the selected state we need to create a table that list all the zip codes in the state. User can then click the zip code, which will expand the row and paint all the subscribers from that zip code. Since the size of data is going to be huge, we decided to load the content via ajax


Since we have multiple zip codes within each state and multiple customers within each zipcode, we cannot use simple datatable even to list the zip codes. In order to use ajax functions inside repeated elements (which inturn is dynamic), we have to use a4j:repeat tag, otherwise the dynamic ids created by JSF framework could create issues while rerendering the ajax content to a specific row.

I am assuming you have already written the code to load zip codes for the selected state. Let us say the zip codes for the selected state are available in zipCodes field on the backing bean. I am also assuming that we have the code in backing bean to get all subscribers for a given zip code and the subscribers for the given zip code is available in a HashMap field in backing bean named subscribersForZip

So, in short, backing bean will look something like this

public class ZipSubscriberBackingBean {

 private List<SelectItem> states;
 private List<String> zipCodes;
 private Map<String, List<String>> subscribersForZip;
 .......
 getters and setters
 .......

 public void getZipsForState(){
  //get selected state from request
  //get zips for state from modal
  //set the zips to zipCodes
 }

 public void getSubscribersForZip(){
  //get selected zip from request parameter
  //if zip not in Map, get subscribers from modal
  //add list of subscribers to the Map with zip as key
 }

}

Assuming the States dropdown is hooked up correctly, below code will paint the zip codes in a table, with a link on zipcode so that user can click to expand

 <a4j:repeat id="zipCodesForState" value="#{backingbean.zipCodes}" var="zip" >
   <t:panelGroup>
         <a4j:commandLink action="#{backingbean.getSubscribersForZip}" reRender="subscriberSection" value="#{zip}"
          oncomplete="javascript:postAjax(this);" id="ajaxLink" >
          <cfui:urlEncodedParam name="zipCode" value="#{zip}"/>
         </a4j:commandLink>
         <a4j:outputPanel ajaxRendered="true" id="subscriberSection">
        <t:dataTable border="1" value="#{backingbean.subscribersForZip[zip]}" var"subName">
              <t:column>
               <f:facet name="header">
                <h:outputText value="Subscriber Name" />
               </f:facet>
               <h:outputText id="subName" value="#{subName}" />
              </t:column>
         </a4j:outputPanel>
   </t:panelGroup>
  </a4j:repeat>





Blog Archive