7 Replies Latest reply on Feb 3, 2010 7:59 AM by ilya_shaikovsky

    ExtendedDataTable Selection Behavior Change

    kileksaic

      I've been using extendedDataTable on a project for about a year. In our tables, we are setting the 'selection' attribute of the extendedDataTable to a value expression on our backing bean (i.e. #{backingTableBean.selection}).

      We are also binding the 'value' attribute to our backing bean, which provides an instance of ExtendedTableDataModel. We instantiate ExtendedTableDataModel with our own data provider implementation.

      In v3.3.0, the selection property of our backing bean was always set to a SimpleSelection that contained the keys of our objects. These keys were derived per row when the RichFaces framework was calling getKey on our custom data provider. In our tables, this key was usually some UUID or other non-Integer type. So effectively, the selection property of the backing bean was a SimpleSelection containing a collection of UUIDs in v3.3.0. After upgrading to v3.3.2, the SimpleSelection now contains Integer values that correspond to the selected rows in the same order they are sorted. So, the first row in the sorted table would always be represented in the selection as Integer (0), the second row in the sorted list as Integer(1), and so on.

      This change in behavior is a little surprising. If we suppose that this was the intended behavior all along, how to I get back to my original UUIDs? I cannot find a method that maps the Integer keys to the table records or to the UUID keys of those records.

      The ExtendedTableDataModel has a method called getObjectAsKey, but when I pass to it one of the Integer from the selection object, I only get back a null reference.

      What is the proper way to get a list of selected records (or their real keys) from the keys being set in SimpleSelection?

      Keith

        • 1. Re: ExtendedDataTable Selection Behavior Change
          ilya_shaikovsky
          show please the code of model implementation.
          • 2. Re: ExtendedDataTable Selection Behavior Change
            kileksaic

            I spent some time today gutting my table code until the problem disappeared.  I was able to narrow the problem down to the filterBy attribute on the rich:column.  Once I did this, I created an independent test example in order to demonstrate the problem in isolated code.  For some reason, when the filterBy attribute is present on any of my columns, the keys being used by the table selection are all integers corresponding to the visible location of the selected row on the page.  When I remove filterBy, the keys are all UUIDs corresponding to the actual keys of the entities backing each row (as returned by getKey in the DataProvider implementation).  I'll paste in my test code below.  Note: Column A contains the filterBy which triggers the use of generated Integers rather than the key from the DataProvider:

             

            **** tabletest.html ****


                 . . .

                    <div style="width: 1024px; height: 500px">
                            
                         <rich:extendedDataTable id="testtable"
                                                 value="#{testTableBB.dataModel}"
                                                 selectionMode="multi"
                                                 selection="#{testTableBB.selection}"
                                                 var="rowRecord">


                            <a4j:support event="onselectionchange"
                                          action="#{testTableBB.onSelectionChanged}"
                                          ajaxSingle="true"
                                          limitToList="true"
                                          reRender="testtable"/>


                            <rich:column id="columnA"

                                                                      filterBy="#{rowRecord.name}">
                                 <f:facet name="header"><h:outputText value="Name"/></f:facet>
                                 #{rowRecord.name}
                             </rich:column>
                            
                             <rich:column id="columnB" width="300px">
                                 <f:facet name="header"><h:outputText value="ID"/></f:facet>
                                 #{rowRecord.id}
                             </rich:column>


                       
                         </rich:extendedDataTable>
                    
                     </div>

            . . .


             

             

            ***** TestTableBB.java ******


            package org.dummy.test;

             

            import java.io.Serializable;
            import java.util.Iterator;

             

            import org.jboss.seam.ScopeType;
            import org.jboss.seam.annotations.Name;
            import org.jboss.seam.annotations.Scope;
            import org.richfaces.model.DataProvider;
            import org.richfaces.model.ExtendedTableDataModel;
            import org.richfaces.model.selection.Selection;

             

            /**
            * Seam component backing-bean
            *
            */
            @Name("testTableBB")
            @Scope(ScopeType.CONVERSATION)
            @SuppressWarnings("unchecked")
            public class TestTableBB implements Serializable {

             

                /** */
                private static final long serialVersionUID = 1L;

             

                private Selection selection = null;
               
                private ExtendedTableDataModel dataModel = null;
               
                /**
                 *
                 * @return data model
                 */
                public ExtendedTableDataModel getDataModel() {
                    if (dataModel == null) {
                        dataModel = new ExtendedTableDataModel(createDataProvider());
                    }
                    return dataModel;
                }
               
               
                private DataProvider createDataProvider() {
                    return new TestTableDataProvider();
                }

             

                /**
                 *
                 * @param selection
                 */
                public void setSelection(Selection selection) {
                    this.selection = selection;
                }
               
                /**
                 *
                 * @return selection
                 */
                public Selection getSelection() {
                    return selection;
                }
               
                /**
                 *
                 */
                public void onSelectionChanged() {
                    if (selection != null) {
                        System.out.println("Selected keys: ");
                        Iterator it = selection.getKeys();
                        while (it.hasNext()) {
                            Object key = it.next();
                            System.out.println("key: "+key);
                        }
                    } else {
                        System.out.println("No selection is set.");
                    }
                }
            }

             

             

             

            /**** TestTableDataProvider.java *****/



            package org.dummy.test;

             

            import java.util.ArrayList;
            import java.util.HashMap;
            import java.util.List;
            import java.util.Map;
            import java.util.UUID;

             

            import org.richfaces.model.DataProvider;

             

            /**
            *
            *
            */
            @SuppressWarnings({"unchecked" })
            public class TestTableDataProvider implements DataProvider {

             

                /** */
                private static final long serialVersionUID = 1L;

             

                private Map<UUID,TestTableDummyEntity> dataTable;
                private List<TestTableDummyEntity> dataList;

             

                /**
                 *
                 */
                public TestTableDataProvider() {
                   TestTableDummyEntity entityA = createEntity("Entity A");
                   TestTableDummyEntity entityB = createEntity("Entity B");
                  
                   dataTable = new HashMap<UUID,TestTableDummyEntity>();
                   dataTable.put(entityA.getId(), entityA);
                   dataTable.put(entityB.getId(), entityB);
                  
                   dataList = new ArrayList<TestTableDummyEntity>(2);
                   dataList.add(entityA);
                   dataList.add(entityB);
                }
               
                private TestTableDummyEntity createEntity(String name) {
                    TestTableDummyEntity entity = new TestTableDummyEntity();
                    entity.setId(UUID.randomUUID());
                    entity.setName(name);
                    return entity;
                }

             

                public Object getItemByKey(Object key) {
                    UUID id = (UUID)key;
                    return dataTable.get(id);
                }

             

                public List getItemsByRange(int start, int end) {
                    return dataList.subList(start, end);
                }

             

                public Object getKey(Object entity) {
                    return ((TestTableDummyEntity)entity).getId();
                }

             

                public int getRowCount() {
                    return dataList.size();
                }

             

            }

             

             

             

             

            **** TestTableDummyEntity.java ****


            package org.dummy.test;

             

            import java.util.UUID;

             

            /**
            *
            *
            */
            public class TestTableDummyEntity {

             

                private UUID id;
                private String name;

             

                /**
                 * @return the id
                 */
                public UUID getId() {
                    return id;
                }
                /**
                 * @param id the id to set
                 */
                public void setId(UUID id) {
                    this.id = id;
                }
                /**
                 * @return the name
                 */
                public String getName() {
                    return name;
                }
                /**
                 * @param name the name to set
                 */
                public void setName(String name) {
                    this.name = name;
                }
               
               
            }

            • 3. Re: ExtendedDataTable Selection Behavior Change
              kileksaic
              It appears that switching to the "external filter" method does not change the behavior.  Switching filterBy to filterMethod and adding a "filter" facet to the column also causes the generated Integers to be set in the selection rather than the keys returned by the DataProvider.
              • 4. Re: ExtendedDataTable Selection Behavior Change
                ilya_shaikovsky

                Checked your code and the results:

                 

                without any changes - I'm getting the same keys in server log as need but them are changed between request because your conversation not has conversation start method - so it alive only one request and data model re-populated then

                 

                changing scope to session - revealed this model re-creation problem.

                 

                 

                But general result - I'm getting UUID's in log using filterBy before and after table filtering.

                • 5. Re: ExtendedDataTable Selection Behavior Change
                  ilya_shaikovsky
                  update - checked under 3.3.3 SNAPSHOT and Seam 2.2.0 (rf-demo environment)
                  • 6. Re: ExtendedDataTable Selection Behavior Change
                    clerum

                    Also see http://community.jboss.org/message/523816

                     

                    Is there a JIRA on this?

                    • 7. Re: ExtendedDataTable Selection Behavior Change
                      ilya_shaikovsky
                      no jira because as I written things goes fine for me using the code provided there. we'll check your thread separately.