6 Replies Latest reply on Mar 16, 2009 3:26 PM by den74

    ExtendedDataTable: row selection when filtered

    den74

      Hi all,

      my env is:
      richfaces 3.3.0
      tomcat 6.0.18
      jsf 1.2

      we have a grave problem getting the row selected when the table is filtered with the standar way.

      We managed a self solution because we saw sometimes Selection result void even if the row was selected.
      The way we followed is to store on our bean the rowKetVar value (using selection object just to reset selection on table):

      <rich:extendedDataTable
      …
      rowKeyVar="rkw">

      <a4j:support event="onRowClick">
      <a4j:actionparam name="tableSelecteIndex" value="#{rkw}" assignTo="#{MyBean.selectedRow}"></a4j:actionparam>
      </a4j:support>

      ….
      </rich:extendedDataTable>

      It works perfectly, included when using data tale scroller, but if we filter the valuse, then the selected index result to be the index of the elemente in the sublist shown, and not the real index of the element in the original list.
      So we can't retrieve the object and use it.
      Ask helps from anyone knows a solution or a better way to manage the selection.

      thanks in advance
      Denis


        • 1. Re: ExtendedDataTable: row selection when filtered
          ilya_shaikovsky

          You could use onselectionchange event and selection binding like implemented at demosite. Your solution except the problem you mentioned will also has next problem - if the user will change selection with the keyboard up/down keys (it will not be stored using your solution)

          • 2. Re: ExtendedDataTable: row selection when filtered
            den74

            thanks ilya_shaikovsky, you are right, i have the problem even when using the keybord up/down keys.

            I tried only with selection binding but it doesn't work, if the list is filtered the selection contains just low indexes (the ones shown in the list) and not the real index of the object in the main list

            • 3. Re: ExtendedDataTable: row selection when filtered
              ilya_shaikovsky

              Next code works fine for me and consider filtering ok.

              <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
              <html xmlns="http://www.w3.org/1999/xhtml"
               xmlns:ui="http://java.sun.com/jsf/facelets"
               xmlns:h="http://java.sun.com/jsf/html"
               xmlns:f="http://java.sun.com/jsf/core"
               xmlns:a4j="http://richfaces.org/a4j"
               xmlns:rich="http://richfaces.org/rich">
              
               <ui:composition>
               <h:form>
               <h:panelGrid columns="2" columnClasses="top,top">
               <rich:extendedDataTable value="#{extendedTableBean.capitalsDataModel}" var="cap" id="table"
               width="580px" height="400px" sortMode="#{extendedTableBean.sortMode}" selection="#{extendedTableBean.selection}"
               selectionMode="#{extendedTableBean.selectionMode}">
               <rich:column sortable="false" label="Flag">
               <f:facet name="header">
               <h:outputText value="Flag"/>
               </f:facet>
               <h:graphicImage value="#{cap.stateFlag}"/>
               </rich:column>
               <rich:column sortable="true" sortBy="#{cap.state}" filterBy="#{cap.state}" filterEvent="onkeyup" width="170px" label="State Name">
               <f:facet name="header">
               <h:outputText value="State Name"/>
               </f:facet>
               <h:outputText value="#{cap.state}"/>
               </rich:column>
               <rich:column sortable="true" sortBy="#{cap.name}" filterBy="#{cap.name}" filterEvent="onkeyup" width="170px" label="State Capital">
               <f:facet name="header">
               <h:outputText value="State Capital"/>
               </f:facet>
               <h:outputText value="#{cap.name}"/>
               </rich:column>
               <rich:column sortable="false" label="Time Zone">
               <f:facet name="header">
               <h:outputText value="Time Zone"/>
               </f:facet>
               <h:outputText value="#{cap.timeZone}"/>
               </rich:column>
               </rich:extendedDataTable>
              
               <rich:panel>
               <f:facet name="header">
               <h:outputText value="Sort/Selection modes changing"/>
               </f:facet>
               <h:panelGrid columns="2">
               <h:outputText value="Sort Mode:"/>
               <h:selectOneMenu value="#{extendedTableBean.sortMode}">
               <f:selectItem itemLabel="Single" itemValue="single"/>
               <f:selectItem itemLabel="Multi" itemValue="multi"/>
               <a4j:support event="onchange" ajaxSingle="true" reRender="table"/>
               </h:selectOneMenu>
               <h:outputText value="Selection Mode:"/>
               <h:selectOneMenu value="#{extendedTableBean.selectionMode}">
               <a4j:support ajaxSingle="true" event="onchange" reRender="table"/>
               <f:selectItem itemLabel="Single" itemValue="single"/>
               <f:selectItem itemLabel="Multi" itemValue="multi"/>
               <f:selectItem itemLabel="None" itemValue="none"/>
               </h:selectOneMenu>
               </h:panelGrid>
               </rich:panel>
               </h:panelGrid>
               <a4j:commandButton value="Show Current Selection" reRender="seltable"
               action="#{extendedTableBean.takeSelection}"
               oncomplete="javascript:Richfaces.showModalPanel('panel');"/>
              
               </h:form>
               <rich:modalPanel id="panel" autosized="false" keepVisualState="false" width="315" height="230">
               <f:facet name="header">
               <h:outputText value="Selected Rows"/>
               </f:facet>
               <f:facet name="controls">
               <span style="cursor:pointer" onclick="javascript:Richfaces.hideModalPanel('panel')">X</span>
               </f:facet>
               <h:panelGroup layout="block" styleClass="scrolls">
               <h:form>
               <rich:dataTable value="#{extendedTableBean.selectedItems}" var="cap" id="seltable">
               <rich:column sortable="true" sortBy="#{cap.state}" filterBy="#{cap.state}" filterEvent="onkeyup" width="170px" label="State Name">
               <f:facet name="header">
               <h:outputText value="State Name"/>
               </f:facet>
               <h:outputText value="#{cap.state}"/>
               </rich:column>
               <rich:column sortable="true" sortBy="#{cap.name}" filterBy="#{cap.name}" filterEvent="onkeyup" width="170px" label="State Capital">
               <f:facet name="header">
               <h:outputText value="State Capital"/>
               </f:facet>
               <h:outputText value="#{cap.name}"/>
               </rich:column>
               <rich:column sortable="false" label="Time Zone">
               <f:facet name="header">
               <h:outputText value="Time Zone"/>
               </f:facet>
               <h:outputText value="#{cap.timeZone}"/>
               </rich:column>
               </rich:dataTable>
               </h:form>
               </h:panelGroup>
               </rich:modalPanel>
               </ui:composition>
              
              </html>


              /**
               *
               */
              package org.richfaces.demo.extendedDataTable;
              
              import java.util.ArrayList;
              import java.util.Iterator;
              import java.util.List;
              
              import org.richfaces.demo.capitals.Capital;
              import org.richfaces.demo.datafilterslider.DemoInventoryItem;
              import org.richfaces.model.DataProvider;
              import org.richfaces.model.ExtendedTableDataModel;
              import org.richfaces.model.selection.SimpleSelection;
              
              /**
               * @author Ilya Shaikovsky
               *
               */
              public class ExtendedTableBean {
               private String sortMode="single";
               private String selectionMode="multi";
               private SimpleSelection selection;
               private List<Capital> selectedItems = new ArrayList<Capital>();
               public SimpleSelection getSelection() {
               return selection;
               }
              
               public List<Capital> getSelectedItems() {
               return selectedItems;
               }
              
               public void setSelectedItems(List<Capital> selectedItems) {
               this.selectedItems = selectedItems;
               }
              
               public void setSelection(SimpleSelection selection) {
               this.selection = selection;
               }
              
               private ExtendedTableDataModel<Capital> dataModel;
               private List<Capital> capitals = new ArrayList<Capital>();
              
               public String getSortMode() {
               return sortMode;
               }
              
               public void setSortMode(String sortMode) {
               this.sortMode = sortMode;
               }
              
               public String getSelectionMode() {
               return selectionMode;
               }
              
               public void setSelectionMode(String selectionMode) {
               this.selectionMode = selectionMode;
               }
              
               public ExtendedTableBean() {
               }
              
               public ExtendedTableDataModel<Capital> getCapitalsDataModel() {
               if (dataModel == null) {
               dataModel = new ExtendedTableDataModel<Capital>(new DataProvider<Capital>(){
              
               private static final long serialVersionUID = 5054087821033164847L;
              
               public Capital getItemByKey(Object key) {
               for(Capital c : capitals){
               if (key.equals(getKey(c))){
               return c;
               }
               }
               return null;
               }
              
               public List<Capital> getItemsByRange(int firstRow, int endRow) {
               return capitals.subList(firstRow, endRow);
               }
              
               public Object getKey(Capital item) {
               return item.getName();
               }
              
               public int getRowCount() {
               return capitals.size();
               }
              
               });
               }
               return dataModel;
               }
              
               public void takeSelection() {
               getSelectedItems().clear();
               Iterator<Object> iterator = getSelection().getKeys();
               while (iterator.hasNext()){
               Object key = iterator.next();
               getCapitalsDataModel().setRowKey(key);
               getSelectedItems().add((Capital) getCapitalsDataModel().getRowData());
               }
               }
              
               public void setCapitals(List<Capital> capitals) {
               this.capitals = capitals;
               }
              
              }
              


              • 4. Re: ExtendedDataTable: row selection when filtered
                den74

                thanks for example ilya_shaikovsky,

                i'm trying in the same way of you, and it works but i have a question: in that way i just can use an attribute of the class to identify the object selected, so i can't access to the original list to get the object but i have to reload from database using its id.
                Do you know a way to reuse the object stored in the original list instead of reload the object from database (and instead of check every elementes of the list looking for the id selected)

                thanks

                • 5. Re: ExtendedDataTable: row selection when filtered
                  den74

                  sorry i didn't pay attention on the way you retrieve the elemnt from the datamodel.

                  well i solved

                  thanks a lot

                  • 6. Re: ExtendedDataTable: row selection when filtered
                    den74

                    thanks a lot ilya_shaikovsky, i solved the problem of selection with your suggestion.
                    Unfortunately i hurted another problem: if i filter the list the data scroller doesn't update correctly. In fact the scroller doesn't change at all. I found a topic telling to force reRender of scroller from the dataTable, but i can't find the reRender option for the extendedDataTabel.
                    Hope you can help me again :) Any suggestion?