Sorting on List Shuttle...

Version 2

    Hello All,

     

    This List shuttle is a wonderful component to use.  Many use this for moving chosen items         from one list into another with their optional reordering.  Along with this feature it also comes handy when there is a list of entities and you have to perform some bulk updates on some selected entities.

     

    In the case the bulk update, the user feels friendly if the displayed order in the source as well as target list sorted.  I dont think there is an option for sorting the list as and when the list changes.  So we end up creating some work around which will involve some manual process.  Let me explain how we can achieve this sorting on the list shuttle.

     

    Consider the scenario where in which there is a list of empoyess, you need to change the office location or any other field for selected employees.  And the requirement is that the display on the source list should be sorted in ascending order of Firstname and then be last name.

     

    Here is how we can do that:

     

    1.  XHTML

     

    Actually i'm using 2 column display lets say, firstName and lastName...  even the target list needs to be displayed in sorted order...

     

              <rich:listShuttle id="employeeBulkUpdateList"
                    sourceValue="#{bulkUpdateEmployeePageForm.sourceEmployeeList}"
                    targetValue="#{bulkUpdateEmployeePageForm.targetEmployeeList}" 
                    var="items" 
                    orderControlsVisible="false"
                    fastOrderControlsVisible="false" converter="employeeConverter">
                    <rich:column>
                         <f:facet name="header">
                            <h:outputText value="#{msg['bulkUpdateEmployee.columnHeader.firstName']}" />
                         </f:facet>
                        <h:outputText value="#{items.firstName}" />
                    </rich:column>
                    <rich:column>
                        <f:facet name="header">
                            <h:outputText value="#{msg['bulkUpdateEmployee.columnHeader.lastName']}" />
                         </f:facet>
                        <h:outputText value="#{items.lastName}" />
                    </rich:column>
                    <a4j:support event="onlistchanged"

                           action="#{bulkUpdateEmployeePageForm.sortEmployeeLists()}"                                                 reRender="employeeBulkUpdateList"/>
                </rich:listShuttle>

     

    2.  Java Entity Employee

     

    To use the Collection.sort() method the entity should implement Comparator and it should define the compareTo() function.

     

    class Employee implements Comparator<Employee> {

        String firstName;
        String lastName;
        ....


        @Override
        public int compareTo(Employee newObj) {
            int employeeCmp = firstName.compareTo(newObj.firstName);

     

            return (employeeCmp!= 0 ? employeeCmp: lastName.compareTo(newObj.lastName));

        }

    }

     

    3.  Page form:

    I can call a method on the pageForm which will sort the lists:

     

         public void sortEmployeeLists() {
            List<Employee> sourceList = getSourceEmployeeList();
            Collections.sort(sourceList);
            setSourceEmployeeList(sourceList);



            List<Employee> targetList = getTargetEmployeeList();
            Collections.sort(targetList);
            setTargetEmployeeList(targetList);
        }

     

    So on the change of the list, the above function is triggered and the lists will be sorted...  The drawback of this workaround is - the performance will depend on the number of items on list elements because on each click of the buttons the entire list needs to be sorted.

     

    Thanks

    Deepak