-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hi,
I have a Listbox defined as this:
<listbox id="games" multiple="false" model="@{win$composer.allGames, load-after='convert.onClick, apply.onClick, upload.onUpload'}" selectedItem="@{win$composer.current}"> <listhead> <listheader label="Game ID" width="110px" sort="auto(gameIDNo)"/> </listhead>
...and the sort works fine, when the listheader is clicked, but is there a way of sorting this automatically when the listbox is filled/loaded?
Please notice that it is not filled when the pages first appears, but is filled when convert, apply or upload button has been triggered.
Thanks in advance :)
Today I faced the same problem described above.
After walking through the code, I found that the most elegant solution is to write a converter for this.
The following converter works for my use case: a listbox, model described by data binding is a List, so the standard coerceToUi method converts it to a ListModelList.
It sorts the model according to the current settings in the ListHeader before setModel is called by the data binding mechanism.
public class SortedListModelConverter extends ListModelConverter { private static final long serialVersionUID = 1L; @Override public Object coerceToUi(Object val, Component comp) { Object bean = super.coerceToUi(val, comp); if (bean instanceof ListModelList && comp instanceof Listbox) { Listbox listbox = (Listbox) comp; ListModelList model = (ListModelList) bean; for (Object child : listbox.getListhead().getChildren()) { final Listheader hd = (Listheader)child; if ("natural".equals(hd.getSortDirection())) { continue; } else if ("ascending".equals(hd.getSortDirection())) { model.sort(hd.getSortAscending(), true); } else if ("descending".equals(hd.getSortDirection())) { model.sort(hd.getSortDescending(), true); } } } return bean; } }
In my opinion, ZK should do this automatically. Instead the sort indicators on the list headers are still shown, even if the result is not sorted at all.
But anyway...
Hi
Here is another way to do it
<?page title="new page title" contentType="text/html;charset=UTF-8"?> <zk> <label multiline="true"> <attribute name="value"> Demo how to auto sort when user add data to model </attribute> </label> <zscript><![CDATA[ import org.zkoss.zk.ui.*; import org.zkoss.zk.ui.util.*; class Person { String _name; public Person(String name) { _name = name; } public String getName() { return _name; } } class MyComposer extends GenericForwardComposer{ Listbox lb; Textbox input; AnnotateDataBinder binder; List list = new ArrayList(); public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); list = new ArrayList(); list.add(new Person("Jim")); list.add(new Person("Apple")); list.add(new Person("Soga")); list.add(new Person("Bobo")); //bind all components inside "comp" binder = new AnnotateDataBinder(comp); binder.bindBean("persons", list); binder.loadAll(); } public void onClick$btn(Event evt) { String name = input.getValue(); if (!"".equals(name)) { list.add(new Person(name)); Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { Person p1 = (Person)o1; Person p2 = (Person)o2; return p1.getName().compareTo(p2.getName()); } }); binder.loadAll(); } } } ]]></zscript> <window title="new page title" border="normal" apply="MyComposer"> <listbox id="lb" model="@{persons}" height="200px"> <listitem self="@{each=entry}"> <listcell label="@{entry.name}"></listcell> </listitem> </listbox> <textbox id="input"></textbox><button id="btn" label="Add Name"></button> </window> </zk>
Hi samchuang,
my solution covers the case where you have multiple columns in the listbox and you want to control the sort strategy via listheaders.
If the model is filled, then the click on the listheaders does its job.
But if you, e.g. want to refresh your model, you need to prepare the model yourself to be sorted according to the sort indicators in the list headers (which is still active).
In your solution, you fix the sorting in the code ("order by name ascending") for one business object.
My solution works for all business objects, as long as the model is a list (could be easily extended to array or any other list models, of course) and as long the automatic sorting in the list headers worked before.
And, finally, because it is possible to solve this problem in a generic way, I wonder, if ZK itself should not do this.
Or - to not show wrong information - reset the sort state of list headers (which is of course not the favourite solution).
Your example with my converter for illustration (manually edited, not tested):
<window title="new page title" border="normal" apply="MyComposer"> <listbox id="lb" model="@{persons, converter='matze.SortedListModelConverter', load-after='btn.onclick'"," height="200px"> <listhead sizable="true"> <listheader label="Name" sort="auto(name)" /> </listhead> <listitem self="@{each=entry}"> <listcell label="@{entry.name}"></listcell> </listitem> </listbox> <textbox id="input"></textbox><button id="btn" label="Add Name"></button> </window> class MyComposer extends GenericForwardComposer{ Textbox input; AnnotateDataBinder binder; List list = new ArrayList(); public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); list = new ArrayList(); list.add(new Person("Jim")); list.add(new Person("Apple")); list.add(new Person("Soga")); list.add(new Person("Bobo")); //bind all components inside "comp" binder = new AnnotateDataBinder(comp); binder.bindBean("persons", list); binder.loadAll(); } public void onClick$btn(Event evt) { String name = input.getValue(); if (!"".equals(name)) { list.add(new Person(name)); } } }
Hello,
Here is the solution : http://books.zkoss.org/wiki/ZK_Configuration_Reference/zk.xml/The_Library_Properties/org.zkoss.zul.listbox.autoSort (http://books.zkoss.org/wiki/ZKConfigurationReference/zk.xml/TheLibraryProperties/org.zkoss.zul.listbox.autoSort)
Just to add one working solution.
<listheader label="Game ID" width="110px" sort="auto(gameIDNo)" onCreate="self.sort(true)"/>
The API: http://www.zkoss.org/javadoc/7.0.1/zk/org/zkoss/zul/Listheader.html#sort(boolean)
Asked: 2010-09-10 05:38:11 +0800
Seen: 1,415 times
Last updated: Apr 22 '14