You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Srinivas Yermal <sy...@indygosoft.com> on 2006/11/10 14:29:48 UTC

ForBean issues

Hi,

I am a newbie trying to learn Tapestry. I did try to search through the
archives for a solution, but couldnt find anything relavant. It would be
great if someone could point me in the right direction.

I have a page with a listing of a collection. I am using "For" component
(ForBean) in the form. There are text fields against each item which has a
value from the items in the collection. Now one can change the text value
and hit the save button at the end of the form. The listener that is
associated with the form gets called but I dont have a clue as to how I can
obtain the changed values from the collection. I tried with both form
listener and submit action listener. I always end up with a null or empty
item collection.

Some code snippet below -

public abstract Collection getItems();
public abstract void setItems(Collection items);

ActionListener Method 1:
public void saveHistory(IRequestCycle cycle, Object[] list) {
        LOG.debug("saveHistory(cycle, array) invoked");
        if (null == list) return;
        for (Object o : list) {
            Question mh = (Question)o;
            LOG.debug(mh.getQuestionText() + " " + mh.getAnswerText());
        }
}

ActionListener Method 2:
public void saveHistory(IRequestCycle cycle) {
        LOG.debug("saveHistory(cycle, array) invoked");
        List list = cycle.getListenerParameters();
        if (null == list) return;
        for (Object o : list) {
            Question mh = (Question)o;
            LOG.debug(mh.getQuestionText() + " " + mh.getAnswerText());
         }
}


FormListner Method:
public void saveFormHistory(IRequestCycle cycle) {
        LOG.debug("saveFormHistory(cyle) invoked");
        Collection<Question> list = getItems();
        if (null == list) return;
        for (Question mh: list) {
            LOG.debug(mh.getQuestionText() + " " + mh.getAnswerText());
        }
}

The HTML file -

<form jwcid="ListHistory@Form" listener="listener:saveFormHistory">
...
<tr jwcid="@For" source="ognl:items" value="ognl:item" element="tr">
  <td><span jwcid="@Insert" value="ognl:item.question.text">Question
Text</span></td>
  <td><input jwcid="@TextField" value="ognl:item.answerText"/></td>
</tr>
...
<input class="button" type="submit" value="Save" name="save"
jwcid="@Submit" action="listener:saveHistory"
parameters="ognl:items"/>

Please do let me know if something here is not right or if you have any
further questions. Looking forward for some advice.

Thanks in advance.
Regards,
Srini.

Re: ForBean issues

Posted by Srinivas Yermal <sy...@indygosoft.com>.
Hi Gabriel,

Thanks for the detailed steps. We tried this out, but it didnt work. The
observation here was that only the first item in the collection has the user
entered value while others in the collection dont have their values set.

However I am happy to report that we have solved the issue. We had to use
the DefaultPrimaryKeyConverter as Lutz suggested and it works. We fed the
converter in pageBeginRender and had to access the collection through the
converter.getValues() in the listener. This actually brings up another
question. If I have to use the converter by default for getting to the
changed values, it doesnt somehow seem right. I thought the converter
existed for an all together different purpose of providing the primary key
values to the For loop and viceversa, and not to access changed values.
Either I am doing something that is absolutely not right or this might be a
bug(?).

Another thing I forgot to mention which might be of interest to people is
that we were using the JAG 6.1 generated files. It looks like their delete
function in the list pages which uses checkboxes is also not working for
this reason.
Thanks,
Srini.

