-
FEATURED COMPONENTS
First time here? Check out the FAQ!
I know how to these kinds of things in old-skool JSP with EL, but having difficulty finding examples of this with ZK.
I'm using a template, as described in most of the current examples, but since I don't see iterations and I'm not sure how to integrate some kind of "c:set " concept between iterations, I'm not sure how I go about setting the previous value in scope so I can make decisions on how to display the next iteration? For example rather than see a list like:
Mammal Squirrel Mammal Fox Mammal Raccoon Bird Hawk Bird Sparrow
I want to hide the first column display if it was previously set so that it looks like:
Mammal Squirrel Fox Raccoon Bird Hawk Sparrow
But how do I do this within the following type of code:
<listbox model="@bind(vm.animals)" selectedItem="@bind(vm.selectedAnimal)" vflex="true"> <template name="model" var="animal"> <listitem> <!--- SOMETHING LIKE THIS??? How do I set "previous" animal ?? --> <listcell label="@bind(animal.class)" visible=${previous.class ne animal.class}></listcell> <listcell label="@bind(animal.family)"></listcell> </listitem> </template> </listbox>
Hi rickcr,
x.children [0] is EL equivalent to x.getChildren().get(0). During the first access I get the listcell element, the second access I get the label.
Do you have a more complex structure, you have to adjust accordingly the index or use the version with the attribute.
You also can create your label elements with an ID and search to them
<label id="@load('l'.concat(forEachStatus.index))" value="@load(each.animalClass)" visible="@load(forEachStatus.index eq 0 ? true : not (lb.getFellow('l'.concat(forEachStatus.index-1)).value.equals(each.animalClass)))"/>
Kai
@khcyt Very cool! When I get back from vacation I'll want to try that out and will have to investigate how that's working. (I haven't really grasped how you know what the selectors are doing (eg children[0]) based on the definition of the listbox/template definition. I'll figure it out though.
This is what I was looking for though was some way to do it with forEachStatus or previous (as in some of my earlier posts were inquiring about.) (I have to admit it's still somewhat easier to do with JSTL in a JSP leveraging c:set, but this helps. Thanks a lot.)
Hi rickcr,
another proposal to solve your problem without saving the state in the viewmodel.
<?xml version="1.0" encoding="UTF-8"?> <?page id="new_page" contentType="text/html;charset=UTF-8"?> <zk> <zscript><![CDATA[ ListModel lm= new ListModelList(); public static class Animal { private String _animalClass; private String _name; public Animal (String animalClass, String name) { _animalClass = animalClass; _name = name; } public String getAnimalClass () { return _animalClass; } public String getName () { return _name; } } class VM { public VM() { lm.add(new Animal("CLASS_ONE", "NAME_ONE")); lm.add(new Animal("CLASS_ONE", "NAME_TWO")); lm.add(new Animal("CLASS_TWO", "NAME_THREE")); } public ListModel getListModel() { return lm; } } ]]></zscript> <window id="win" title="how can I get the previous row " border="normal" width="600px" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('VM')" > <listbox id="lb" model="@bind(vm.listModel)"> <listhead> <listheader hflex="1" label="animalClass"/> <listheader hflex="2" label="name"/> </listhead> <template name="model"> <listitem vflex="1"> <listcell> <label value="@load(each.animalClass)" visible="@load(forEachStatus.index eq 0 ? true : not (lb.children[forEachStatus.index].children[0].children[0].value.equals(each.animalClass)))"/> </listcell> <listcell> <label value="@load(each.name)"/> </listcell> </listitem> </template> </listbox> </window> </zk>
You can also store the animalclass as an attribute in listitem.
<listitem vflex="1" attributes.aclass="@load(each.animalClass)"> ... <label value="@load(each.animalClass)" visible="@load(forEachStatus.index eq 0 ? true : not (lb.children[forEachStatus.index].getAttribute('aclass').equals(each.animalClass)))"/>
Kai
@rdgrimes good catch. I fixed it http://zkfiddle.org/sample/23m3med/7-Get-previous-value-in-template-with-MVVM-VM-way2
relevant change:
<listcell label="@load(not vm.equalPrevious ? animal.animalClass:'')" />
@rickr:
The only problem, when you run it, it doesn't quite work. I see:
animalClass name CLASS_ONE NAME_ONE NAME_TWO CLASS_TWO NAME_THREE
I've found you can't use visible as it behaves as though the cell was removed and shifts everything to the left. At least, in Google Chrome and Safari on the Mac, and IE 9 on the PC, that's what I see. I had tried that in my example earlier, and found it was problematic, which is why I settled on setting the label = ""; What I ended up doing in my real project is setStyle("font-size: 0") because I still needed the set value when the user clicks on that line. It's a lousy substitution for setVisible, but it works.
Use straight iteration might have better performance, but it is a little bit break the MVVM pattern since the code in VM considering 'the value of previous item' and the 'previous item' is UI part stuff.
However it is still a good way to go if you think it makes your code more clear and easier to maintain, that is the most important thing.
I still think one would be the best for performance. One straight iteration http://zkfiddle.org/sample/23m3med/5-Get-previous-value-in-template-with-MVVM-VM-way2#source-2
@Ron,
Yes it is more dynamic (and should have better performance too) to get previous item directly instead of accessing session :D.
@benbai:
That's very slick. Glad you posted it. I'm sure that will come in handy for me as well.
Ron
Asked: 2012-10-24 14:26:29 +0800
Seen: 310 times
Last updated: Dec 12 '12