title: How to create JSF Table with links after post
body: <p>I like to display a form where the end-user can enter details and the post will result in the table which contain a filtered list based on the user input. This table should have link for each row to select that specific row and return a detailed view.</p>
  
  <p>accounts-list.xhtml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
  xmlns:utils="http://java.sun.com/jsf/composite/snippets" template="/WEB-INF/templates/default.xhtml"&gt;
  
      &lt;ui:define name="title"&gt;&lt;/ui:define&gt;
      &lt;ui:define name="content"&gt;
          &lt;h:form id="search"&gt;
              &lt;fieldset&gt;
                  &lt;legend&gt;Search for account&lt;/legend&gt;
                  &lt;div class="account_list_section"&gt;
                      &lt;span class="account_section_title"&gt;&lt;h:outputLabel for="id" value="Account ID" /&gt;&lt;/span&gt;
                      &lt;span class="account_list_item"&gt;
                          &lt;h:inputText id="id" value="#{accountsCrudBean.searchId}" styleClass="field_inputtext_account" /&gt;
                      &lt;/span&gt;
                  &lt;/div&gt;
                  &lt;div class="account_list_section"&gt;
                      &lt;span class="account_section_title"&gt;&lt;h:outputLabel for="name" value="Account Name" /&gt;&lt;/span&gt;
                      &lt;span class="account_list_item"&gt;
                          &lt;h:inputText id="name" value="#{accountsCrudBean.searchName}" styleClass="field_inputtext_account" /&gt;
                      &lt;/span&gt;
                  &lt;/div&gt;
                  &lt;h:commandButton id="search" value="Display" action="#{accountsCrudBean.actionSearch}" /&gt;
              &lt;/fieldset&gt;
          &lt;/h:form&gt;
  
          &lt;h:form id="view" rendered="#{accountsCrudBean.dataItemId.value != null}"&gt;
              &lt;h:dataTable var="dataItem" binding="#{accountsCrudBean.dataTable}" value="#{accountsCrudBean.list}" id="accountListTable"
                  columnClasses="accountsCrudBeanTable_row_date, transactionsListTable_row_amount, transactionsListTable_row_balance, transactionsListTable_row_description" styleClass="transactionsListTable"&gt;
                  &lt;h:column headerClass="transactionsListTable_header_amount"&gt;
                      &lt;f:facet name="header"&gt;Id&lt;/f:facet&gt;
                      &lt;h:commandLink value="#{dataItem.id}" action="#{accountsCrudBean.editDataItem}" /&gt;
                  &lt;/h:column&gt;
                  &lt;h:column headerClass="transactionsListTable_header_balance"&gt;
                      &lt;f:facet name="header"&gt;Name&lt;/f:facet&gt;#{dataItem.name}&lt;/h:column&gt;
                  &lt;h:column headerClass="transactionsListTable_header_description"&gt;
                      &lt;f:facet name="header"&gt;Total Balance&lt;/f:facet&gt;#{dataItem.totalBalance}&lt;/h:column&gt;
              &lt;/h:dataTable&gt;
              &lt;h:inputHidden binding="#{accountsCrudBean.dataItemId}" /&gt;
          &lt;/h:form&gt;
      &lt;/ui:define&gt;
  &lt;/ui:composition&gt;
  </code></pre>
  
  <p>accounts-edit.xhtml:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;ui:composition xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:utils="http://java.sun.com/jsf/composite/snippets"
      template="/WEB-INF/templates/default.xhtml"&gt;
  
      &lt;ui:define name="title"&gt;&lt;/ui:define&gt;
      &lt;ui:define name="content"&gt;
          &lt;h:form id="edit" rendered="#{accountsCrudBean.dataItemId.value != null}"&gt;
              &lt;fieldset&gt;
                  &lt;legend&gt;View account 1&lt;/legend&gt;
                  &lt;div class="account_list_section"&gt;
                      &lt;span class="account_section_title"&gt;&lt;h:outputLabel for="id" value="Account ID" /&gt;&lt;/span&gt;
                      &lt;span class="account_list_item"&gt;
                          #{accountsCrudBean.dataItemId.value}
                      &lt;/span&gt;
                  &lt;/div&gt;
                  &lt;div class="account_list_section"&gt;
                      &lt;span class="account_section_title"&gt;&lt;h:outputLabel for="name" value="Account Name" /&gt;&lt;/span&gt;
                      &lt;span class="account_list_item"&gt;
                          &lt;h:inputText readonly="true" id="name" value="#{accountsCrudBean.dataItem.name}" styleClass="field_inputtext_account" /&gt;
                      &lt;/span&gt;
                  &lt;/div&gt;
  
                  &lt;div class="account_list_section"&gt;
                      &lt;span class="account_section_title"&gt;&lt;h:outputLabel for="accountOwners" value="Owners" /&gt;&lt;/span&gt;
                      &lt;span class="account_list_item"&gt;
                          &lt;h:selectOneListbox readonly="true" id="accountOwners" value="#{accountsCrudBean.selectedOwner}"&gt;
                              &lt;f:selectItems value="#{accountsCrudBean.accountOwners}" /&gt;
                          &lt;/h:selectOneListbox&gt;       
                      &lt;/span&gt;
                  &lt;/div&gt;      
  
                  &lt;h:inputHidden binding="#{accountsCrudBean.dataItemId}" /&gt;
  
                  &lt;h:commandButton id="edit" value="Save" action="#{accountsCrudBean.actionSearch}" /&gt;
              &lt;/fieldset&gt;
          &lt;/h:form&gt;
          &lt;h:outputText value="No item selected." rendered="#{accountsCrudBean.dataItemId.value == null}" /&gt;
      &lt;/ui:define&gt;
  &lt;/ui:composition&gt;
  </code></pre>
  
  <p>AccountsCrudBean.java:</p>
  
  <pre><code>@ManagedBean
  @SessionScoped
  public class AccountsCrudBean extends JsfManagedBeanBase {
  
      private static final long serialVersionUID = 1L;
  
      @EJB
      AccountsManagerLocal accountsManager;
  
      private Long searchId;
      private String searchName;
  
      private String selectedOwner;
  
      private Account dataItem;
      private HtmlDataTable dataTable;
      private HtmlInputHidden dataItemId = new HtmlInputHidden();
  
      private List&lt;Account&gt; accountList = null;
  
      public AccountsCrudBean() {
      }
  
      public Long getSearchId() {
          return searchId;
      }
  
      public void setSearchId(Long searchId) {
          this.searchId = searchId;
      }
  
      public String getSearchName() {
          return searchName;
      }
  
      public void setSearchName(String searchName) {
          this.searchName = searchName;
      }
  
      public HtmlInputHidden getDataItemId() {
          return dataItemId;
      }
  
      public Account getDataItem() {
          return dataItem;
      }
  
      public void setDataItem(Account dataItem) {
          this.dataItem = dataItem;
      }
  
      public HtmlDataTable getDataTable() {
          return dataTable;
      }
  
      public void setDataTable(HtmlDataTable dataTable) {
          this.dataTable = dataTable;
      }
  
      public void setDataItemId(HtmlInputHidden dataItemId) {
          this.dataItemId = dataItemId;
      }
  
      public String getSelectedOwner() {
          return selectedOwner;
      }
  
      public void setSelectedOwner(String selectedOwner) {
          this.selectedOwner = selectedOwner;
      }
  
      public List&lt;Account&gt; getList() {
          if (accountList == null) {
              actionLoad();
          }
          return accountList;
      }
  
      private void actionLoad() {
          if (searchId != null) {
              Account account = accountsManager.getAccount(searchId);
              accountList = Arrays.asList(account);
          } else if (searchName != null) {
              accountList = accountsManager.findAccountByName(searchName);
          } else if (dataItemId != null &amp;&amp; dataItemId.getValue() != null) {
              Account account = accountsManager.getAccount(Long
                      .valueOf(dataItemId.getValue().toString()));
              accountList = Arrays.asList(account);
          } else
              accountList = new ArrayList&lt;Account&gt;();
      };
  
      public void actionSearch() {
          dataItem = (Account) dataTable.getRowData();
          dataItemId.setValue(dataItem.getId());
          actionLoad();
      }
  
      public Map&lt;String, User&gt; getAccountOwners() {
          List&lt;User&gt; owners = accountsManager.getUsers(dataItem);
          LinkedHashMap&lt;String, User&gt; map = new LinkedHashMap&lt;String, User&gt;();
          for (User user : owners) {
              map.put(user.getFirstName() + " " + user.getLastName(), user);
          }
          return map;
      }
  
      public String editDataItem() {
          dataItem = (Account) dataTable.getRowData();
          dataItemId.setValue(dataItem.getId());
          return "accounts-edit";
      }
  }
  </code></pre>
  
  <p>This works on JBoss 7.1 but on 6 it's failed with:</p>
  
  <pre><code>javax.faces.el.EvaluationException: javax.el.ELException: /s/accounts-list.xhtml at line 22 and column 94 action="#{accountsCrudBean.actionSearch}": java.lang.IllegalArgumentException: row is unavailable
      at javax.faces.component._MethodExpressionToMethodBinding.invoke(_MethodExpressionToMethodBinding.java:96)
      at org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:100)
      at javax.faces.component.UICommand.broadcast(UICommand.java:120)
      at javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:889)
      at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:238)
      at javax.faces.component.UIViewRoot._process(UIViewRoot.java:1201)
      at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:627)
      at org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:34)
      at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:171)
      at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
      at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:324)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242)
      at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242)
      at com.demo.server.ejb.security.AuthenticationFilter.doFilter(AuthenticationFilter.java:35)
      at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:274)
      at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:242)
      at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
      at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
      at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:181)
      at org.jboss.modcluster.catalina.CatalinaContext$RequestListenerValve.event(CatalinaContext.java:285)
      at org.jboss.modcluster.catalina.CatalinaContext$RequestListenerValve.invoke(CatalinaContext.java:261)
      at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:88)
      at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:100)
      at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:159)
      at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
      at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
      at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
      at org.jboss.web.tomcat.service.request.ActiveRequestResponseCacheValve.invoke(ActiveRequestResponseCacheValve.java:53)
      at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:362)
      at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
      at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:654)
      at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:951)
      at java.lang.Thread.run(Thread.java:722)
  Caused by: javax.el.ELException: /s/accounts-list.xhtml at line 22 and column 94 action="#{accountsCrudBean.actionSearch}": java.lang.IllegalArgumentException: row is unavailable
      at org.apache.myfaces.view.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:95)
      at javax.faces.component._MethodExpressionToMethodBinding.invoke(_MethodExpressionToMethodBinding.java:88)
      ... 35 more
  Caused by: java.lang.IllegalArgumentException: row is unavailable
      at javax.faces.model.ListDataModel.getRowData(ListDataModel.java:69)
      at javax.faces.component.UIData.getRowData(UIData.java:462)
      at com.demo.server.web.AccountsCrudBean.actionSearch(AccountsCrudBean.java:130)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:601)
      at org.apache.el.parser.AstValue.invoke(AstValue.java:196)
      at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
      at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:43)
      at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:56)
      at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:43)
      at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:56)
      at org.apache.myfaces.view.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:83)
      ... 36 more
  </code></pre>
  
  <p>This is based on <a href="http://balusc.blogspot.com/2006/06/using-datatables.html#AddBackingBeanActionToEveryRow" rel="nofollow">http://balusc.blogspot.com/2006/06/using-datatables.html#AddBackingBeanActionToEveryRow</a></p>
  
  <p>On the post the author use @RequestScoped bean but if I try to change the bean to be @RequestScoped the filter does not work, and i don't get the table with the links.</p>
  
  <p>Thanks.</p>