0

foreach

asked 2011-05-29 10:38:42 +0800

ftmichael gravatar image ftmichael
129 1

updated 2011-05-29 10:42:11 +0800

hi there,
i'm in trouble. i've just read documentations and forum-posts, but i've not found any solution for my problem.

i have a composer: MyComposer.java
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
//new UserDB();
UserDB.createPOIs();
//wire variables
Components.wireVariables(comp, this);
//register onXxx event listeners
Events.addEventListeners(comp, this);
//auto forward
Components.addForwards(comp, this);
list.add("Eins");
list.add("Zwei");
comp.setAttribute("test", this, false);
}
public List<String> getList(){
return list;
}
and a zul page: index.zul where i apply my MyComposer.java
in this zul file i want to loop throught the returned list:
<zk forEach="${test.testList}" >
<textbox value="${each}" />
</zk>

the problem is, that this won't work. i found out that in "foreach" there is only EL allowed.
i have to access the variable defined in MyComposer.

I hope someone can help me.
Best Regards

[Edit:] I'm using the latest version of zk

delete flag offensive retag edit

18 Replies

Sort by ยป oldest newest

answered 2011-05-29 11:06:16 +0800

ftmichael gravatar image ftmichael
129 1

updated 2011-05-29 11:23:32 +0800

ok i've got it working by using session.setAttribute and bind the component.
my next question is, when i edit the textbox and want to override the current value i have to do that with the onChange event manually or will the "set" methode be called?
the problem is: <textbox id="txt" value="${each}" />
in java i can do the following: public void onChange$txt{} but if more than two textboxes are generated by foreach there is a conflict because all textboxes have the same id. how can i solve this?

<textbox value="Eins"/>
<textbox value="Zwei"/>

if the first textbox changed his value to "One" this new value should also replace "Eins" in the java-List "list" correctly.

link publish delete flag offensive edit

answered 2011-05-30 08:22:53 +0800

caclark gravatar image caclark
1753 2 5
http://clarktrips.intltwi...

First, use the code tags available in this forum editor. Look at the line immediate above the text editor when you're creating a new thread or right above the Post Reply button when replying.

Secondly, the answer to your original post is that forEach is evaluated, using only EL, in the component creation phase of the page's lifecycle. The doAfterCompose() is called later in the rendering phase. So, when your ZUL was evaluated, "testList" had no value.

There's a (apparently) little known interface that GFC implements named ComposeExt that has a doBeforeCompose() method. This is called BEFORE the page is rendered, so it's appropriate to initialize variables there that EL expressions need. Just be aware that when using forEAch, you'll not be able to change the list of components that are generated. EL and forEach are 1 time deals because of them being done during the component creation phase (aka the composer's Compose time in the doBefore/AfterCompose()) unlike those created by databinding.

Third, you're doing things in your doAfterCompose() method that are already done for you. The Components::wireVariables and Components::addForwards are done for you by GFC and its ancestors. Your code should be:

    public void doAfterCompose(Component comp) throws Exception
    {
        super.doAfterCompose(comp);  // stuff done for you here...
        //new UserDB();
        UserDB.createPOIs();
    }

    public void doBeforeCompose(Component comp) throws Exception
    {
        super.doBeforeCompose(comp);
        list.add("Eins");
        list.add("Zwei");
        comp.setAttribute("test", this, false);
    }

link publish delete flag offensive edit

answered 2011-06-02 05:11:02 +0800

ftmichael gravatar image ftmichael
129 1

Hey caclark, thanks for your reply.
i'm knowing the issue with EL.
i'm searching for a solution where i can create textboxes at runtime, where databinding can deal with onChange-Events.
the current solution is i'm creating a listbox with a model="@{win$composer.getList}" then i'm looping the list and create textboxes in listcell. that's working fine, but i don't want to use a listbox or gridbox. i just want the number of textboxes with databinding.

i hope you understand my problem.

link publish delete flag offensive edit

answered 2011-06-02 08:01:36 +0800

caclark gravatar image caclark
1753 2 5
http://clarktrips.intltwi...

Not following you so much...

link publish delete flag offensive edit

answered 2011-06-02 08:16:12 +0800

ftmichael gravatar image ftmichael
129 1

ok from beginning (i don't know the correct syntax):

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" root="win" ?>
<window id="win" apply="myComposer">

<listbox id="box" model="@{win$composer.getAll}">
	<listhead>
		<listheader label="a lot of text" sort="auto" />
	</listhead>
	<listitem self="each..." value="...">
		<listcell ><textbox value="@{list.text}" /></listcell
	</listitem>
</listbox>
</window>

this snippet works fine, if i'm changing the textbox the databinder binds the new value. he calls list.setText().
the problem is, that i won't use listbox. i want to do it like for-each, but it only works with EL, so when i'm changing the text, the methode list.setText() is not called because of EL.
the result should look like this:

<vlayout>
<zk foreach...>
<vbox><textbox value="@{list.text}" /></vbox>
</zk>
</vlayout>

this example won't work because of EL.

link publish delete flag offensive edit

answered 2011-06-02 11:44:30 +0800

caclark gravatar image caclark
1753 2 5
http://clarktrips.intltwi...

Hook the onChange or onChanging event, as appropriate, and forward it to your controller. Also, look into adding a custom attribute to the textbox and assigning it the value of "each" from your foreach iteration. This will let you retrieve the domain model when the onChange/onChanging event is fired and update the correct value.

Remind me why you don't want to use databinding?

link publish delete flag offensive edit

answered 2011-06-02 12:01:17 +0800

ftmichael gravatar image ftmichael
129 1

i want to use databinding! but it doesn't work with foreach because of EL... databinding is for me, that zk determines if it have to call setText() and getText(). an this is not possible with foreach and EL

link publish delete flag offensive edit

answered 2011-06-02 13:02:38 +0800

caclark gravatar image caclark
1753 2 5
http://clarktrips.intltwi...

You're only going to be able to use databinding with components that support the model attribute.

From your earlier post:

...but i don't want to use a listbox or gridbox...

Why not?

link publish delete flag offensive edit

answered 2011-06-02 13:16:37 +0800

ftmichael gravatar image ftmichael
129 1

because its a table look&feel and in the next step i want to replace textbox with ckeditor and they can't be placed in listbox.

link publish delete flag offensive edit

answered 2011-06-02 13:54:15 +0800

terrytornado gravatar image terrytornado flag of Germany
9393 3 7 16
http://www.oxitec.de/

updated 2011-06-02 13:56:00 +0800

ftmichael, automatically databinding is not the solution for all things !!!

Try to use an Itemrenderer. In it you can do what you want with your textboxes. And like Cary said, use than the forwarding of the textbox Events.


not tested

public class MyRenderer implements ListitemRenderer {

	@Override
	public void render(Listitem item, Object data) throws Exception {

	final Customer customer = (Customer) data;

	Listcell lc = new Listcell(customer.getKunNr());
	lc.setParent(item);
	
        Listcell lc = new Listcell();
        Textbox txtbox = new Textbox();
        txtbox.setParent(item);
        ComponentsCtrl.applyForward(txtbox, "onChanging=onChangingMethodInTheController");

	item.Value( data) ;

}

best
Stephan

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2011-05-29 10:38:42 +0800

Seen: 1,639 times

Last updated: May 01 '12

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More