1 Reply Latest reply on May 6, 2013 7:51 AM by denixxx

    4.3.1.Final & extendedDataTable & custom filter & selectOneMenu looses selection

    burkatzkim

      Hello together!

       

      I getting confused since we tried to migrate from 4.2.x to 4.3.1.Final. In particular, the selection feature of the extendedDataTable in combination with a custom filter of selectOneMenu-style seems not to work properly. The be most precise, I modified the showcase-sources in order to preproduce the error systematically.

       

      First, I added a custom filter into extTableSelection-sample.xhtml. Both files are attached as well.

       

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:a4j="http://richfaces.org/a4j"
          xmlns:fn="http://java.sun.com/jsp/jstl/functions"
          xmlns:rich="http://richfaces.org/rich">
          <h:panelGrid columns="2">
              <h:form>
                  <fieldset style="margin-bottom: 10px;"><legend><h:outputText value="Selection Mode " /></legend>
                  <h:selectOneRadio value="#{extTableSelectionBean.selectionMode}">
                      <f:selectItem itemLabel="Single" itemValue="single"/>
                      <f:selectItem itemLabel="Multiple" itemValue="multiple"/>
                      <f:selectItem itemLabel="Multiple Keyboard-free" itemValue="multipleKeyboardFree"/>
                      <a4j:ajax render="table, res"/>
                  </h:selectOneRadio>
                  </fieldset>
                  <rich:extendedDataTable
                      value="#{extTableSelectionBean.inventoryItems}" var="car"
                      selection="#{extTableSelectionBean.selection}" id="table"
                      frozenColumns="2" style="height:300px; width:500px;" selectionMode="#{extTableSelectionBean.selectionMode}">
                      <a4j:ajax execute="@form"
                      event="selectionchange"
                      listener="#{extTableSelectionBean.selectionListener}" render=":res" />
                      <f:facet name="header"> 
                          <h:outputText value="Cars marketplace" />
                      </f:facet>
                      <rich:column filterValue="#{extTableSelectionBean.vendorFilter}"
                                              filterExpression="#{fn:containsIgnoreCase(car.vendor, extTableSelectionBean.vendorFilter)}"
                                              filterType="custom">
                                         <f:facet  name="header">
                                              <h:panelGroup>
                                                  <h:outputText value="Vendor "/>
                                                  <h:selectOneMenu value="#{extTableSelectionBean.vendorFilter}">
                                                      <f:selectItems value="#{carsBean.vendorOptions}"/>
                                                      <a4j:ajax render="table" execute="@this" event="change"/>
                                                  </h:selectOneMenu>
                                              </h:panelGroup>
                                          </f:facet>
                         <ui:remove>
                            <f:facet name="header">
                                <h:outputText value="vendor" />
                             </f:facet>
                          </ui:remove>
                          <h:outputText value="#{car.vendor}" />
                      </rich:column>
                      <rich:column>
                          <f:facet name="header">
                              <h:outputText value="Model" />
                          </f:facet>
                          <h:outputText value="#{car.model}" />
                      </rich:column>
                      <rich:column>
                          <f:facet name="header">
                              <h:outputText value="Price" />
                          </f:facet>
                          <h:outputText value="#{car.price}" />
                      </rich:column>
                      <rich:column>
                          <f:facet name="header">
                              <h:outputText value="Mileage" />
                          </f:facet>
                          <h:outputText value="#{car.mileage}" />
                      </rich:column>
                      <rich:column>
                          <f:facet name="header">
                              <h:outputText value="VIN Code" />
                          </f:facet>
                          <h:outputText value="#{car.vin}" />
                      </rich:column>
                      <rich:column>
                          <f:facet name="header">
                              <h:outputText value="Items stock" />
                          </f:facet>
                          <h:outputText value="#{car.stock}" />
                      </rich:column>
                      <rich:column>
                          <f:facet name="header">
                              <h:outputText value="Days Live" />
                          </f:facet>
                          <h:outputText value="#{car.daysLive}" />
                      </rich:column>
                  </rich:extendedDataTable>
              </h:form>
              <a4j:outputPanel id="res">
                  <rich:panel header="Selected Rows:"
                      rendered="#{not empty extTableSelectionBean.selectionItems}">
                      <rich:list type="unordered"
                          value="#{extTableSelectionBean.selectionItems}" var="sel">
                          <h:outputText value="#{sel.vendor} - #{sel.model} - #{sel.price}" />
                      </rich:list>
                  </rich:panel>
              </a4j:outputPanel>
          </h:panelGrid>
      </ui:composition>
      

       

      Second, I added some code to ExtTableSelectionBean.java:

      package org.richfaces.demo.tables;
      
      import java.io.Serializable;
      import java.util.ArrayList;
      import java.util.Collection;
      import java.util.List;
      
      import javax.faces.bean.ManagedBean;
      import javax.faces.bean.ManagedProperty;
      import javax.faces.bean.ViewScoped;
      import javax.faces.event.AjaxBehaviorEvent;
      
      import org.richfaces.component.UIExtendedDataTable;
      import org.richfaces.demo.tables.model.cars.InventoryItem;
      import org.richfaces.model.Filter;
      
      @ManagedBean
      @ViewScoped
      public class ExtTableSelectionBean implements Serializable {
          private String selectionMode="multiple";
          private Collection<Object> selection;
          @ManagedProperty(value = "#{carsBean.allInventoryItems}")
          private List<InventoryItem> inventoryItems;
          private List<InventoryItem> selectionItems = new ArrayList<InventoryItem>();
          private String vendorFilter;
      
          public void selectionListener(AjaxBehaviorEvent event) {
              UIExtendedDataTable dataTable = (UIExtendedDataTable) event.getComponent();
              Object originalKey = dataTable.getRowKey();
              selectionItems.clear();
              for (Object selectionKey : selection) {
                  dataTable.setRowKey(selectionKey);
                  if (dataTable.isRowAvailable()) {
                      selectionItems.add((InventoryItem) dataTable.getRowData());
                  }
              }
              dataTable.setRowKey(originalKey);
          }
      
          public Filter<?>  getFilterVendor() {
              return new Filter<InventoryItem>() {
                  public boolean accept(InventoryItem t) {
                      String vendor = getVendorFilter();
                      if (vendor == null || vendor.length() == 0 || vendor.equals(t.getVendor())) {
                          return true;
                      }
                      return false;
                  }
              };
          }
      
          public String getVendorFilter() {
              return vendorFilter;
          }
      
          public void setVendorFilter(String vendorFilter) {
              this.vendorFilter = vendorFilter;
          }
      
          public Collection<Object> getSelection() {
              return selection;
          }
      
          public void setSelection(Collection<Object> selection) {
              this.selection = selection;
          }
      
          public List<InventoryItem> getInventoryItems() {
              return inventoryItems;
          }
      
          public void setInventoryItems(List<InventoryItem> inventoryItems) {
              this.inventoryItems = inventoryItems;
          }
      
          public List<InventoryItem> getSelectionItems() {
              return selectionItems;
          }
      
          public void setSelectionItems(List<InventoryItem> selectionItems) {
              this.selectionItems = selectionItems;
          }
      
          public String getSelectionMode() {
              return selectionMode;
          }
      
          public void setSelectionMode(String selectionMode) {
              this.selectionMode = selectionMode;
          }
      }
      

       

      The error is reproduced as follows:

       

      1. Open page
      2. Choose vendor filter Infinity. Only Infinity vehicles are now displayed.
      3. Select first row, on the right "Infiniti - G35 - 46787" is displayed
      4. Choose vendor filter Ford. The table content will be updated and show Ford vehicles only now.
      5. Select first row, on the right "Infiniti - G35 - 46787" gets displayed, which is wrong! I expect a Ford vehicle.

       

      At this state you may select any other row instead. The details will always show Infinity vehicles.

      What am I doing wrong? Can anyone please supply some insight? Thank you very much in advance!

       

      Best,

      Mark

        • 1. Re: 4.3.1.Final & extendedDataTable & custom filter & selectOneMenu looses selection
          denixxx

          Hi. I have had same problem. I'm sure it's result of appearance built-in filtering and sorting in RF 4.3.1.

          Try somethink like this:

          <rich:column filterValue="#{extTableSelectionBean.vendorFilter}"
                                                  filterExpression="#{fn:containsIgnoreCase(car.vendor, extTableSelectionBean.vendorFilter)}"
                                                  filterType="custom">

                                             <f:facet  name="header">
                                                  <h:panelGroup>
                                                      <h:outputText value="Vendor "/>
                                                      <h:selectOneMenu value="#{extTableSelectionBean.vendorFilter1}">
                                                          <f:selectItems value="#{carsBean.vendorOptions}"/>
                                                          <a4j:ajax render="table" execute="@this" event="change"/>
                                                      </h:selectOneMenu>
                                                  </h:panelGroup>
                                              </f:facet>

          ...

           


          private String vendorFilter;

          private String vendorFilter1;

           

          public String getVendorFilter() {
                  return vendorFilter;
              }
          public void setVendorFilter(String vendorFilter) {
                  //this.vendorFilter = vendorFilter;
              }


          public String getVendorFilter1() {
                  return vendorFilter1;
              }

          public void setVendorFilter1(String vendorFilter1) {
               this.vendorFilter1 = vendorFilter1;

               this.vendorFilter = vendorFilter1;   

          }

           

          PS: In my case there are 3 filters, so setters look like this:

           

          public void setStatusFilter1(String statusFilter1) {

                  this.statusFilter1 = statusFilter1;

                  //

                  this.fioFilter = fioFilter1;

                  this.statusFilter = statusFilter1;

                  this.changesFilter = changesFilter1;

              }