Multiple Field Sorting on Listbox

From Documentation
DocumentationSmall Talks2009JanuaryMultiple Field Sorting on Listbox
Multiple Field Sorting on Listbox

Author
Cloudchen, Engineer, Potix Corp.
Date
Jan 13, 2009
Version
Applicable to ZK 3.5.3 and later.

Introduction

In introduction of Grids, Trees and Listbox of developer's guide, we learned how to sort particular fields within listbox automatically. First we introduce a simple example.

Sorting in Listbox with Fixed Data

Here is an example of listbox with fixed data and can be sorted automatically:

<listbox fixedLayout="true">
	<listhead>
		<listheader label="Full Name" sort="auto"/>
		<listheader label="Gender" align="center" sort="auto"/>
		<listheader label="Age" align="center" sort="auto"/>
	</listhead>
	<listitem>
		<listcell label="Tom Anderson"/>	
		<listcell label="Male"/>
		<listcell label="26"/>
	</listitem>	
	<listitem>
		<listcell label="John Chen"/>	
		<listcell label="Male"/>
		<listcell label="23"/>
	</listitem>	
	<listitem>
		<listcell label="Carey Chen"/>	
		<listcell label="Female"/>
		<listcell label="23"/>
	</listitem>	
	<listitem>
		<listcell label="Jean Anderson"/>	
		<listcell label="Female"/>
		<listcell label="26"/>
	</listitem>	
</listbox>

Before sorting :

Smalltalk030800.jpg

Now we sort it by full name, comparison will be started from the first character :

Smalltalk030801.jpg

We see the result of sorting, but how about sorting last name in the listbox? We need a comparator to help us do this.

Sorting Listbox with Live Data

From the developer's guide introduced at the beginning of this article, we learnt how to insert live data into listbox. In this case we have to sort our listbox manually, which means by creating a comparator for the listbox. We design a comparator which could sort last name in the last case. Besides this, the comparator should be able to sort other items of the listbox, in other words, it can sort items of two data types : string (full name and gender)and integer(grades).

class MyItemComparator implements Comparator {
	    private boolean asc = false;
	    private int index =0;
	    private int type = 0;
	    private int v;  
	    
	    public MyItemComparator(boolean ascending,int i,int t) {
	       asc = ascending;
	       index = i;
	       type = t;
	    }
	    public int compare(Object o1, Object o2) {       
	    	Student l1 = (Student)o1;
	    	Student l2 = (Student)o2;
	    	Object temp1 = (index==0) ? l1.getFullName() : (index==1) ? l1.getGender() : l1.getAge();
	    	Object temp2 = (index==0) ? l2.getFullName() : (index==1) ? l2.getGender() : l2.getAge();
	    	
	    	if (type ==0){
	    		String s1 = (String)temp1;
	    		String s2 = (String)temp2;
	    		v = s1.compareTo(s2);  
	    	}
	    	else{
	    		Integer s1 = (Integer)temp1;
	    		Integer s2 = (Integer)temp2;
	    		v = s1.compareTo(s2);
	    	} 
	    	
	       return asc ? v: -v;
	    }
  }

Then we modify zul file to :

<zscript>
       Comparator asc = new MyItemComparator(true,0,0);        
       Comparator dsc = new MyItemComparator(false,0,0);
       Comparator asc1 = new MyItemComparator(true,1,0);        
       Comparator dsc1 = new MyItemComparator(false,1,0);
       Comparator asc2 = new MyItemComparator(true,2,1);        
       Comparator dsc2 = new MyItemComparator(false,2,1);
</zscript>
<listbox fixedLayout="true" model="@{persons}">
	<listhead>
		<listheader label="Full Name" sortAscending="${asc0}" sortDescending="${dsc0}"/>
		<listheader label="Gender" align="center" sortAscending="${asc1}" sortDescending="${dsc1}"/>
		<listheader label="Grades" align="center" sortAscending="${asc2}" sortDescending="${dsc2}"/>
	</listhead>
	<listitem self="@{each=persons}">
		<listcell label="@{persons.fullName}"/>	
		<listcell label="@{persons.gender}"/>
		<listcell label="@{persons.age}"/>
	</listitem>	
</listbox>

Ok, now we make a listbox with live data and can be sorted by full name, gender, and ages.

  • How about sorting by last name?

Don't worry, just modify two lines of comparator as follows:

Object temp1 = (index==0) ? l1.getLastName() : (index==1) ? l1.getGender() : l1.getAge();
Object temp2 = (index==0) ? l2.getLastName() : (index==1) ? l2.getGender() : l2.getAge();

Finally, sorting listbox by last name.

Smalltalk030802.jpg

  • How about sorting by last name and then first name?

Don't worry, just modify comparator......oh, the code would be complicated.

New Feature

  • Do you agree that it takes time and effort to create comparator for a listbox?

  • Do you compromise that your listbox can only be sorted by one item if you don't want to design a comparator for it?


Now don't worry about the two situations above. We could make use of a new feature of ZK 3.5.3 to solve this. With few modifications for the first two examples we'll sort last name and then first name easily. Amazingly, there is no more comparator implementation.

<listheader label="Full Name" sort="auto(lastName, firstName)"/>
<listheader label="Gender" align="center" sort="auto(gender)"/>
<listheader label="Grades" align="center" sort="auto(age)"/>

After sorting, we will see :

Smalltalk030803.jpg

Amazing! And we can sort last name and then age by

<listheader label="Full Name" sort="auto(lastName,age)"/>
<listheader label="Gender" align="center" sort="auto(gender)"/>
<listheader label="Grades" align="center" sort="auto(age)"/>

Let's see the result of sorting.

Smalltalk030804.jpg

Summary

In this article, we present how to sort fields in listbox with fixed and live data. For live data, we must design comparator to make sorting. Although comparator can help sort by specified rules, it took much time and effort to design complicated algorithm. Finally, we introduce a new feature of ZK 3.5.3 to make task easy. The most important of all, we can use this feature to sort multiple fields automatically.


Download




Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.