-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hello all,
I am facing a very small but strange issue while working on Custom pagination and Sorting. Pagination and Sorting both works fine but the only problem is when I sort the data, result on a first page display in a reverse direction.
e.g. I am on page 5 and clicked on header ID.
Descending Order Result
Data I am Expecting : 1260,1259,1258,1257,1256,1255......
Data it is showing right now: 1255,1256,1257,1258,1259,1260
Icon on a header changed to descending...
Ascending Order Result
Data I am Expecting : 1255,1256,1257,1258,1259,1260
Data it is showing right now: 1260,1259,1258,1257,1256,1255......
Icon on a header changed to ascending...
I got redirected to very first page, which is fine. Once I sort the data and navigate to next page (Page #2) and come back to page #1 then everything is in a order the way I want..i.e. 1260,1259,1258,1257,1256,1255......
I am unable to understand what thing I am doing wrong while sorting. Please take a look at the code below and any suggestions will be highly appreciated.
thanks ...Vish
TagsContoller.java
import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; import org.zkoss.lang.Strings; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.ext.AfterCompose; import org.zkoss.zul.Listbox; import org.zkoss.zul.Listcell; import org.zkoss.zul.Listhead; import org.zkoss.zul.Listheader; import org.zkoss.zul.Listitem; import org.zkoss.zul.Paging; import org.zkoss.zul.event.PagingEvent; public class TagsContoller extends SimpleWindow implements AfterCompose { /** * */ private static final long serialVersionUID = 1L; private final String LST_TAGS = "lstTags"; private final String PAG_TAGS = "pagTag"; private String ASCENDING = "ascending"; private String DESCENDING = "descending"; private String NATURAL = "natural"; private String DATE_FORMAT = "yyyy/MM/dd HH:mm:ss"; private boolean ascending = true; Listhead listhead; Listbox lstTags; private String getHeaderLabel(String label){ if(label != null && label.equalsIgnoreCase("Timestamp")){ return TagBlinkCache.TIMESTAMP_SEC_INDEX; }else if(label != null && label.equalsIgnoreCase("x")){ return TagBlinkCache.LOC_X_INDEX; }else if(label != null && label.equalsIgnoreCase("y")){ return TagBlinkCache.LOC_Y_INDEX; }else if(label != null && label.equalsIgnoreCase("z")){ return TagBlinkCache.LOC_Z_INDEX; }else if(label != null && label.equalsIgnoreCase("Exciter Id")){ return TagBlinkCache.STATION_ID_INDEX; }else{ return TagBlinkCache.TAG_ID_INDEX; } } public void redrawForAscDesc(String indexId){ List<TagBlink> list1 = TagBlinkCache.getInstance().getList(indexId); Paging pag = getPaging(PAG_TAGS); pag.setTotalSize(list1.size()); final int PAGE_SIZE = pag.getPageSize(); // Show Listbox with first PAGE_SIZE redraw(0, PAGE_SIZE,list1,true); pag.setActivePage(0); } public void onSortEventListener(Event event) { final Listheader lh = (Listheader) event.getTarget(); final String sortDirection = lh.getSortDirection(); String indexId = ""; if (ASCENDING.equals(sortDirection)) { ascending = true; indexId = getHeaderLabel(lh.getLabel()); redrawForAscDesc(indexId); } else if (DESCENDING.equals(sortDirection) || NATURAL.equals(sortDirection) || Strings.isBlank(sortDirection)) { ascending = false; indexId = getHeaderLabel(lh.getLabel()); redrawForAscDesc(indexId); } } @SuppressWarnings("unchecked") public void afterCompose() { lstTags = getListbox(LST_TAGS); Listhead listhead = lstTags.getListhead(); List<Listheader> list = listhead.getChildren(); for (Object object : list) { if (object instanceof Listheader) { Listheader lheader = (Listheader) object; if (lheader.getSortAscending() != null || lheader.getSortDescending() != null) { lheader.addEventListener("onSort", new EventListener() { public void onEvent(Event event) { onSortEventListener(event); } }); } } } String indexId = "tagId_INDEX"; final List<TagBlink> list1 = TagBlinkCache.getInstance().getList(indexId); Paging pag = getPaging(PAG_TAGS); pag.setTotalSize(list1.size()); final int PAGE_SIZE = pag.getPageSize(); // Show Listbox with first PAGE_SIZE redraw(0, PAGE_SIZE,list1,false); pag.addEventListener(org.zkoss.zul.event.ZulEvents.ON_PAGING, new EventListener() { public void onEvent(Event event) { PagingEvent pe = (PagingEvent) event; int pgno = pe.getActivePage(); int ofs = pgno * PAGE_SIZE; // Redraw current paging redraw(ofs, PAGE_SIZE,list1,false); } }); } private void redraw(int firstResult, int maxResults, List<TagBlink> list1,boolean sorting) { RangeFinder.Range range; List<TagBlink> subList; synchronized (list1) { range = RangeFinder.findRange(list1, firstResult, maxResults, ascending); try { subList = list1.subList(range.getFromIndex(), range.getToIndex()); } catch (IndexOutOfBoundsException e) { subList = new ArrayList<TagBlink>(); } } Listbox lst = getListbox(LST_TAGS); lst.getItems().clear(); SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT); for (TagBlink tagBlink : subList) { Listitem li = new Listitem(); li.setValue(tagBlink); li.appendChild(new Listcell("" + tagBlink.getSource())); li.appendChild(new Listcell(tagBlink.getFormat())); li.appendChild(new Listcell(tagBlink.getId())); li.appendChild(new Listcell(tagBlink.getX()+"")); li.appendChild(new Listcell(tagBlink.getY()+"")); li.appendChild(new Listcell(tagBlink.getZ()+"")); li.appendChild(new Listcell(tagBlink.getBattery()+"")); li.appendChild(new Listcell(tagBlink.getStationId()+"")); li.appendChild(new Listcell(tagBlink.getStatus()+"")); Date date = new Date(tagBlink.getTimestampMillis()); li.appendChild(new Listcell(df.format(date))); lst.appendChild(li); } } }
tags.zul
<?xml version="1.0" encoding="UTF-8"?> <?page id="zkHome" title="ZK Demo"?> <?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?> <?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="./cTags"?> <zk xmlns="http://www.zkoss.org/2005/zul"> <style src="../style/zls-console.css"></style> <style> div.z-grid-body{ background: white; border: 0; overflow: auto; width: 100%; } </style> <window width="100%" id="cTags" border="none" use="TagsContoller" xmlns:zk="http://www.zkoss.org/2005/zul" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:n="http://www.zkoss.org/2005/zk/native" xsi:schemaLocation="http://www.zkoss.org/2005/zul http://www.zkoss.org/2005/zul/zul.xsd"> <n:script type="text/javascript"><![CDATA[ function screenResolution(){ if(screen.height == 1024) zk.Widget.$(jq('$lstTags')[0]).setStyle('height:710px'); else if(screen.height == 864) zk.Widget.$(jq('$lstTags')[0]).setStyle('height:635px'); else if(screen.height == 768) zk.Widget.$(jq('$lstTags')[0]).setStyle('height:540px'); else if(screen.height == 600) zk.Widget.$(jq('$lstTags')[0]).setStyle('height:375px'); } ]]> </n:script> <attribute name="onCreate"><![CDATA[ Clients.evalJavaScript("screenResolution()"); ]]></attribute> <toolbar align="end"><div height="23px"> </div></toolbar> <div> <zk:listbox id="lstTags" vflex="true" style="height:540px" hflex="true"> <zk:listhead sizable="true"> <zk:listheader label="Source"/> <zk:listheader label="Format"/> <zk:listheader label="Tag Id" sort="auto" /> <zk:listheader label="x" sort="auto" width="5%"/> <zk:listheader label="y" sort="auto" width="5%"/> <zk:listheader label="z" sort="auto" width="5%"/> <zk:listheader label="Battery" width="10%"/> <zk:listheader label="Exciter Id" sort="auto" width="10%"/> <zk:listheader label="Status" width="10%"/> <zk:listheader label="Timestamp" sort="auto" /> </zk:listhead> </zk:listbox> <zk:paging id="pagTag" pageSize="25"/> </div> </window> </zk>
p.s. I debugged the code and also put Sys.out when it fill the list..it is filling the list in a correct order but while displaying on a page(.zul) it just comes out in a reverse order. Is this because I am having sort="auto" or ZUL page?
okay..I kind of figure it out..I just replaced above listbox with below and things started working..
<div> <zk:listbox id="lstTags" vflex="true" style="height:540px" hflex="true"> <zk:listhead sizable="true"> <zk:listheader label="Source"/> <zk:listheader label="Format"/> <zk:listheader label="Tag Id" sort="auto(id)" /> <zk:listheader label="x" sort="auto(x)" width="5%"/> <zk:listheader label="y" sort="auto(y)" width="5%"/> <zk:listheader label="z" sort="auto(z)" width="5%"/> <zk:listheader label="Battery" width="10%"/> <zk:listheader label="Exciter Id" sort="auto(stationId)" width="10%"/> <zk:listheader label="Status" width="10%"/> <zk:listheader label="Timestamp" sort="auto(timestampMillis)" /> </zk:listhead> </zk:listbox> <zk:paging id="pagTag" pageSize="25"/> </div>
as I said I kind of figure out..If I sort by Id then it looks okay as Id in my Object (TagBlink) is String.. X, Y, Z are double and timestamp is long..
how do I pass double, long and int into Listcell for comparison?
anyone??
thanks
Vish
It's behaving really weird now..above code works when I sort by ID..then I tried sorting by X, Y, Z and timestamp and it threw below error..
Mar 23, 2011 4:58:50 PM org.zkoss.zk.ui.impl.UiEngineImpl handleError:1253 SEVERE: >>org.zkoss.zk.ui.UiException: java.lang.NoSuchMethodException: class org.zkoss.zul.Listitem: name=timestampMillis args=null >>java.lang.NoSuchMethodException: class org.zkoss.zul.Listitem: name=timestampMillis args=null >> at org.zkoss.lang.Classes.myGetAcsObj(Classes.java:968) >> at org.zkoss.lang.Classes.getAccessibleObject(Classes.java:893) >> at org.zkoss.lang.reflect.Fields.get(Fields.java:114) >> at org.zkoss.lang.reflect.Fields.getByCompound(Fields.java:61) >> at org.zkoss.zul.FieldComparator.compare0(FieldComparator.java:119) >> at org.zkoss.zul.FieldComparator.compare(FieldComparator.java:82)
can anyone guide me in the right direction please?
thanks
A wild guess: sorting by id column works because Listitem has an "id" bean property.
@vradiya,
From your source code, it seems you don't associate a ListModel with the Listbox? Then the auto(xyz) mechanism will be applied onto the Listitem itself rather than the object in ListModel. The auto(xyz) assumes a getXyz() in the Object/Listitem and compare them for sorting purpose. So Matze2's guess is correct. The stack trace:
SEVERE: >>org.zkoss.zk.ui.UiException: java.lang.NoSuchMethodException: class org.zkoss.zul.Listitem: name=timestampMillis args=null
says the ZK engine try to find a getTimestampMillis() method on Listitem, but it cannot find it.
Here is a simple example you might like to take a look:
http://books.zkoss.org/wiki/Small_Talks/2009/March/New_Features_of_ZK_3.6.0#Listbox_supports_auto-sorting_on_fields
And this is an advanced example on how to load huge data with sorting and paging.
http://books.zkoss.org/wiki/Small_Talks/2011/March/Sorting_huge_data_using_ZK
I have the very same problem. Sorting works for all my columns columns, but the first page is always reversed after the sort order is changed (by clicking on a list column header). When I switch the page forward and back, the sort is OK again. Is there a clear solution to this problem? The discussion so far doesn't mention one...
Asked: 2011-03-23 14:43:51 +0800
Seen: 1,618 times
Last updated: Sep 08 '13