On 11/15/06, Gabriel Lozano <gh...@gmail.com> wrote:
>
> Hey what I do is the following:
>
> 1. You have to initialize the collection somewhere. Yes, pageBeginRender
> is
> ok ( well, sorry for the tapestry gurus, but I have also done it that way
> ).
> And dont have to initialize it in the rewind phase.
> 2. What I do is to "hide" the collection in the form. Oh, what I did
> sometime was to persist the collection property ( tap 3) but now I prefer
> to
> do this.  Items in the collection should implement serializable interface.
> In your code I would do:
>
> <form jwcid="ListHistory@Form" listener="listener:saveFormHistory">
> <span jwcid="@Hidden" value="ognl:items"/>
> ...
> <tr jwcid="@For" source="ognl:items" value="ognl:item" element="tr">
> <td><span jwcid="@Insert" value="ognl:item.question.text">Question
> Text</span></td>
> <td><input jwcid="@TextField" value="ognl:item.answerText"/></td>
> </tr>
>
> 3. I dont pass parameters to the submit method, I think you dont need it.
> 4. With this, in the submit or in the form listener you should have access
> to the updated collection.
>
> Tell me if this works for you.
>
> Gabriel H. Lozano M.
>
>
> On 11/14/06, Srinivas Yermal <sy...@indygosoft.com> wrote:
> >
> > Thanks so much for the response. I will try out the
> > DefaultPrimaryKeyConverter and InvokeListener options.
> > My comments inline -
> >
> >
> > > Anyway.. about your code: obviously, I can't tell you which is best.
> > > But I think you don't have to pass your items as a parameter to the
> > > listener method. Instead, the form fields (in this case, the
> > > collection) will be bound to an instance variable in your page object.
> > > Maybe you should drop that parameters attribute in the @Submit.
> > > But you have to make sure the list is not null during rewind, and has
> > > the right length, so you have to refill it before the rewind, and the
> > > values will be overwritten during rewind.
> >
> >
> > I tried not passing them as parameter initially, but that didnt work.
> > Setting the parameter was something that I guessed might work, but it
> > doesnot. I have also made sure that the items object is not null during
> > rewind phase by removing the if condition in pageBeginRender, but all it
> > does is gives me the same items without change to any values. On a side
> > note, actually it might turn out be a overhead in large pages if I have
> to
> > run the query again just for the rewind phase. Moreover, the collection
> is
> > serialised and is available from the form, isnt it? Shouldnt it be
> > deserialized?
> >
> > I have another observation to add. I have a method that returns the
> > PropertySelectionModel for each item depending on the item. This is
> > required
> > for the dropdowns for each item. The dropdown values depend on the item.
> > During the rewind phase this method gets called and I get proper objects
> > with proper values. But when the submit listener gets called I still get
> a
> > null collection or the old collection. Is there any other method like
> say
> > renderComponent of the page that I have to implement?
> >
> > The listener method that is called will be the one referenced in the
> > > @Submit component. In your case, the one referenced in the @Form is
> > > never called, I think. So you might want to lose on of those two, to
> > > avoid confusion.
> >
> >
> > Actually, both the listeners get called. The form listener gets invoked
> > last. I have both the listeners just as an experiment to see if I get a
> > non-null proper collection in any listener at all.
> > Thank you very much for the advice. Will continue trying and see where
> > this
> > goes. Its just that I am running out of time.
> > Regards,
> > Srini.
> >
> >
>
>


-- 
http://www.indygosoft.com

Re: ForBean issues

Posted by Gabriel Lozano <gh...@gmail.com>.
Hey what I do is the following:

1. You have to initialize the collection somewhere. Yes, pageBeginRender is
ok ( well, sorry for the tapestry gurus, but I have also done it that way ).
And dont have to initialize it in the rewind phase.
2. What I do is to "hide" the collection in the form. Oh, what I did
sometime was to persist the collection property ( tap 3) but now I prefer to
do this.  Items in the collection should implement serializable interface.
In your code I would do:

<form jwcid="ListHistory@Form" listener="listener:saveFormHistory">
<span jwcid="@Hidden" value="ognl:items"/>
...
<tr jwcid="@For" source="ognl:items" value="ognl:item" element="tr">
 <td><span jwcid="@Insert" value="ognl:item.question.text">Question
Text</span></td>
 <td><input jwcid="@TextField" value="ognl:item.answerText"/></td>
</tr>

3. I dont pass parameters to the submit method, I think you dont need it.
4. With this, in the submit or in the form listener you should have access
to the updated collection.

Tell me if this works for you.

Gabriel H. Lozano M.


