4 Replies Latest reply on Feb 26, 2009 6:20 AM by konstantin.mishin

    dataTable Filtering not working when using Binding.

    nnishizaka

      Weblogic 10.3
      JSF RI 1.2_011
      RichFaces 3.3

      Pretty simple setup.
      Backing bean with a List filled with instances of a class.
      A jsf page with <rich:dataTable> that is already displaying data fine.

      The problem is when I use the binding property to bind the dataTable to a property on the backing bean, the filtering no longer works once I exit the page and go to the next one. (Say by the user clicking on a commandLink on a row for instance.) So when the user returns to this page, It looks like it's attempting to filter the dataTable, however the data I am seeing isn't correct.

      I'll try to explain the symptom.
      When the page is opened for the first time, things work fine. Things continue to work fine as long as another request isn't made from the page. (such as by clicking on the "next" commandButton, or on the commandLink on each row) Once another request is made, and the user comes back to this page, the filtering becomes dysfunctional. When I type in a letter in the filter box, it's still filtering, but data that is displayed in the dataTable is displaying the first 4 rows (I have rows="4" on the dataTable) instead of the correct set of 4 rows. When I click on the commandLink on anyone of them the row data is actually from what was filters.

      So, let's say I have some userid's in alphabetical order. When I type in "t" in the filter column, I still see data from "a", but when I click on the commandLink on one of the "a" records, the row data is that of "t". So the filter is actually working, but what is displayed in the dataTable isn't correct. When I hit the refresh button in IE, I see the "t" records now.

      When I don't use binding, then everything works fine. However I can't select row data without binding, so this is a show stopper.

      Here is the section of the jsf page:

      <h:form id="MyForm">
       <div>
       <rich:dataTable id="dataTable" value="#{TbUserMaint.allUsers}" binding="#{TbUserMaint.usersTable}" var="users" rows="4" reRender="ds">
       <f:facet name="header">
       <rich:columnGroup>
       <rich:column breakBefore="true">
       <h:outputText value="#{msg.coluserid}" />
       </rich:column>
       <rich:column>
       <h:outputText value="#{msg.colenabled}" />
       </rich:column>
       <rich:column>
       <h:outputText value="#{msg.coldatecreated}" />
       </rich:column>
       </rich:columnGroup>
       </f:facet>
       <rich:column filterBy="#{users.userid}" filterEvent="onkeyup">
       <f:facet name="header">
       <h:outputText value=" " title="Hack due to bug. Shuold be remoevd till release"></h:outputText>
       </f:facet>
       <h:commandLink value="#{users.userid}" action="#{TbUserMaint.getUserDetail}" style="width: 150px;height: 12px;text-align: left" />
       </rich:column>
       <rich:column>
       <h:outputText value="#{users.enabled}" style="width: 50px;height: 12px;text-align: center" />
       </rich:column>
       <rich:column>
       <h:outputText value="#{users.dateCreated}" style="width: 225px;height: 12px;text-align: center" />
       </rich:column>
       <f:facet name="footer">
       <rich:datascroller id="ds" renderIfSinglePage="false"></rich:datascroller>
       </f:facet>
       </rich:dataTable>
      
       <h:panelGrid id="panelColumnsNav" columns="1" border="0">
       <h:commandButton value="Add User" action="#{TbUserMaint.addUser}" style="width: 10em;" />
       </h:panelGrid>
      
       </div>
       </h:form>
      


      Relevant parts of the backing bean for binding.

      import org.richfaces.component.html.HtmlDataTable;
      ...
      
      //property for binding
      private HtmlDataTable htmlDataTable;
      
      //getter
      public HtmlDataTable getHtmlDataTable(){
       return htmlDataTable;
      }
      
      //setter
      public void setHtmlDataTable(HtmlDataTable val){
       htmlDataTable = val;
      }
      
      
      


        • 1. Re: dataTable Filtering not working when using Binding.
          nnishizaka

          For now, I am using <f:param> so that I don't have to use binding.

          <h:commandLink id="clUserid" value="#{users.userid}" action="#{TbUserMaint.getUserDetail}" actionListener="#{TbUserMaint.actionUserid}" style="width: 150px;height: 12px;text-align: left" >
           <f:param name="tbUserMaintForm:dtUsers:colUserid:clUserid:recordid" value="#{users.recordid}"/>
           </h:commandLink>
          


          Then in my backing bean, I have a actionListener method that will fetch me the data based on the recordid that I get from Httprequest.

          public void actionUserid(ActionEvent event) {
           HttpServletRequest request = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
           String recordid = request.getParameter("tbUserMaintForm:dtUsers:colUserid:clUserid:recordid");
           this.tbUser = this.tbUserMaintModel.getTbUserDAO().findById(Integer.valueOf(recordid));
           }
          


          This works for now...but probably not the best solution...

          • 2. Re: dataTable Filtering not working when using Binding.
            konstantin.mishin

            What scope your backing bean has?

            • 3. Re: dataTable Filtering not working when using Binding.
              nnishizaka

               

              "konstantin.mishin" wrote:
              What scope your backing bean has?


              I have a session scoped bean holding the data for the List, HtmlDataTable, DAO calls, etc...

              Then I have a request scoped bean that deals with the JSF requests.

              So for instance, in actuality, the binding would be to the request scoped bean, which in turn gets/sets the HtmlDataTable on the session scoped bean.


              So I have this in the request scoped bean called TbUserMaintController...
              
              ***TbUserMaintModel is a session scoped bean which gets injected into TbUserMaintController everytime TbUserMaintController is created per request.
              
              //property for binding
              private HtmlDataTable htmlDataTable;
              
              //getter
              public HtmlDataTable getHtmlDataTable(){
               return this.TbUserMaintModel.getHtmlDataTable();
              }
              
              //setter
              public void setHtmlDataTable(HtmlDataTable val){
               this.TbUserMaintModel.setHtmlDataTable(val);
              }
              


              My previous solution works fine, but the problem is I need to make an additional DAO call when a userid commandLink is clicked. I would rather avoid this.

              I was looking into rowKeyVar of Rich:dataTable but it looks like that's no good because when the filtering is applied, the rowKeyVar also gets affected. So I can't take the rowKeyVar value and do a get(rowKeyVar) on the List.

              For instance, if I enter "c" in the filter column, and it retrieves all the userid's that start with c, the first "c" record has a rowKeyVar of "0"...so that's useless to me since I can't go to my List and use this value as an index to get a row...

              • 4. Re: dataTable Filtering not working when using Binding.
                konstantin.mishin

                You shouldn't put any components in session. And you can select row data without binding. You might wrap TbUserMaint.allUsers into javax.faces.model.ListDataModel and use method getRowData.