-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Dear ZK Forum
should i know this?
I have an app that collects a families details
Thats two parents and 1 or more children
each childs details are entered in a tabbox
so i need to dynamically create 1 or more tabboxes
As tabbox doesnt support data models
how can i do this?
is it possible to do?
Warm regards
Dick Dastardly
Review docs and api, please. ZK lets you create components programatically. Here are some lines of code to add tabs to a tabbox
Asume you have a zul page with a tabbox with id="tabbox", use Components.wirevariables() on, for example, afterCompose() (look at smalltalks about autowiring), then
Tabpanel tabpanel= new Tabpanel();
Tabtab= new Tab( title );
tabbox.getTabs().appendChild( tab );
tabbox.getTabpanels().appendChild(tabpanel);
You can do this wherever you want, zk will update you the ui. For example, when pressing a button.
It's easy, just modify the zul page using its components and properties. No secrets.
Hole that helps
Thanks for that
got the tabs being added dynamically
Now im stuck on how to bind the instances of the child list to each tab?
As i am using spring 3 i have already created and bound the data objects to the zk page
however as the user can dynamically add children i need to get access to the child List and resize it,
then bind the newly created instance to the new tab.
whats the cleanest way of doing this?
Sorry but the small talks i've looked at dont help!
DD
I've generated the components using Executions.createComponents
however i cannot get the data backing model to be bound to the input fields
How do you do this?
My included page has its own binder,
Also I cannot see how to use the tabindex value to control the iteration of the backing arraylist
Is this something i should be able to work out for myself?
have i let myself down? :-(
can no one help me?
DD
Hey dickdastardly, can you show me some of your code. It would really help to see your ZUL file and how you implemented the bindings.
Dear tmillsclare
heres my composer
main zul page
and included zul page for each tab within tabbox
what i am after is that the backing child list (a java arraylist) has each instances set by the associated tabindex within the tabbox.
also
a new tab and tab panel can be added when the user clicks the "add child" button.
I have managed to get a new tab and tab panel to be added to the tabbox, however i cannot get the data model to bind to the input & output fields
did i mention i was using spring 3.0?
package com.pre.school.zk.composer; import java.util.HashMap; import java.util.List; import java.util.Map; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Components; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.event.ForwardEvent; import org.zkoss.zk.ui.util.GenericForwardComposer; import org.zkoss.zkplus.databind.AnnotateDataBinder; import org.zkoss.zul.Button; import org.zkoss.zul.Datebox; import org.zkoss.zul.Tab; import org.zkoss.zul.Tabbox; import org.zkoss.zul.Tabpanel; import org.zkoss.zul.Tabpanels; import org.zkoss.zul.Tabs; import org.zkoss.zul.Textbox; import org.zkoss.zul.impl.InputElement; public class ValidationComposer extends GenericForwardComposer { private static final long serialVersionUID = -1870580858482873118L; private AnnotateDataBinder binder; private Component childComponent; public boolean allFieldsValid = true; private Button nextButton; private Tabbox childrenTabbox; @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); addChildrenTab(); addChildrenTab(); } // public void onClick$addChild(ForwardEvent event) throws Exception { // System.out.println(" in ValidationComposer"); // addChildrenTab(); // } public void onCreate$win(ForwardEvent event) { binder = (AnnotateDataBinder) event.getTarget().getAttributeOrFellow("binder", true); nextButton.setDisabled(true); } @SuppressWarnings("unchecked") public void onOK$win(ForwardEvent event) { List childComponents; childComponents = event.getTarget().getChildren(); childComponent = (Component) childComponents.get(0); if (getChildren(childComponent)) { nextButton.setDisabled(false); } else { nextButton.setDisabled(true); } binder.saveAll(); addChildrenTab(); } private int addChildrenTab() { Map<String,Integer> arguments = new HashMap<String, Integer>(); Tabpanel tabpanel = new Tabpanel(); Tab tab = new Tab("Another Child"); tab.setSelected(true); if (childrenTabbox.getTabs() == null){ childrenTabbox.appendChild(new Tabs()); childrenTabbox.appendChild(new Tabpanels()); } childrenTabbox.getTabs().appendChild(tab); arguments.put("tabularIndex", tab.getIndex()); System.out.println(" tab.getIndex() = " + tab.getIndex()); Executions.createComponents("childTAB.zul", tabpanel, arguments); childrenTabbox.getTabpanels().appendChild(tabpanel); childrenTabbox.invalidate(); return tab.getIndex(); } @SuppressWarnings("unchecked") private boolean getChildren(Component theseChildren) { List<Component> componentList; if (theseChildren == null) { return false; } componentList = (List<Component>) theseChildren.getChildren(); if ((componentList == null) || (componentList.size() == 0)) { return allFieldsValid; } for (Component myComponent : componentList) { if (myComponent instanceof Textbox) { ((Textbox) myComponent).getValue(); } else if (myComponent instanceof Datebox) { ((Datebox) myComponent).getValue(); } if (myComponent instanceof InputElement) { if (allFieldsValid) { allFieldsValid = ((InputElement) myComponent).isValid(); } } getChildren(myComponent); } return allFieldsValid; } }
heres the main page is here
<?xml version="1.0" encoding="UTF-8" ?> <?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?> <?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?> <?page title="family"?> <zk> <window id="win" title="B U R H A M PreSchool" border="normal" width="100%" height="100%" apply="com.pre.school.zk.composer.ValidationComposer"> <borderlayout height="100%"> <north size="30%" flex="true" maxsize="250" splittable="true" collapsible="true"> </north> <center border="normal"> <borderlayout> <west title="Parents/Gaurdians" size="33%" flex="true" maxsize="300" splittable="true" collapsible="true"> <div> <tabbox id="parentTabbox"> <tabs> <tab label="Mother" /> <tab label="Father" /> </tabs> <tabpanels> <tabpanel> <grid fixedLayout="false"> <columns> <column label="" width="25%" /> <column label="" width="25%" /> </columns> <rows> <row> <label value="Title" /> <combobox model="@{preSchoolReferenceData.titles}" selectedItem="@{family.mother.title}" readonly="true" mold="rounded"> <comboitem self="@{each='motherTitle'}" label="@{motherTitle.description}"> </comboitem> </combobox> </row> <row> <label value="First Name" width="100px" /> <textbox constraint="no empty" value="@{family.mother.firstName, save-when='self.onBlur'}" width="190px" /> </row> <row> <label value="Middle Name" width="100px" /> <textbox value="@{family.mother.middleName, save-when='self.onBlur'}" width="190px" /> </row> <row> <label value="Surname" width="100px" /> <textbox constraint="no empty" value="@{family.mother.surname, save-when='self.onBlur'}" width="190px" /> </row> <row> <label value="eMail Address" width="100px" /> <textbox constraint="no empty" value="@{family.mother.emailAddress, save-when='self.onBlur'}" width="190px" /> </row> <row> <label value="Address" width="100px" /> <textbox constraint="no empty" value="@{family.homeAddress.addressLine1, save-when='self.onBlur'}" width="230px" /> </row> <row> <label value="" width="100px" /> <textbox constraint="no empty" value="@{family.homeAddress.addressLine2, save-when='self.onBlur'}" width="230px" /> </row> <row> <label value="" width="100px" /> <textbox value="@{family.homeAddress.addressLine3, save-when='self.onBlur'}" width="230px" /> </row> <row> <label value="" width="100px" /> <textbox value="@{family.homeAddress.addressLine4, save-when='self.onBlur'}" width="230px" /> </row> <row> <label value="" width="100px" /> <textbox value="@{family.homeAddress.addressLine5, save-when='self.onBlur'}" width="230px" /> </row> <row> <label value="" width="100px" /> <textbox value="@{family.homeAddress.addressLine6, save-when='self.onBlur'}" width="230px" /> </row> <row> <label value="" width="100px" /> <textbox value="@{family.homeAddress.addressLine7, save-when='self.onBlur'}" width="230px" /> </row> <row> <label value="Post Code" width="100px" /> <textbox constraint="no empty" value="@{family.homeAddress.postcode, save-when='self.onBlur'}" width="90px" /> </row> </rows> </grid> </tabpanel> <tabpanel> <grid fixedLayout="false"> <rows> <row> <label value="Title" /> <combobox model="@{preSchoolReferenceData.titles}" selectedItem="@{family.father.title}" readonly="true" mold="rounded"> <comboitem self="@{each='fatherTitle'}" label="@{fatherTitle.description}"> </comboitem> </combobox> </row> <row> <label value="First Name" width="100px" /> <textbox value="@{family.father.firstName, save-when='self.onBlur'}" width="190px" /> </row> <row> <label value="Middle Name" width="100px" /> <textbox value="@{family.father.middleName, save-when='self.onBlur'}" width="190px" /> </row> <row> <label value="Surname" width="100px" /> <textbox value="@{family.father.surname, save-when='self.onBlur'}" width="190px" /> </row> <row> <label value="eMail Address" width="100px" /> <textbox constraint="no empty" value="@{family.father.emailAddress, save-when='self.onBlur'}" width="190px" /> </row> <row> <button id="nextButton" label="Next" href="/family/next/addpage1.do" /> </row> <row> <button id="addChild" label="Add Nipper" href="/family/next/addchild.do" /> </row> </rows> </grid> </tabpanel> </tabpanels> </tabbox> </div> </west> <center title="Children"> <div> <tabbox id="childrenTabbox"></tabbox> </div> </center> <east title="Telephone Contact(s)" size="33%" flex="true" maxsize="250" splittable="true" collapsible="true"> <div> <listbox id="contactBox" width="350px" model="@{family.mother.contact}"> <listhead sizable="true"> <listheader label="Type" sort="auto" /> <listheader label="Contact" sort="auto" /> <listheader label="Emergency" sort="auto" /> </listhead> <listitem self="@{each='motherContact'}"> <listcell label="@{motherContact.contactType.description}" /> <listcell> <textbox value="@{motherContact.contact}" /> </listcell> <listcell> <checkbox value="@{motherContact.emergency}" /> </listcell> </listitem> </listbox> </div> </east> </borderlayout> </center> </borderlayout> </window> </zk>
and the subpage included for each new tab in tabbox
<?xml version="1.0" encoding="UTF-8" ?> <?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?> <?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="./zeroKode${arg.tabularIndex}"?> <window id="zeroKode${arg.tabularIndex}"> <grid fixedLayout="false"> <columns> <column label="" width="15%" /> <column label="" width="30%" /> </columns> <rows> <row> <label value="Gender" /> <combobox model="@{preSchoolReferenceData.genders}" selectedItem="@{family.child.gender}" readonly="true" mold="rounded"> <comboitem self="@{each='childGender'}" label="@{childGender.description}"> </comboitem> </combobox> </row> <row> <label value="First Name ${arg.tabularIndex}" width="100px" /> <textbox constraint="no empty" value="@{family.child.firstName, save-when='self.onBlur'}" width="190px" /> </row> <row> <label value="Middle Name" width="100px" /> <textbox value="@{family.child.middleName, save-when='self.onBlur'}" width="190px" /> </row> <row> <label value="Surname" width="100px" /> <textbox constraint="no empty" value="@{family.child.surname, save-when='self.onBlur'}" width="190px" /> </row> <row> Date Of Birth: <hbox> <datebox onSelection="self.close()" readonly="false" mold="rounded" constraint="no empty, no future: Please enter a valid Date Of Birth" format="dd/MM/yyyy" value="@{family.child.dateOfBirth, save-when='self.onChange'}" /> </hbox> </row> <row> <label value="Language" /> <combobox model="@{preSchoolReferenceData.languages}" selectedItem="@{family.child.language}" readonly="true" mold="rounded"> <comboitem self="@{each='childLanguage'}" label="@{childLanguage.description}"> </comboitem> </combobox> </row> <row> <label value="Ethnic Group" /> <combobox model="@{preSchoolReferenceData.ethnicGroups}" selectedItem="@{family.child.ethnicGroup}" readonly="true" mold="rounded"> <comboitem self="@{each='childEthnicGroup'}" label="@{childEthnicGroup.description}"> </comboitem> </combobox> </row> <row> <label value="Religion" /> <combobox model="@{preSchoolReferenceData.religions}" selectedItem="@{family.child.religion}" readonly="true" mold="rounded"> <comboitem self="@{each='childReligion'}" label="@{childReligion.description}"> </comboitem> </combobox> </row> </rows> </grid> </window>
I am feeling unloved and ignored by the zk forum!
is there no one that can put me out of my misery?
Muttley, Do Something!!!!!!!!!!!!! :-)
@DD
Don't worry I love you and I will help you try and find the pigeon :).
I think the answer to your prayers may be here. Please try and use this function on your root component after creation with "createComponents" and it should iterate through them all and bind the data.
If not, please try iterating through the component list yourself.
Dear tmillsclare
Im feeling the love :-)
i'll give
loadComponent(Component comp) Load values from the data bean properties to all attributes of a specified UI component.
a go ...
however i can feel a "Drat and Double Drat" coming on :-(
D. Dastardly
WAH HAY tmillsclare
no "Drat" or indeed "Double Drat"
it works N I C E
Now i have one last outstanding problem....
Now that i can both dynamically create tabpanel(s) in my tabbox and bind the backing beans to the ui components
i now need to use the tabindex to control which instance of the child array (arrayList actually but how is counting!!!)
is bound on each individual tab
thanks again for helping
Yours
Dick D
private int addChildrenTab() { AnnotateDataBinder tabboxBinder; Component tabComponent; Map<String,Integer> arguments = new HashMap<String, Integer>(); Tabpanel tabpanel = new Tabpanel(); Tab tab = new Tab("Another Child"); tab.setSelected(true); if (childrenTabbox.getTabs() == null){ childrenTabbox.appendChild(new Tabs()); childrenTabbox.appendChild(new Tabpanels()); } childrenTabbox.getTabs().appendChild(tab); arguments.put("tabularIndex", tab.getIndex()); System.out.println(" tab.getIndex() = " + tab.getIndex()); tabComponent = Executions.createComponents("childTAB.zul", tabpanel, arguments); childrenTabbox.getTabpanels().appendChild(tabpanel); childrenTabbox.invalidate(); tabboxBinder = new AnnotateDataBinder(tabComponent); tabboxBinder.loadAll(); return tab.getIndex(); }
Asked: 2010-04-09 05:50:42 +0800
Seen: 1,403 times
Last updated: Jul 30 '10