On 11/14/06, Srinivas Yermal <sy...@indygosoft.com> wrote:
>
> Thanks so much for the response. I will try out the
> DefaultPrimaryKeyConverter and InvokeListener options.
> My comments inline -
>
>
> > Anyway.. about your code: obviously, I can't tell you which is best.
> > But I think you don't have to pass your items as a parameter to the
> > listener method. Instead, the form fields (in this case, the
> > collection) will be bound to an instance variable in your page object.
> > Maybe you should drop that parameters attribute in the @Submit.
> > But you have to make sure the list is not null during rewind, and has
> > the right length, so you have to refill it before the rewind, and the
> > values will be overwritten during rewind.
>
>
> I tried not passing them as parameter initially, but that didnt work.
> Setting the parameter was something that I guessed might work, but it
> doesnot. I have also made sure that the items object is not null during
> rewind phase by removing the if condition in pageBeginRender, but all it
> does is gives me the same items without change to any values. On a side
> note, actually it might turn out be a overhead in large pages if I have to
> run the query again just for the rewind phase. Moreover, the collection is
> serialised and is available from the form, isnt it? Shouldnt it be
> deserialized?
>
> I have another observation to add. I have a method that returns the
> PropertySelectionModel for each item depending on the item. This is
> required
> for the dropdowns for each item. The dropdown values depend on the item.
> During the rewind phase this method gets called and I get proper objects
> with proper values. But when the submit listener gets called I still get a
> null collection or the old collection. Is there any other method like say
> renderComponent of the page that I have to implement?
>
> The listener method that is called will be the one referenced in the
> > @Submit component. In your case, the one referenced in the @Form is
> > never called, I think. So you might want to lose on of those two, to
> > avoid confusion.
>
>
> Actually, both the listeners get called. The form listener gets invoked
> last. I have both the listeners just as an experiment to see if I get a
> non-null proper collection in any listener at all.
> Thank you very much for the advice. Will continue trying and see where
> this
> goes. Its just that I am running out of time.
> Regards,
> Srini.
>
>

Re: ForBean issues

Posted by Srinivas Yermal <sy...@indygosoft.com>.
Thanks so much for the response. I will try out the
DefaultPrimaryKeyConverter and InvokeListener options.
My comments inline -


> Anyway.. about your code: obviously, I can't tell you which is best.
> But I think you don't have to pass your items as a parameter to the
> listener method. Instead, the form fields (in this case, the
> collection) will be bound to an instance variable in your page object.
> Maybe you should drop that parameters attribute in the @Submit.
> But you have to make sure the list is not null during rewind, and has
> the right length, so you have to refill it before the rewind, and the
> values will be overwritten during rewind.


I tried not passing them as parameter initially, but that didnt work.
Setting the parameter was something that I guessed might work, but it
doesnot. I have also made sure that the items object is not null during
rewind phase by removing the if condition in pageBeginRender, but all it
does is gives me the same items without change to any values. On a side
note, actually it might turn out be a overhead in large pages if I have to
run the query again just for the rewind phase. Moreover, the collection is
serialised and is available from the form, isnt it? Shouldnt it be
deserialized?

I have another observation to add. I have a method that returns the
PropertySelectionModel for each item depending on the item. This is required
for the dropdowns for each item. The dropdown values depend on the item.
During the rewind phase this method gets called and I get proper objects
with proper values. But when the submit listener gets called I still get a
null collection or the old collection. Is there any other method like say
renderComponent of the page that I have to implement?

The listener method that is called will be the one referenced in the
> @Submit component. In your case, the one referenced in the @Form is
> never called, I think. So you might want to lose on of those two, to
> avoid confusion.


Actually, both the listeners get called. The form listener gets invoked
last. I have both the listeners just as an experiment to see if I get a
non-null proper collection in any listener at all.
Thank you very much for the advice. Will continue trying and see where this
goes. Its just that I am running out of time.
Regards,
Srini.

RE: ForBean issues

Posted by Ma...@bmw.ch.
> 
> I also just used a list as source and the index attribute, it 
> seems Tapestry updates the items "in place" during rewind, 
> which is fine.
> But I don't understand how I can avoid the items being 
> serialized into hidden fields if I choose this approach.

