ZK 6 Composite component getter not working in view model
hi,
you need addition information(annotation) to support save-binding in composite or other custom component.
please follow this feature request. http://tracker.zkoss.org/browse/ZK-833
Hi Dennis,
I have the same troubles with composite component.
I did getter and setter for Date value (in my case).
I send event onChange, when internal component is updated.
Events.postEvent(Events.ON_CHANGE,this,null);
Different is only in my annotations:
<testcomposite someProp="@{vm.selected.website,save-when='self.onChange'}" self="@action(recalculate,when='onChange')"/>
Action "recalculate" works fine, but data binding works only for setter.
When can I expect solution for this issue?
pmq
@jaan
this feature was resolved by http://tracker.zkoss.org/browse/ZK-883 already,
following is the example to enable binding for imagelabel in the smalltalk http://books.zkoss.org/wiki/Small_Talks/2011/December/Define_Composite_Component_using_Java_Annotation_in_ZK6.
@ComponentAnnotation({"description:@ZKBIND(ACCESS=both,SAVE_EVENT=onAfterEdit)","title:@ZKBIND(ACCESS=both,SAVE_EVENT=onAfterEdit)"})
public class ImageLabel extends Div implements IdSpace {..}
@pmq
form the syntax, you are trying zkbind1
did you try zkbind2 ? it is more powerful and easier than zkbind1
you can read document here. http://books.zkoss.org/wiki/ZK%20Developer's%20Reference/MVVM
Hi Dennis,
Where can I find package for Componentannotation?
I cannot find library with org.zkoss.zk.ui.annotation.ComponentAnnotation
pmq
it is after zk 6.0.1, it is freshly now. try here, http://www.zkoss.org/download/freshly/
Adding to this. Is there any support for child components? Like the one I describe in ZK 6 Composite Feature
Hi,
I follow the small talk to composite a component and and it making an error to deploy:
Caused by: java.lang.IncompatibleClassChangeError: Found class org.objectweb.asm.AnnotationVisitor, but interface was expected
It seems that the 3 jars added + zk 6.0.1 make this error. (in the original version 6.0 also).
thanks in advance
Hi,
I have been trying to deploy your example and it was impossible. I have been learning how to make the composite components with the example that is found in the demo components: ListBox:DualListBox. It was impossible that this component updated the status populating the input listbox in MVVM, bumping into the same problem
<emailDualListbox id="dualLBox" candidateModel="@init(initEmailDualBox)"/>
thank in advance
I think you have multiple asm jars in the project and they conflict.
Hi,
Thanks for your help.... I built the component step by step and is working (is updated form VMMV to Component but not from component to VMMV).... The only problem that onAfterEvent is not fire... I dont know why, any idea!!
<div id="EmailDiv">
<emailDualListbox id="dualLBox" candidateList="@bind(vm.candidateEmailDualBox)" chosenList="@bind(vm.chosenEmailDualBox)" >
<attribute name="onAfterEdit"><![CDATA[
alert("new title is: "+event.candidateList);
alert("new title is: "+event.chosenList);
]]></attribute>
</emailDualListbox>
</div> public static final String ON_AFTER_EDIT = "onAfterEdit";
public class AfterEditEvent extends Event{
private static final long serialVersionUID = 7283694297879164498L;
public AfterEditEvent() {
super(ON_AFTER_EDIT, EmailDualListbox.this);
}
public List<CodeExtraInfoVo> getCandidateList(){
return new ArrayList<CodeExtraInfoVo>(candidateModel);
}
public List<CodeExtraInfoVo> getChosenList() {
System.out.println("dddddddd");
return new ArrayList<CodeExtraInfoVo>(chosenModel);
}
Do you know if i have to do something special to updated the information from the component to VMMV?
Thanks in advance...
if you are talking about dual listbox selection, I just wrote a simple example for you.
MoveSelectionVM.java
package j1p545q6$v2;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.NotifyChange;public class MoveSelectionVM {
Set<String> selection1;
List<String> list1;
Set<String> selection2;
List<String> list2;
public MoveSelectionVM(){
list1 = new ArrayList<String>();
list2 = new ArrayList<String>();
selection1 = new HashSet<String>();
selection2 = new HashSet<String>();
for (int i=0;i<10;i++){
list1.add("Item "+i);
}
}public Set<String> getSelection1() {
return selection1;
}public void setSelection1(Set<String> selection1) {
this.selection1 = selection1;
}public List<String> getList1() {
return list1;
}public Set<String> getSelection2() {
return selection2;
}public void setSelection2(Set<String> selection2) {
this.selection2 = selection2;
}public List<String> getList2() {
return list2;
}
@Command
@NotifyChange({"list1","list2","selection1","selection2"})
public void moveToList1(){
if(selection2!=null && selection2.size()>0){
list1.addAll(selection2);
list2.removeAll(selection2);
selection1.addAll(selection2);
selection2.clear();
}
}
@Command
@NotifyChange({"list1","list2","selection1","selection2"})
public void moveToList2(){
if(selection1!=null && selection1.size()>0){
list2.addAll(selection1);
list1.removeAll(selection1);
selection2.addAll(selection1);
selection1.clear();
}
}
}
index.zul
<window apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('j1p545q6$v2.MoveSelectionVM')">
<hlayout>
<vlayout>
List1
<listbox model="@bind(vm.list1)" selectedItems="@bind(vm.selection1)" multiple="true" width="300px" height="300px"/>
</vlayout>
<vbox vflex="1" pack="middle">
<button label=">" onClick="@command('moveToList2')"/>
<button label="<" onClick="@command('moveToList1')"/>
</vbox>
<vlayout>
List2
<listbox model="@bind(vm.list2)" selectedItems="@bind(vm.selection2)" multiple="true" width="300px" height="300px"/>
</vlayout>
</hlayout>
</window>
please try it on fiddle and switch the zk version to 6.0.0
Hi Dennis,
i am not explain myself very well, apologizes about that. I will try again:
1.- i make it the dualboxlist like you do in your last post
2.- I get this and make it a composite component with that, following yours recomendation. Right i can instance this component populating from VMMV a list and initializating the component in correct way. When i pass a elemnt i can get the event and the element updated.
3.- I create a zul page with the composite and a button to store in DB the chosen elements:
<emailDualListbox id="dualLBox" candidateList="@bind(vm.candidateEmailDualBox)" chosenList="@bind(vm.chosenEmailDualBox)" >
<button label="Store" onClick="@command('StoreDB')"/>
4.- The problem is the folowing:
The dualBoxList has to list:
-> One the initially the candidatesList form VMMV is OK: the candistes is render n the component correctly.
-> When pass elements from the candidates to the chosen it is fire an event and it is working fine also . I can get it the element also, no problem...
but when press StoreDB button to get chosenElements in the MVVM function is fired and i get the chosenElement list empty (or with the same elements when it was initially ). that it menas that from the composite components has to inform the VMMV about this chosenlist is change and this is not happens. I know that i can use directly the event form the component to updated the chosenList for each buttton, buit to avoid to do that for every element that the user select and avoid more ajax call innecesaries i would like to get the whole list form the component.
This means that i can send and update informaton from MVVM => Component but in reverse way from the COmponent to MVVM is not happens and maybe the only solution for that is to updated in each event increasing the ajax call to the server....
Regards
Could you provide your implementation(and the test-case) to me, hard to know what you have done (and what is wrong or missing in your composite implementation).
Can you share the code in gist http://gist.github.com?
Here you have the link with the code:
git@gist.github.com:741eba05139d98065066.git
regards
https://gist.github.com/741eba05139d98065066
Create.Zul
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<zk>
<window border="none" width="100%" height="100%" xmlns:w="client" >
<include id="includeStyle" src="/style/default.zul" ></include>
<borderlayout width="100%" height="100%" vflex="true">
<center border="normal" flex="true" class="center" style="overflow:auto; background: white" autoscroll="true"
apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('es.migou.myamp.fe.myamp.CreateAmpVm')"
form="@id('fx') @save(vm.codeVo , before='save' )">
<vlayout spacing="2%" style="overflow:auto; background: white">
<div id="msgAreaRememberWindow" visible="@load(vm.isVisibleMessageArea)" >
<label value="@load(vm.messageArea)" style="color : #FF0000; font-style:italic;font-size:15px;"></label>
</div>
<div align="left">
<label value="${labels.newAmp.main.infoTxt}" style="font-size: 15px;"></label>
</div>
<groupbox id="EmailGroup" mold="3d" closable="true" width="50%" open="false">
<caption image="/images/icon_email.png" label="Email" ></caption>
<div id="EmailDiv">
<emailDualListbox id="dualLBox" candidateList="@bind(vm.candidateEmailDualBox)" chosenList="@bind(vm.chosenEmailDualBox)" >
<attribute name="onChoose"><![CDATA[
alert("new title is: "+event.candidateList);
alert("new title is: "+event.chosenList);
]]></attribute>
</emailDualListbox>
</div>
</groupbox>
<vlayout>
<button label="Guardar" onClick="@command('save')"></button>
<button label="Atrás" onClick="@command('goToWelcome')" ></button>
</vlayout>
</vlayout>
</center>
<east width="5%" border="normal" flex="true" vflex="min" >
</east>
<south border="normal" class="footer" size="45px">
<include src="/footer/footer.zul"></include>
</south>
</borderlayout>
</window>
</zk>
CreateAmpVm.java
package es.migou.myamp.fe.myamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.Clients;
import es.migou.myamp.be.myamp.MyAmpLocator;
import es.migou.myamp.be.myamp.service.code.CodeServiceRemote;
import es.migou.myamp.be.myamp.vo.code.CodeExtraInfoVo;
import es.migou.myamp.be.myamp.vo.code.CodeVo;
import es.migou.myamp.be.myamp.vo.enumerates.CodeTypeEnum;
import es.migou.myamp.fe.vo.ComboVo;
public class CreateAmpVm
{
private static final Logger log = Logger.getLogger(CreateAmpVm.class);
private MyAmpLocator locator;
private CodeVo codeVo;
private String messageArea;
private Boolean isVisibleMessageArea;
private List<ComboVo> codeTypeList;
private ComboVo selectedCodeType;
private List<CodeExtraInfoVo> candidateEmailDualBox;
private List<CodeExtraInfoVo> chosenEmailDualBox;
@Init(superclass=true)
public void init()
{
locator=MyAmpLocator.getInstance();
codeVo=new CodeVo();
messageArea="";
isVisibleMessageArea=false;
this.loadCodeTypeList();
selectedCodeType=new ComboVo();
this.loadEmailDualList();
}
@Command("goToHome")
public void goToWelcome(){
log.debug("[CreateAmpVm - goToHome] - redirect:/welcome.zul");
Executions.sendRedirect("/welcome.zul");
}
@NotifyChange({"selectedCodeType"})
@Command("onSelectCodeType")
public void onSelectCodeType()
{
log.debug("[CreateAmpVm - onSelectCodeType] - init");
log.debug("[CreateAmpVm - onSelectCodeType] - selectedCodeType:"+selectedCodeType.getCode());
if (CodeTypeEnum.ADDRESS_BOOK.toString().equals(selectedCodeType.getCode())){
Clients.evalJavaScript("jq('$personalInfoDiv').hide().slideDown(1000);");
Clients.evalJavaScript("jq('$professionalInfoDiv').show().slideUp(1000);");
this.loadCodeTypeList();
}else if(CodeTypeEnum.VCARD_COMPANY.toString().equals(selectedCodeType.getCode())){
Clients.evalJavaScript("jq('$personalInfoDiv').show().slideUp(1000);");
Clients.evalJavaScript("jq('$professionalInfoDiv').hide().slideDown(1000);");
}else if(CodeTypeEnum.VCARD_PROFESIONAL.toString().equals(selectedCodeType.getCode())){
Clients.evalJavaScript("jq('$personalInfoDiv').hide().slideDown(1000);");
Clients.evalJavaScript("jq('$professionalInfoDiv').hide().slideDown(1000);");
}
}
@NotifyChange({"isVisibleMessageArea", "messageArea"})
@Command("save")
public void save()
{
long T1=System.currentTimeMillis();
log.debug("[CreateAmpVm - save] -INIT ");
isVisibleMessageArea=true;
try{
log.debug("[CreateAmpVm - save] - codeVo: "+codeVo);
log.debug("[CreateAmpVm - save] - Creating codeVo...");
log.debug("[CreateAmpVm - save] - candidateEmailDualBox:"+candidateEmailDualBox);
log.debug("[CreateAmpVm - save] - chosenEmailDualBox:"+chosenEmailDualBox);
// CodeServiceRemote codeService = locator.getCodeService();
// codeService.createCode(codeVo);
messageArea=Labels.getLabel("newAccount.suscess.000");
}catch (Exception ex){
log.error("[CreateAmpVm - save] - Error:",ex);
messageArea=Labels.getLabel("general.error.001");
}finally{
log.debug("[CreateAmpVm - save] - isVisibleMessageArea:"+isVisibleMessageArea);
log.debug("[CreateAmpVm - save] - messageArea:"+messageArea);
log.debug("[CreateAmpVm - save] - Finish Timing:"+(System.currentTimeMillis()-T1));
}
}
public CodeVo getCodeVo() {
return codeVo;
}
public void setCodeVo(CodeVo codeVo) {
this.codeVo = codeVo;
}
public String getMessageArea() {
return messageArea;
}
public void setMessageArea(String messageArea) {
this.messageArea = messageArea;
}
public Boolean getIsVisibleMessageArea() {
return isVisibleMessageArea;
}
public void setIsVisibleMessageArea(Boolean isVisibleMessageArea) {
this.isVisibleMessageArea = isVisibleMessageArea;
}
public void loadEmailDualList()
{
candidateEmailDualBox=new ArrayList<CodeExtraInfoVo>();
chosenEmailDualBox=new ArrayList<CodeExtraInfoVo>();
long uuid=0;
CodeExtraInfoVo codeExtraInfoVo = null;
codeExtraInfoVo = new CodeExtraInfoVo();
codeExtraInfoVo.setIdCode(uuid++);
codeExtraInfoVo.setSubcategory("Email");
codeExtraInfoVo.setValue(uuid+"ss@hotmail.com");
candidateEmailDualBox.add(codeExtraInfoVo);
codeExtraInfoVo = new CodeExtraInfoVo();
codeExtraInfoVo.setIdCode(uuid++);
codeExtraInfoVo.setSubcategory("Email");
codeExtraInfoVo.setValue(uuid+"sxxxxxxxdsds@hotmail.com");
candidateEmailDualBox.add(codeExtraInfoVo);
System.out.println("loadEmailDualList - FINISH");
}
public void loadCodeTypeList()
{
System.out.println("loadCodeTypeList");
List<ComboVo> codeTypeListAux=new ArrayList<ComboVo>();
Collection<String> codeTypeEnumList=CodeTypeEnum.literals();
Iterator<String> ite=codeTypeEnumList.iterator();
while(ite.hasNext())
{
String code=ite.next();
ComboVo comboVo=new ComboVo(code , Labels.getLabel("CodeTypeEnum."+code));
codeTypeListAux.add(comboVo);
}
this.codeTypeList =codeTypeListAux;
}
public List<ComboVo> getCodeTypeList() {
return codeTypeList;
}
public void setCodeTypeList(List<ComboVo> codeTypeList) {
this.codeTypeList = codeTypeList;
}
public ComboVo getSelectedCodeType() {
return selectedCodeType;
}
public void setSelectedCodeType(ComboVo selectedCodeType) {
this.selectedCodeType = selectedCodeType;
}
public List<CodeExtraInfoVo> getCandidateEmailDualBox() {
return candidateEmailDualBox;
}
public void setCandidateEmailDualBox(List<CodeExtraInfoVo> candidateEmailDualBox) {
this.candidateEmailDualBox = candidateEmailDualBox;
}
public List<CodeExtraInfoVo> getChosenEmailDualBox() {
return chosenEmailDualBox;
}
public void setChosenEmailDualBox(List<CodeExtraInfoVo> chosenEmailDualBox) {
this.chosenEmailDualBox = chosenEmailDualBox;
}
}
emailDualListbox.zul
<!-- View of customized component DualListbox -->
<vlayout vflex="true" hflex="true">
<zscript><![CDATA[
String imgPath = "/images/composite/emailDualList";
]]></zscript>
<space spacing="2%"></space>
<hlayout>
<vlayout hflex="1"></vlayout>
<label value="Email"></label>
<textbox hflex="1" id="codeInpt" value="" ></textbox>
<textbox hflex="1" id="cods" value="" ></textbox>
<button id="add" label="Add" image="${imgPath}/icon_add_email.png"
hoverImage="${imgPath}/icon_add_email_hover.png" style="cursor:pointer" ></button>
<vlayout hflex="1"></vlayout>
</hlayout>
<hlayout vflex="true" hflex="true" spacing="2%">
<listbox id="candidateLb" vflex="true" hflex="true" multiple="true" emptyMessage="No items match your search">
<listhead>
<listheader hflex="min"></listheader>
<listheader hflex="min" label="Tipo"></listheader>
<listheader hflex="min" label="Email"></listheader>
</listhead>
<template name="model">
<listitem>
<listcell image="${imgPath}/icon_email.png"></listcell>
<listcell label="${each.subcategory}"></listcell>
<listcell label="${each.value }"></listcell>
</listitem>
</template>
</listbox>
<vbox vflex="true" spacing="10px" align="center" pack="center">
<image style="cursor:pointer" id="chooseAllBtn" src="${imgPath}/rightrightarrow_g.png" ></image>
<image style="cursor:pointer" id="chooseBtn" src="${imgPath}/rightarrow_g.png" ></image>
<image style="cursor:pointer" id="removeBtn" src="${imgPath}/leftarrow_g.png" ></image>
<image style="cursor:pointer" id="removeAllBtn" src="${imgPath}/leftleftarrow_g.png" ></image>
</vbox>
<listbox id="chosenLb" vflex="true" hflex="true" width="380px" multiple="true" emptyMessage="Dont select Any items">
<listhead>
<listheader hflex="1"></listheader>
<listheader hflex="1" label="Tipo"></listheader>
<listheader hflex="3" label="Email"></listheader>
</listhead>
<template name="model">
<listitem>
<listcell image="${imgPath}/icon_email.png"></listcell>
<listcell label="${each.subcategory}"></listcell>
<listcell label="${each.value }"></listcell>
</listitem>
</template>
</listbox>
<vbox spacing="10px">
<image style="cursor:pointer" id="topBtn" src="${imgPath}/upuparrow_g.png" ></image>
<image style="cursor:pointer" id="upBtn" src="${imgPath}/uparrow_g.png" ></image>
<image style="cursor:pointer" id="downBtn" src="${imgPath}/downarrow_g.png" ></image>
<image style="cursor:pointer" id="bottomBtn" src="${imgPath}/downdownarrow_g.png" ></image>
</vbox>
</hlayout>
</vlayout>
EmailDualListbox.java
package es.migou.myamp.fe.composite;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import org.zkoss.composite.Composite;
import org.zkoss.composite.Composites;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.IdSpace;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.select.annotation.Listen;
import org.zkoss.zk.ui.select.annotation.Wire;
import org.zkoss.zul.Div;
import org.zkoss.zul.ListModelList;
import org.zkoss.zul.Listbox;
import es.migou.myamp.be.myamp.vo.code.CodeExtraInfoVo;
@Composite(name="emailDualListbox")
public class EmailDualListbox extends Div implements IdSpace {
/**
*
*/
private static final long serialVersionUID = 5183321186606483396L;
@Wire
private Listbox candidateLb;
@Wire
private Listbox chosenLb;
private ListModelList<CodeExtraInfoVo> candidateModel;
private ListModelList<CodeExtraInfoVo> chosenModel;
public EmailDualListbox() {
Composites.doCompose(this, null);
}
@Listen("onClick = #chooseBtn")
public void chooseItem() {
Events.postEvent(new ChooseEvent(this, chooseOne()));
}
@Listen("onClick = #removeBtn")
public void unchooseItem() {
Events.postEvent(new ChooseEvent(this, unchooseOne()));
}
@Listen("onClick = #chooseAllBtn")
public void chooseAllItem() {
for (int i = 0, j = candidateModel.getSize(); i < j; i++) {
chosenModel.add(candidateModel.getElementAt(i));
}
candidateModel.clear();
}
@Listen("onClick = #removeAllBtn")
public void unchooseAll() {
for (int i = 0, j = chosenModel.getSize(); i < j; i++) {
candidateModel.add(chosenModel.getElementAt(i));
}
chosenModel.clear();
}
@Listen("onClick = #topBtn")
public void top() {
int i = 0;
Iterator<CodeExtraInfoVo> iterator = new LinkedHashSet<CodeExtraInfoVo>(chosenModel.getSelection()).iterator();
while (iterator.hasNext()) {
CodeExtraInfoVo selectedItem = iterator.next();
chosenModel.remove(selectedItem);
chosenModel.add(i++, selectedItem);
chosenModel.addToSelection(selectedItem);
}
}
@Listen("onClick = #upBtn")
public void up() {
Set<CodeExtraInfoVo> selected = chosenModel.getSelection();
if (selected.isEmpty())
return;
int index = chosenModel.indexOf(selected.iterator().next());
if (index == 0 || index < 0)
return;
CodeExtraInfoVo selectedItem = chosenModel.get(index);
chosenModel.remove(selectedItem);
chosenModel.add(--index, selectedItem);
chosenModel.addToSelection(selectedItem);
}
@Listen("onClick = #downBtn")
public void down() {
Set<CodeExtraInfoVo> selected = chosenModel.getSelection();
if (selected.isEmpty())
return;
int index = chosenModel.indexOf(selected.iterator().next());
if (index == chosenModel.size() - 1 || index < 0)
return;
CodeExtraInfoVo selectedItem = chosenModel.get(index);
chosenModel.remove(selectedItem);
chosenModel.add(++index, selectedItem);
chosenModel.addToSelection(selectedItem);
}
@Listen("onClick = #bottomBtn")
public void bottom() {
Iterator<CodeExtraInfoVo> iterator = new LinkedHashSet<CodeExtraInfoVo>(chosenModel.getSelection()).iterator();
while (iterator.hasNext()) {
CodeExtraInfoVo selectedItem = iterator.next();
chosenModel.remove(selectedItem);
chosenModel.add(selectedItem);
chosenModel.addToSelection(selectedItem);
}
}
/**
* Set new candidate ListModelList.
*
* @param candidate is the of candidate list model
*/
public void setCandidateList(List<CodeExtraInfoVo> candidate) {
System.out.println("setCandidateList candidate:"+candidate);
candidateLb.setModel(this.candidateModel = new ListModelList<CodeExtraInfoVo>(candidate));
chosenLb.setModel(chosenModel = new ListModelList<CodeExtraInfoVo>());
}
public List<CodeExtraInfoVo> getCandidateList()
{
System.out.println("getCandidateList");
return new ArrayList<CodeExtraInfoVo>(candidateModel);
}
/**
* @return current chosen list
*/
public List<CodeExtraInfoVo> getChosenList() {
System.out.println("getChosenList");
return new ArrayList<CodeExtraInfoVo>(chosenModel);
}
public void setChosenList(List<CodeExtraInfoVo> chosen) {
chosenLb.setModel(this.chosenModel = new ListModelList<CodeExtraInfoVo>(chosen));
}
private Set<CodeExtraInfoVo> chooseOne() {
Set<CodeExtraInfoVo> set = candidateModel.getSelection();
for (CodeExtraInfoVo selectedItem : set) {
chosenModel.add(selectedItem);
candidateModel.remove(selectedItem);
}
return set;
}
private Set<CodeExtraInfoVo> unchooseOne() {
Set<CodeExtraInfoVo> set = chosenModel.getSelection();
for (CodeExtraInfoVo selectedItem : set) {
candidateModel.add(selectedItem);
chosenModel.remove(selectedItem);
}
return set;
}
// Customized Event
public class ChooseEvent extends Event {
private static final long serialVersionUID = -7334906383953342976L;
public ChooseEvent(Component target, Set<CodeExtraInfoVo> data) {
super("onChoose", target, data);
}
public List<CodeExtraInfoVo> getCandidateList(){
System.out.println("ChooseEvent - getCandidateList");
return new ArrayList<CodeExtraInfoVo>(candidateModel);
}
public List<CodeExtraInfoVo> getChosenList() {
System.out.println("ChooseEvent - getChosenList");
return new ArrayList<CodeExtraInfoVo>(chosenModel);
}
}
}
OK, you have to let binder know when to save the value of component back to bean when the component change (with the onChoose event fired) by adding zkbind annotation of your composite componet.
here, try to add this in EmailDualListbox
@Composite(name="emailDualListbox")
@ComponentAnnotation({"candidateList:@ZKBIND(ACCESS=both,SAVE_EVENT=onChoose)","chosenList:@ZKBIND(ACCESS=both,SAVE_EVENT=onChoose)"})
public class EmailDualListbox extends Div implements IdSpace {
..
}Thanks you very much for oyur help. It has been very worthy..
ZK - Open Source Ajax Java Framework
Hi,
I'm a very newbie in ZK and Java. But I do love the technology by now.
After a lot of trial (and more error) I bumped into the following problem.
I've created a composite component following this smalltalk: Define Composite Component using Java Annotation in ZK6
@Composite(name="testcomposite") public class TestComposite extends Textbox implements IdSpace { private String someProp; public TestComposite() { } public String getSomeProp() { return this.getValue(someProp); } public void setSomeProp(String someProp) { this.setValue(someProp) } }Now if I bind some data from a viewModel to this someProp-property it is set (setSomeProp is called).
So when I try :
the textbox is filled with the website data.
But when I try to save the data nothing is changed in vm.selected. It never updates the website value.
I'm doing stupid things? Am I forgetting something?
jaan