1 Reply Latest reply on Nov 12, 2010 11:31 AM by ndrw_cheung

    ExtendedDataTable : cannot clear selection on reRender

    ndrw_cheung

      Hi. I have modified the ExtendedDataTable example on my local development environment to implement a "Select Capital button". When a user selects a row in the ExtendedDataTable and then click on the "Select Capital" button, the selected capital should appear in the "selectiontable" datatable and the selected capital should disappear from the ExtendedDataTable on the left-hand side. Furthermore, all the items in the ExtendedDataTable should NOT be shown as selected.

       

      However, I can only get the first part working (that is, the selected capital shows up in the data table in the right hand side and disappears from the ExtendedDataTable on the left), but the  ExtendedDataTable has the next item shown as selected after re-rendering.

       

      What I found was that in the "takeSelection" method in the ExtendedTableBean.java, getSelection().getKeys().hasNext() returns false after I did "setSelection(new SimpleSelection());", which means that the selection has been cleared. But somehow when ExtendedDataTable is re-rendered again, the item below the item that was previously selected would appear selected.

       

      Any help is appreciated. Code and configurations can be found below.

       

      -Andrew

       

      -------------------------------------------

       

      Current infrastructure:

      -RichFaces 3.3.3Final

      -JSF1.2

      -Facelets 1.1.15B1

      -GateIn Portal 3.0

       

      Code in various files are as follows:

       

      regionresults.xhtml:

       

      <h:panelGrid columns="2" columnClasses="top , top">
                  <rich:extendedDataTable
                      value="#{brokeradmin.etb.capitalsDataModel}" var="cap" id="table"
                      width="580px" height="400px"
                      sortMode="#{brokeradmin.etb.sortMode}"
                      selectionMode="#{brokeradmin.etb.selectionMode}"
                      tableState="#{brokeradmin.etb.tableState}"
                      selection="#{brokeradmin.etb.selection}">
                      <rich:column sortable="false" label="Flag" id="col_1">
                          <f:facet name="header">
                              <h:outputText value="Flag" id="flag"/>
                          </f:facet>
                          <h:graphicImage value="#{cap.stateFlag}" id="cap_state_flag"/>
                      </rich:column>
                      <rich:column sortable="true" sortBy="#{cap.state}" id="col_2"
                          filterBy="#{cap.state}" filterEvent="onkeyup" width="170px"
                          label="State Name">
                          <f:facet name="header">
                              <h:outputText value="State Name" id="state_name"/>
                          </f:facet>
                          <h:outputText value="#{cap.state}" id="cap_state"/>
                      </rich:column>
                      <rich:column sortable="true" sortBy="#{cap.name}" id="col_3"
                          filterBy="#{cap.name}" filterEvent="onkeyup" width="170px"
                          label="State Capital">
                          <f:facet name="header">
                              <h:outputText value="State Capital" id="state_capital"/>
                          </f:facet>
                          <h:outputText value="#{cap.name}" id="cap_name"/>
                      </rich:column>
                      <rich:column sortable="false" label="Time Zone" id="col_4">
                          <f:facet name="header">
                              <h:outputText value="Time Zone" id="time_zone"/>
                          </f:facet>
                          <h:outputText value="#{cap.timeZone}" id="cap_time_zone"/>
                      </rich:column>
                      <a4j:support id="extended_table_bean_take_selection"
                          action="#{brokeradmin.etb.takeSelection}"
                          event="onselectionchange"/>
                  </rich:extendedDataTable>
                  <h:panelGroup layout="block" style="width:250px">
                      <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="#{brokeradmin.etb.sortMode}">
                                  <f:selectItem itemLabel="Single" itemValue="single" />
                                  <f:selectItem itemLabel="Multi" itemValue="multi" />
                                  <a4j:support event="onchange" ajaxSingle="true" reRender="table" id="support_sort_onchange"/>
                              </h:selectOneMenu>
                              <h:outputText value="Selection Mode:" />
                              <h:selectOneMenu value="#{brokeradmin.etb.selectionMode}">
                                  <a4j:support ajaxSingle="true" event="onchange" reRender="table" id="support_select_onchange"/>
                                  <f:selectItem itemLabel="Single" itemValue="single" />
                                  <f:selectItem itemLabel="Multi" itemValue="multi" />
                                  <f:selectItem itemLabel="None" itemValue="none" />
                              </h:selectOneMenu>
                          </h:panelGrid>
                      </rich:panel>
                      <rich:panel>
                      <a4j:commandButton id="btnGetSelectedRegions" reRender="selectiontable,table" value="Select Capital" >
              </a4j:commandButton>
                      </rich:panel>
                      <rich:panel>
                          <f:facet name="header">
                              <h:outputText value="Currently selected rows:" />
                          </f:facet>
                          <rich:dataTable value="#{brokeradmin.etb.selectedCapitals}"
                              var="sel" id="selectiontable">
                              <rich:column>
                                  <h:graphicImage value="#{sel.stateFlag}" />
                              </rich:column>
                              <rich:column>
                                  <h:outputText value="#{sel.state}" />
                              </rich:column>
                              <rich:column>
                                  <h:outputText value="#{sel.name}" />
                              </rich:column>
                              <rich:column>
                                  <h:outputText value="#{sel.timeZone}" />
                              </rich:column>
                          </rich:dataTable>
                      </rich:panel>
                  </h:panelGroup>
              </h:panelGrid>

       

      -------------------

      BrokerAdmin.java (this is the backing bean):

       

      private ExtendedTableBean etb = new ExtendedTableBean();

       

      public ExtendedTableBean getEtb() {
          return etb;
      }
      public void setEtb(ExtendedTableBean etb) {
          this.etb = etb;
      }

       

       

       

      //populate data here
              List tmpCapitals = new ArrayList<Capital>();
             
              Capital tmpcapital1 = new Capital();
              tmpcapital1.setName("Capital1");
              tmpcapital1.setState("State1");
              tmpCapitals.add(tmpcapital1);
              tmpcapital1 = null;
             
              Capital tmpcapital2 = new Capital();
              tmpcapital2.setName("Capital2");
              tmpcapital2.setState("State2");
              tmpCapitals.add(tmpcapital2);
              tmpcapital2 = null;
             
              Capital tmpcapital3 = new Capital();
              tmpcapital3.setName("Capital3");
              tmpcapital3.setState("State3");
              tmpCapitals.add(tmpcapital3);
              tmpcapital3 = null;
             
              Capital tmpcapital4 = new Capital();
              tmpcapital4.setName("Capital4");
              tmpcapital4.setState("State4");
              tmpCapitals.add(tmpcapital4);
              tmpcapital4 = null;
             
              etb.setCapitals(tmpCapitals);

      ---------------------------------

       

      ExtendedTableBean.java:

      /**
      *
      */
      package demo;

       


      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.apache.log4j.Logger;
      import org.richfaces.model.DataProvider;
      import org.richfaces.model.ExtendedTableDataModel;
      import org.richfaces.model.selection.Selection;
      import org.richfaces.model.selection.SimpleSelection;

       

      import org.apache.log4j.Logger;

       

      public class ExtendedTableBean {
          private String sortMode="single";
          private String selectionMode="multi";
          private Object tableState;
          private Selection selection = new SimpleSelection();
          private List<Capital> capitals = new ArrayList<Capital>();
          private ExtendedTableDataModel<Capital> dataModel;
          private List<Capital> selectedCapitals = new ArrayList<Capital>();
         
         
          private static final Logger myLogger = Logger.getLogger(ExtendedTableBean.class.getName());

       

          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 void takeSelection(){
                Iterator<Object> iterator = getSelection().getKeys();
              myLogger.error("DEBUGXXX : in takeSelection");
              while (iterator.hasNext()) {
                  Object key = iterator.next();
                  myLogger.error("DEBUGXXX : in takeSelectionm key = " + key.toString());
                  selectedCapitals.add(getCapitalsDataModel().getObjectByKey(key));
                        myLogger.error("DEBUGXXX : before remove capitals size = " + capitals.size());
                          capitals.remove(getCapitalsDataModel().getObjectByKey(key));
             
                          myLogger.error("DEBUGXXX : capitals size = " + capitals.size());
                              setSelection(new SimpleSelection());
                          dataModel.setRowKey(null);
                          dataModel.reset(); //this is needed so that the updated capitals list is included in the data model
                          myLogger.error("DEBUGXXX : after reset, row index = " + dataModel.getRowIndex());

       


              } //while
          }
         
         
         
          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();
                      }
                     
                  });
              }
              myLogger.error("DEBUGXXX : in getCapitalsDataModel 3");
              return dataModel;
          }

       

          public void setCapitals(List<Capital> capitals) {
              this.capitals = capitals;
          }

       

          public Object getTableState() {
              return tableState;
          }

       

          public void setTableState(Object tableState) {
              this.tableState = tableState;
          }

       

          public Selection getSelection() {
              return selection;
          }

       

          public void setSelection(Selection selection) {
              this.selection = selection;
          }

       

          public List<Capital> getSelectedCapitals() {
              return selectedCapitals;
          }

       

          public void setSelectedCapitals(List<Capital> selectedCapitals) {
              this.selectedCapitals = selectedCapitals;
          }

       

      }

       

       

      ---------------------------

      Capital.java:

       

      package demo;

       

      import java.io.Serializable;

       

      public class Capital implements Serializable {
          /**
           *
           */
          private static final long serialVersionUID = -1042449580199397136L;
          private boolean checked=false;
          private String name;
          private String state;
          private String timeZone;
          private CapitalData data;
         
          public CapitalData getData() {
              return data;
          }
          public void setData(CapitalData data) {
              this.data = data;
          }
          private final static String FILE_EXT = ".gif";
          public Capital() {
          }
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public String getState() {
              return state;
          }
          public void setState(String state) {
              this.state = state;
          }

       

          private String stateNameToFileName() {
              return state.replaceAll("\\s", "").toLowerCase();
          }
         
          public String getStateFlag() {
              return "/images/capitals/" + stateNameToFileName() + FILE_EXT;
          }
         
          public String getTimeZone() {
              return timeZone;
          }
          public void setTimeZone(String timeZone) {
              this.timeZone = timeZone;
          }
          public boolean isChecked() {
              return checked;
          }
          public void setChecked(boolean checked) {
              this.checked = checked;
          }
      }

       

       

      -----------------------------------

      faces-config.xml

       

      <managed-bean>
        <description>Demo Broker Admin</description>
        <managed-bean-name>brokeradmin</managed-bean-name>
        <managed-bean-class>demo.BrokerAdmin</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
      </managed-bean>
        <managed-bean>
        <managed-bean>
        <description>Extended Table Bean</description>
        <managed-bean-name>extendedTableBean</managed-bean-name>
        <managed-bean-class>demo.ExtendedTableBean</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
      </managed-bean>
         <managed-bean>
        <description>Capitals Bean</description>
        <managed-bean-name>capitalsbean</managed-bean-name>
        <managed-bean-class>demo.ExtendedTableBean</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
      </managed-bean>

        • 1. Re: ExtendedDataTable : cannot clear selection on reRender
          ndrw_cheung

          Ok, I found the solution:

           

          In regionResults.xhtml, the button needs to be changed to:

           

                       <a4j:commandButton ajaxSingle="true" action="#{brokeradmin.selectCapital}" id="btnGetSelectedRegions" reRender="selectiontable,table" value="Select Capital" >

           

          In ExtendedTableBean.java :

          1. Change the dataType of the variable "selection" to SimpleSelection.

          2. For the takeSelection method, remove the code :

                              setSelection(new SimpleSelection());
                              dataModel.setRowKey(null);

           

          In BrokerAdmin.java, add:

           

          public String selectCapital() {
                    etb.getSelection().clear();
                   etb.setSelection(new SimpleSelection());
                  etb.getSelection().setSelectAll(false);
                  return "";
              }