try, setting the For-component's volatile parameter to "true".

> That's about all the advice I can give you.... let's just 
> hope someone who really knows let's us in on some 
> "collections in forms" insight.

Imo, using a custom SqueezeAdaptor works best (see the Wiki, tapernate
or honeycomb for how to implement/use one).

hth,
Marcus

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: ForBean issues

Posted by Lutz Hühnken <lh...@googlemail.com>.
I've been using Tapestry for a couple of month now and still haven't
understood how to work with collections in forms correctly.

What works well for me is the DefaultPrimaryKeyConverter. But it seems
such an overhead, I have to populate it in the beginPageRender, and
iterate it in the listener to update my original collection.

In the "Enjoy.." book by Kent Tong, he demonstrates using an
InvokeListener and calling a listener on every iteration, to process
the current item. Again, that seems odd to me, especially when you
want to delete items.

I also just used a list as source and the index attribute, it seems
Tapestry updates the items "in place" during rewind, which is fine.
But I don't understand how I can avoid the items being serialized into
hidden fields if I choose this approach.

Having said all that, I would like to add that I'm not new to
programing or Java. Quite the opposite, really, but I find Tapestry is
not very well documented in some areas (or the documentation is very
hard to find).

Anyway.. about your code: obviously, I can't tell you which is best.
But I think you don't have to pass your items as a parameter to the
listener method. Instead, the form fields (in this case, the
collection) will be bound to an instance variable in your page object.
Maybe you should drop that parameters attribute in the @Submit.
But you have to make sure the list is not null during rewind, and has
the right length, so you have to refill it before the rewind, and the
values will be overwritten during rewind.

The listener method that is called will be the one referenced in the
@Submit component. In your case, the one referenced in the @Form is
never called, I think. So you might want to lose on of those two, to
avoid confusion.

That's about all the advice I can give you.... let's just hope someone
who really knows let's us in on some "collections in forms" insight.

Lutz


On 11/13/06, Srinivas Yermal <sy...@indygosoft.com> wrote:
> Can some tapestry savvy guys look at this and help us out here. Would really
> appreciate the effort. This is quite a big blocker for me at present.
> Thanks,
> Srini.
>
> On 11/10/06, Srinivas Yermal <sy...@indygosoft.com> wrote:
> >
> > BTW We currently use version 4.0.2. and run it on tomcat. I would also
> > appreciate if somebody can point me to the "rewind" document if any. I have
> > heard so many stories about common newbie rewind mistakes but couldnt find
> > what they really are.
> > Thanks again.
> > Srini.
> >
> > On 11/10/06, Srinivas Yermal <sy...@indygosoft.com> wrote:
> > >
> > > Hi,
> > >
> > > I am a newbie trying to learn Tapestry. I did try to search through the
> > > archives for a solution, but couldnt find anything relavant. It would be
> > > great if someone could point me in the right direction.
> > >
> > > I have a page with a listing of a collection. I am using "For" component
> > > (ForBean) in the form. There are text fields against each item which has a
> > > value from the items in the collection. Now one can change the text value
> > > and hit the save button at the end of the form. The listener that is
> > > associated with the form gets called but I dont have a clue as to how I can
> > > obtain the changed values from the collection. I tried with both form
> > > listener and submit action listener. I always end up with a null or empty
> > > item collection.
> > >
> > > Some code snippet below -
> > >
> > > public abstract Collection getItems();
> > > public abstract void setItems(Collection items);
> > >
> > > ActionListener Method 1:
> > > public void saveHistory(IRequestCycle cycle, Object[] list) {
> > >         LOG.debug("saveHistory(cycle, array) invoked");
> > >         if (null == list) return;
> > >         for (Object o : list) {
> > >             Question mh = (Question)o;
> > >             LOG.debug(mh.getQuestionText() + " " + mh.getAnswerText());
> > >         }
> > > }
> > >
> > > ActionListener Method 2:
> > > public void saveHistory(IRequestCycle cycle) {
> > >         LOG.debug("saveHistory(cycle, array) invoked");
> > >         List list = cycle.getListenerParameters();
> > >         if (null == list) return;
> > >         for (Object o : list) {
> > >             Question mh = (Question)o;
> > >             LOG.debug(mh.getQuestionText() + " " + mh.getAnswerText());
> > >          }
> > > }
> > >
> > >
> > > FormListner Method:
> > > public void saveFormHistory(IRequestCycle cycle) {
> > >         LOG.debug("saveFormHistory(cyle) invoked");
> > >         Collection<Question> list = getItems();
> > >         if (null == list) return;
> > >         for (Question mh: list) {
> > >             LOG.debug(mh.getQuestionText () + " " + mh.getAnswerText());
> > >         }
> > > }
> > >
> > > The HTML file -
> > >
> > > <form jwcid="ListHistory@Form" listener="listener:saveFormHistory">
> > > ...
> > > <tr jwcid="@For" source="ognl:items" value="ognl:item" element="tr">
> > >
> > >
> > >   <td><span jwcid="@Insert" value="ognl:item.question.text">Question Text</span></td>
> > >   <td><input jwcid="@TextField" value="ognl:item.answerText
> > > "/></td>
> > >
> > > </tr>
> > > ...
> > > <input class="button" type="submit" value="Save" name="save" jwcid="@Submit" action="listener:saveHistory"
> > >
> > >  parameters="ognl:items"/>
> > >
> > > Please do let me know if something here is not right or if you have any
> > > further questions. Looking forward for some advice.
> > >
> > > Thanks in advance.
> > > Regards,
> > > Srini.
> > >
> >
> >
>
>
> --
> http://www.indygosoft.com
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: ForBean issues

Posted by Srinivas Yermal <sy...@indygosoft.com>.
Can some tapestry savvy guys look at this and help us out here. Would really
appreciate the effort. This is quite a big blocker for me at present.
Thanks,
Srini.

On 11/10/06, Srinivas Yermal <sy...@indygosoft.com> wrote:
>
> BTW We currently use version 4.0.2. and run it on tomcat. I would also
> appreciate if somebody can point me to the "rewind" document if any. I have
> heard so many stories about common newbie rewind mistakes but couldnt find
> what they really are.
> Thanks again.
> Srini.
>
> On 11/10/06, Srinivas Yermal <sy...@indygosoft.com> wrote:
> >
> > Hi,
> >
> > I am a newbie trying to learn Tapestry. I did try to search through the
> > archives for a solution, but couldnt find anything relavant. It would be
> > great if someone could point me in the right direction.
> >
> > I have a page with a listing of a collection. I am using "For" component
> > (ForBean) in the form. There are text fields against each item which has a
> > value from the items in the collection. Now one can change the text value
> > and hit the save button at the end of the form. The listener that is
> > associated with the form gets called but I dont have a clue as to how I can
> > obtain the changed values from the collection. I tried with both form
> > listener and submit action listener. I always end up with a null or empty
> > item collection.
> >
> > Some code snippet below -
> >
> > public abstract Collection getItems();
> > public abstract void setItems(Collection items);
> >
> > ActionListener Method 1:
> > public void saveHistory(IRequestCycle cycle, Object[] list) {
> >         LOG.debug("saveHistory(cycle, array) invoked");
> >         if (null == list) return;
> >         for (Object o : list) {
> >             Question mh = (Question)o;
> >             LOG.debug(mh.getQuestionText() + " " + mh.getAnswerText());
> >         }
> > }
> >
> > ActionListener Method 2:
> > public void saveHistory(IRequestCycle cycle) {
> >         LOG.debug("saveHistory(cycle, array) invoked");
> >         List list = cycle.getListenerParameters();
> >         if (null == list) return;
> >         for (Object o : list) {
> >             Question mh = (Question)o;
> >             LOG.debug(mh.getQuestionText() + " " + mh.getAnswerText());
> >          }
> > }
> >
> >
> > FormListner Method:
> > public void saveFormHistory(IRequestCycle cycle) {
> >         LOG.debug("saveFormHistory(cyle) invoked");
> >         Collection<Question> list = getItems();
> >         if (null == list) return;
> >         for (Question mh: list) {
> >             LOG.debug(mh.getQuestionText () + " " + mh.getAnswerText());
> >         }
> > }
> >
> > The HTML file -
> >
> > <form jwcid="ListHistory@Form" listener="listener:saveFormHistory">
> > ...
> > <tr jwcid="@For" source="ognl:items" value="ognl:item" element="tr">
> >
> >
> >   <td><span jwcid="@Insert" value="ognl:item.question.text">Question Text</span></td>
> >   <td><input jwcid="@TextField" value="ognl:item.answerText
> > "/></td>
> >
> > </tr>
> > ...
> > <input class="button" type="submit" value="Save" name="save" jwcid="@Submit" action="listener:saveHistory"
> >
> >  parameters="ognl:items"/>
> >
> > Please do let me know if something here is not right or if you have any
> > further questions. Looking forward for some advice.
> >
> > Thanks in advance.
> > Regards,
> > Srini.
> >
>
>


-- 
http://www.indygosoft.com

Re: ForBean issues

Posted by Srinivas Yermal <sy...@indygosoft.com>.
BTW We currently use version 4.0.2. and run it on tomcat. I would also
appreciate if somebody can point me to the "rewind" document if any. I have
heard so many stories about common newbie rewind mistakes but couldnt find
what they really are.
Thanks again.
Srini.

On 11/10/06, Srinivas Yermal <sy...@indygosoft.com> wrote:
>
> Hi,
>
> I am a newbie trying to learn Tapestry. I did try to search through the
> archives for a solution, but couldnt find anything relavant. It would be
> great if someone could point me in the right direction.
>
> I have a page with a listing of a collection. I am using "For" component
> (ForBean) in the form. There are text fields against each item which has a
> value from the items in the collection. Now one can change the text value
> and hit the save button at the end of the form. The listener that is
> associated with the form gets called but I dont have a clue as to how I can
> obtain the changed values from the collection. I tried with both form
> listener and submit action listener. I always end up with a null or empty
> item collection.
>
> Some code snippet below -
>
> public abstract Collection getItems();
> public abstract void setItems(Collection items);
>
> ActionListener Method 1:
> public void saveHistory(IRequestCycle cycle, Object[] list) {
>         LOG.debug("saveHistory(cycle, array) invoked");
>         if (null == list) return;
>         for (Object o : list) {
>             Question mh = (Question)o;
>             LOG.debug(mh.getQuestionText() + " " + mh.getAnswerText());
>         }
> }
>
> ActionListener Method 2:
> public void saveHistory(IRequestCycle cycle) {
>         LOG.debug("saveHistory(cycle, array) invoked");
>         List list = cycle.getListenerParameters();
>         if (null == list) return;
>         for (Object o : list) {
>             Question mh = (Question)o;
>             LOG.debug(mh.getQuestionText() + " " + mh.getAnswerText());
>          }
> }
>
>
> FormListner Method:
> public void saveFormHistory(IRequestCycle cycle) {
>         LOG.debug("saveFormHistory(cyle) invoked");
>         Collection<Question> list = getItems();
>         if (null == list) return;
>         for (Question mh: list) {
>             LOG.debug(mh.getQuestionText () + " " + mh.getAnswerText());
>         }
> }
>
> The HTML file -
>
> <form jwcid="ListHistory@Form" listener="listener:saveFormHistory">
> ...
> <tr jwcid="@For" source="ognl:items" value="ognl:item" element="tr">
>
>   <td><span jwcid="@Insert" value="ognl:item.question.text">Question Text</span></td>
>   <td><input jwcid="@TextField" value="ognl:item.answerText"/></td>
>
> </tr>
> ...
> <input class="button" type="submit" value="Save" name="save" jwcid="@Submit" action="listener:saveHistory"
>  parameters="ognl:items"/>
>
> Please do let me know if something here is not right or if you have any
> further questions. Looking forward for some advice.
>
> Thanks in advance.
> Regards,
> Srini.
>