You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Chris Conrad <cc...@vasoftware.com> on 2006/01/26 20:53:44 UTC

Non-intuitive behavior from the For component

Hello everyone,

I'm working a tiny little RSVP for a friend.  While doing so I found,  
what seems to me at least, a very non-intuitive result from the For  
component.  Basically the behavior I want is:

1. The user navigates to the RSVP page and is provided a drop down  
box to select the number of people who will be attending the event.

2. The user is given a list of text entry boxes (to enter the name of  
the guest) and drop downs (to select the meal the guest wants).

1 was simple to accomplish though having to create a  
PropertySelectionModel is kinda a pain for something this simple.   
Where things got hairy is 2.  Basically the code flow is: in the  
listener for the form submit in #1, I grab the number of guests  
attending and set that on the meal selection page.  The meal  
selection page's pageBeginRender creates a List of x RSVP objects  
where x is the number of guests attending.  Then the meal selection  
page uses a For component to loop through the List of RSVP objects so  
that, in the first pass everything is blank and then when the guest  
submits, those RSVP objects in the List get filled in with the  
details the guest entered.

Now, what actually happened is the first RSVP object in the list is  
continually updated over and the others are never touched.  When  
tracing through the For components code, it appears to be trying to  
match the serialized object saved in the form against the ones in the  
List to "intelligently" pick which one to update.  But since all of  
the RSVP objects were the same to start with, and the For component  
doesn't update it's internal mapping after updating an object, it  
just ignored everything in the list after the first item.  Or, I  
guess more accurately, it continually matched the first item in the  
List and so it just repeatedly updated that one RSVP object. To work  
around this, I needed to set the RSVP's id in the pageBeginRender to  
a different value for each RSVP object and then reset them back to 0  
just before sending them to Hibernate to persist (if I don't reset  
them to 0, Hibernate things it's a detached object and ends up  
updating a row instead of adding a new row).

This work around seems very much like a hack to me.  Is there a way  
to make the For component do the right thing (i.e. actually iterate  
over the array when rewinding instead of assuming it knows what it's  
doing)? I did try playing with the match parameter and that  
completely breaks everything, none of the objects in the List get  
updated.  It seems that my use case isn't so terribly strange that it  
would be this difficult to accomplish in Tapestry.

Thanks,
--Chris

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


Re: Non-intuitive behavior from the For component

Posted by Jesse Kuhnert <jk...@gmail.com>.
P.S. Doing things with your current method also has the added bad side
effect of having all of your selection objects serialized into the form. It
may not hit you in this instance, but once your hibernate object graph grows
you'll quickly run into scenerios where you are having unexplainable
performance hits working with anything form related in loops..

The keyProvider parameter to the For component is ideal for working with
hibernate objects, as it will only serialize this value into the form
instead of the object, as well as use it to find your object again once you
submit the form to the server.

On 1/26/06, Jesse Kuhnert <jk...@gmail.com> wrote:
>
> Ahhh, that makes much more sense now.
>
> In this instance I would say that you might want to re-think the way that
> you are implementing equals() in your hibernate objects. Even the hibernate
> documentation puts in caveates about object identity (tried to lookup a
> reference but couldn't find it in time)...Basically, if you don't provide
> alternative equals() logic for cases where your objects aren't yet persisted
> you are going to run into this problem a ~lot~. For your case, I would do
> something similar (but not exactly ;) ) to this for my objects:
>
> public boolean equals(Object obj) {
>     if (!obj instanceof Foo)
>         return false;
>      Foo foo = (Foo)obj;
>      if (getId() > 0)
>           return getId() == foo.getId();
>      else if (getNumber() /* whatever your 1-10 values are stored in*/ ==
> foo.getNumber())
>        return true;
>       else
>           return false;
> }
>
> Expecting the For component to be able to handle object equality is a very
> high order. Perhaps it ~could~ try and do it based on index value, but even
> this would probably spurn 10 more mailing list emails for those scnerios
> where other people find ~that~ method non-intuitive ;)
>
> Well, that's my opinion on it anyways. (Your idea about the using the same
> ordering on index may have merit though, I'd have to crack open the For
> component and double check all of that to confirm, could very well be a
> great idea...Hard to say right now)
>
> jesse
>
> On 1/26/06, Chris Conrad <cc...@vasoftware.com> wrote:
> >
> > Hi Jesse,
> >
> > On Jan 26, 2006, at 11:58 AM, Jesse Kuhnert wrote:
> >
> > > Hmmm. .
> > >
> > > I do these sort of things a lot, esp. with hibernate. I've found
> > > the For
> > > component to incredibly useful, but maybe the identification of
> > > objects part
> > > could be made more clear?
> >
> > In this case, however, I'm using the For component before anything
> > Hibernate related happens.  I'm trying to create a list of empty RSVP
> > objects which the user fills in and then, after the user fills them
> > in, they are persisted.  So I can understand why the For component is
> > misbehaving for me; all the RSVP objects in the list are initially
> > identical.
> >
> > > I think the PropertySelectionModel problem could be solved if you
> > > used the
> > > "BeanPropertySelectionModel"  class found in
> > > http://tacos.sourceforge.netinstead. It makes turning a list of
> > > hibernate objects into the selection
> > > model a one-line argument.
> >
> > I'm sorry, I must not have been clear.  I'm not putting anything
> > Hibernate related at all in the PropertySelectionModel.  My drop down
> > box is just a list of numbers from 1 to 10.  The user uses that drop
> > down to select the number of guests attending.  Then, using the
> > number they gave, I create a list of RSVP objects.  That list of RSVP
> > objects (which should all be identical, they have no id because they
> > haven't been persisted, they have no name associated with them
> > because the user hasn't entered it yet, etc.) is then rendered using
> > the For component.  And then on rewind, the For component just
> > continually updates the first RSVP object in the list because it's
> > (from my understanding of the code) trying to intelligently choose
> > the correct RSVP object from the List to update.  But it's
> > impossible, in this use case, for it to make a choice that way
> > because all of the RSVP objects are legitimately the same at that
> > point.  That is why I went and added the hack to make sure all the
> > RSVP objects aren't identical, they all have a different id.  But the
> > id I assign isn't a valid id and I need to reset them back to 0
> > before I can persist them to Hibernate.  And that needing to set the
> > id and then reset it is a code smell which bothers me.
> >
> > I basically want the For component to work like a regular for loop
> > and just update the List one by one.  There is no possibility of the
> > list having changed or of updating the wrong item in the list.
> >
> > >
> > > Let me know if you try that and still find problems.
> >
> > Please let me know if I'm still not expressing myself clearly
> > regarding what the problem is.  And thanks for your extremely quick
> > response.
> >
> > --Chris
> >
> > >
> > > On 1/26/06, Chris Conrad <cc...@vasoftware.com> wrote:
> > >>
> > >> Hello everyone,
> > >>
> > >> I'm working a tiny little RSVP for a friend.  While doing so I found,
> >
> > >> what seems to me at least, a very non-intuitive result from the For
> > >> component.  Basically the behavior I want is:
> > >>
> > >> 1. The user navigates to the RSVP page and is provided a drop down
> > >> box to select the number of people who will be attending the event.
> > >>
> > >> 2. The user is given a list of text entry boxes (to enter the name of
> > >> the guest) and drop downs (to select the meal the guest wants).
> > >>
> > >> 1 was simple to accomplish though having to create a
> > >> PropertySelectionModel is kinda a pain for something this simple.
> > >> Where things got hairy is 2.  Basically the code flow is: in the
> > >> listener for the form submit in #1, I grab the number of guests
> > >> attending and set that on the meal selection page.  The meal
> > >> selection page's pageBeginRender creates a List of x RSVP objects
> > >> where x is the number of guests attending.  Then the meal selection
> > >> page uses a For component to loop through the List of RSVP objects so
> > >> that, in the first pass everything is blank and then when the guest
> > >> submits, those RSVP objects in the List get filled in with the
> > >> details the guest entered.
> > >>
> > >> Now, what actually happened is the first RSVP object in the list is
> > >> continually updated over and the others are never touched.  When
> > >> tracing through the For components code, it appears to be trying to
> > >> match the serialized object saved in the form against the ones in the
> > >> List to "intelligently" pick which one to update.  But since all of
> > >> the RSVP objects were the same to start with, and the For component
> > >> doesn't update it's internal mapping after updating an object, it
> > >> just ignored everything in the list after the first item.  Or, I
> > >> guess more accurately, it continually matched the first item in the
> > >> List and so it just repeatedly updated that one RSVP object. To work
> > >> around this, I needed to set the RSVP's id in the pageBeginRender to
> > >> a different value for each RSVP object and then reset them back to 0
> > >> just before sending them to Hibernate to persist (if I don't reset
> > >> them to 0, Hibernate things it's a detached object and ends up
> > >> updating a row instead of adding a new row).
> > >>
> > >> This work around seems very much like a hack to me.  Is there a way
> > >> to make the For component do the right thing (i.e. actually iterate
> > >> over the array when rewinding instead of assuming it knows what it's
> > >> doing)? I did try playing with the match parameter and that
> > >> completely breaks everything, none of the objects in the List get
> > >> updated.  It seems that my use case isn't so terribly strange that it
> > >> would be this difficult to accomplish in Tapestry.
> > >>
> > >> Thanks,
> > >> --Chris
> > >>
> > >> ---------------------------------------------------------------------
> >
> > >> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> > >> For additional commands, e-mail: tapestry-user-
> > >> help@jakarta.apache.org
> > >>
> > >>
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
> >
> >
>

Re: Non-intuitive behavior from the For component

Posted by Jesse Kuhnert <jk...@gmail.com>.
Ahhh, that makes much more sense now.

In this instance I would say that you might want to re-think the way that
you are implementing equals() in your hibernate objects. Even the hibernate
documentation puts in caveates about object identity (tried to lookup a
reference but couldn't find it in time)...Basically, if you don't provide
alternative equals() logic for cases where your objects aren't yet persisted
you are going to run into this problem a ~lot~. For your case, I would do
something similar (but not exactly ;) ) to this for my objects:

public boolean equals(Object obj) {
    if (!obj instanceof Foo)
        return false;
     Foo foo = (Foo)obj;
     if (getId() > 0)
          return getId() == foo.getId();
     else if (getNumber() /* whatever your 1-10 values are stored in*/ ==
foo.getNumber())
       return true;
      else
          return false;
}

Expecting the For component to be able to handle object equality is a very
high order. Perhaps it ~could~ try and do it based on index value, but even
this would probably spurn 10 more mailing list emails for those scnerios
where other people find ~that~ method non-intuitive ;)

Well, that's my opinion on it anyways. (Your idea about the using the same
ordering on index may have merit though, I'd have to crack open the For
component and double check all of that to confirm, could very well be a
great idea...Hard to say right now)

jesse

On 1/26/06, Chris Conrad <cc...@vasoftware.com> wrote:
>
> Hi Jesse,
>
> On Jan 26, 2006, at 11:58 AM, Jesse Kuhnert wrote:
>
> > Hmmm. .
> >
> > I do these sort of things a lot, esp. with hibernate. I've found
> > the For
> > component to incredibly useful, but maybe the identification of
> > objects part
> > could be made more clear?
>
> In this case, however, I'm using the For component before anything
> Hibernate related happens.  I'm trying to create a list of empty RSVP
> objects which the user fills in and then, after the user fills them
> in, they are persisted.  So I can understand why the For component is
> misbehaving for me; all the RSVP objects in the list are initially
> identical.
>
> > I think the PropertySelectionModel problem could be solved if you
> > used the
> > "BeanPropertySelectionModel"  class found in
> > http://tacos.sourceforge.netinstead. It makes turning a list of
> > hibernate objects into the selection
> > model a one-line argument.
>
> I'm sorry, I must not have been clear.  I'm not putting anything
> Hibernate related at all in the PropertySelectionModel.  My drop down
> box is just a list of numbers from 1 to 10.  The user uses that drop
> down to select the number of guests attending.  Then, using the
> number they gave, I create a list of RSVP objects.  That list of RSVP
> objects (which should all be identical, they have no id because they
> haven't been persisted, they have no name associated with them
> because the user hasn't entered it yet, etc.) is then rendered using
> the For component.  And then on rewind, the For component just
> continually updates the first RSVP object in the list because it's
> (from my understanding of the code) trying to intelligently choose
> the correct RSVP object from the List to update.  But it's
> impossible, in this use case, for it to make a choice that way
> because all of the RSVP objects are legitimately the same at that
> point.  That is why I went and added the hack to make sure all the
> RSVP objects aren't identical, they all have a different id.  But the
> id I assign isn't a valid id and I need to reset them back to 0
> before I can persist them to Hibernate.  And that needing to set the
> id and then reset it is a code smell which bothers me.
>
> I basically want the For component to work like a regular for loop
> and just update the List one by one.  There is no possibility of the
> list having changed or of updating the wrong item in the list.
>
> >
> > Let me know if you try that and still find problems.
>
> Please let me know if I'm still not expressing myself clearly
> regarding what the problem is.  And thanks for your extremely quick
> response.
>
> --Chris
>
> >
> > On 1/26/06, Chris Conrad <cc...@vasoftware.com> wrote:
> >>
> >> Hello everyone,
> >>
> >> I'm working a tiny little RSVP for a friend.  While doing so I found,
> >> what seems to me at least, a very non-intuitive result from the For
> >> component.  Basically the behavior I want is:
> >>
> >> 1. The user navigates to the RSVP page and is provided a drop down
> >> box to select the number of people who will be attending the event.
> >>
> >> 2. The user is given a list of text entry boxes (to enter the name of
> >> the guest) and drop downs (to select the meal the guest wants).
> >>
> >> 1 was simple to accomplish though having to create a
> >> PropertySelectionModel is kinda a pain for something this simple.
> >> Where things got hairy is 2.  Basically the code flow is: in the
> >> listener for the form submit in #1, I grab the number of guests
> >> attending and set that on the meal selection page.  The meal
> >> selection page's pageBeginRender creates a List of x RSVP objects
> >> where x is the number of guests attending.  Then the meal selection
> >> page uses a For component to loop through the List of RSVP objects so
> >> that, in the first pass everything is blank and then when the guest
> >> submits, those RSVP objects in the List get filled in with the
> >> details the guest entered.
> >>
> >> Now, what actually happened is the first RSVP object in the list is
> >> continually updated over and the others are never touched.  When
> >> tracing through the For components code, it appears to be trying to
> >> match the serialized object saved in the form against the ones in the
> >> List to "intelligently" pick which one to update.  But since all of
> >> the RSVP objects were the same to start with, and the For component
> >> doesn't update it's internal mapping after updating an object, it
> >> just ignored everything in the list after the first item.  Or, I
> >> guess more accurately, it continually matched the first item in the
> >> List and so it just repeatedly updated that one RSVP object. To work
> >> around this, I needed to set the RSVP's id in the pageBeginRender to
> >> a different value for each RSVP object and then reset them back to 0
> >> just before sending them to Hibernate to persist (if I don't reset
> >> them to 0, Hibernate things it's a detached object and ends up
> >> updating a row instead of adding a new row).
> >>
> >> This work around seems very much like a hack to me.  Is there a way
> >> to make the For component do the right thing (i.e. actually iterate
> >> over the array when rewinding instead of assuming it knows what it's
> >> doing)? I did try playing with the match parameter and that
> >> completely breaks everything, none of the objects in the List get
> >> updated.  It seems that my use case isn't so terribly strange that it
> >> would be this difficult to accomplish in Tapestry.
> >>
> >> Thanks,
> >> --Chris
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> >> For additional commands, e-mail: tapestry-user-
> >> help@jakarta.apache.org
> >>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>

Re: Non-intuitive behavior from the For component

Posted by Chris Conrad <cc...@vasoftware.com>.
Hi Jesse,

On Jan 26, 2006, at 11:58 AM, Jesse Kuhnert wrote:

> Hmmm. .
>
> I do these sort of things a lot, esp. with hibernate. I've found  
> the For
> component to incredibly useful, but maybe the identification of  
> objects part
> could be made more clear?

In this case, however, I'm using the For component before anything  
Hibernate related happens.  I'm trying to create a list of empty RSVP  
objects which the user fills in and then, after the user fills them  
in, they are persisted.  So I can understand why the For component is  
misbehaving for me; all the RSVP objects in the list are initially  
identical.

> I think the PropertySelectionModel problem could be solved if you  
> used the
> "BeanPropertySelectionModel"  class found in
> http://tacos.sourceforge.netinstead. It makes turning a list of
> hibernate objects into the selection
> model a one-line argument.

I'm sorry, I must not have been clear.  I'm not putting anything  
Hibernate related at all in the PropertySelectionModel.  My drop down  
box is just a list of numbers from 1 to 10.  The user uses that drop  
down to select the number of guests attending.  Then, using the  
number they gave, I create a list of RSVP objects.  That list of RSVP  
objects (which should all be identical, they have no id because they  
haven't been persisted, they have no name associated with them  
because the user hasn't entered it yet, etc.) is then rendered using  
the For component.  And then on rewind, the For component just  
continually updates the first RSVP object in the list because it's  
(from my understanding of the code) trying to intelligently choose  
the correct RSVP object from the List to update.  But it's  
impossible, in this use case, for it to make a choice that way  
because all of the RSVP objects are legitimately the same at that  
point.  That is why I went and added the hack to make sure all the  
RSVP objects aren't identical, they all have a different id.  But the  
id I assign isn't a valid id and I need to reset them back to 0  
before I can persist them to Hibernate.  And that needing to set the  
id and then reset it is a code smell which bothers me.

I basically want the For component to work like a regular for loop  
and just update the List one by one.  There is no possibility of the  
list having changed or of updating the wrong item in the list.

>
> Let me know if you try that and still find problems.

Please let me know if I'm still not expressing myself clearly  
regarding what the problem is.  And thanks for your extremely quick  
response.

--Chris

>
> On 1/26/06, Chris Conrad <cc...@vasoftware.com> wrote:
>>
>> Hello everyone,
>>
>> I'm working a tiny little RSVP for a friend.  While doing so I found,
>> what seems to me at least, a very non-intuitive result from the For
>> component.  Basically the behavior I want is:
>>
>> 1. The user navigates to the RSVP page and is provided a drop down
>> box to select the number of people who will be attending the event.
>>
>> 2. The user is given a list of text entry boxes (to enter the name of
>> the guest) and drop downs (to select the meal the guest wants).
>>
>> 1 was simple to accomplish though having to create a
>> PropertySelectionModel is kinda a pain for something this simple.
>> Where things got hairy is 2.  Basically the code flow is: in the
>> listener for the form submit in #1, I grab the number of guests
>> attending and set that on the meal selection page.  The meal
>> selection page's pageBeginRender creates a List of x RSVP objects
>> where x is the number of guests attending.  Then the meal selection
>> page uses a For component to loop through the List of RSVP objects so
>> that, in the first pass everything is blank and then when the guest
>> submits, those RSVP objects in the List get filled in with the
>> details the guest entered.
>>
>> Now, what actually happened is the first RSVP object in the list is
>> continually updated over and the others are never touched.  When
>> tracing through the For components code, it appears to be trying to
>> match the serialized object saved in the form against the ones in the
>> List to "intelligently" pick which one to update.  But since all of
>> the RSVP objects were the same to start with, and the For component
>> doesn't update it's internal mapping after updating an object, it
>> just ignored everything in the list after the first item.  Or, I
>> guess more accurately, it continually matched the first item in the
>> List and so it just repeatedly updated that one RSVP object. To work
>> around this, I needed to set the RSVP's id in the pageBeginRender to
>> a different value for each RSVP object and then reset them back to 0
>> just before sending them to Hibernate to persist (if I don't reset
>> them to 0, Hibernate things it's a detached object and ends up
>> updating a row instead of adding a new row).
>>
>> This work around seems very much like a hack to me.  Is there a way
>> to make the For component do the right thing (i.e. actually iterate
>> over the array when rewinding instead of assuming it knows what it's
>> doing)? I did try playing with the match parameter and that
>> completely breaks everything, none of the objects in the List get
>> updated.  It seems that my use case isn't so terribly strange that it
>> would be this difficult to accomplish in Tapestry.
>>
>> Thanks,
>> --Chris
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: tapestry-user- 
>> help@jakarta.apache.org
>>
>>


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


Re: Non-intuitive behavior from the For component

Posted by Chris Conrad <cc...@vasoftware.com>.
I think the problem here (and this is also in regards to using the  
keyProvider parameter and equals method) is I'm dealing with a list  
of objects which are 100% legitimately equal to each other.  And  
that's really what I want.  I want the For component to take a list  
of equal objects to render the page and then, during the rewind,  
update that list of objects according to their index in the list.   
When I start I have no identifying information about the list of  
objects, all I know is that I need x number of them.

To try and explain in a different way ... if you look at the Form  
section of the Quick Start guide you can see the standard pattern for  
having a user fill in a form to create a new object.  In the Quick  
Start guide it's creating a new ProjectRelease.  So, as in the  
example, in your pageBeginRender you instantiate a blank  
ProjectRelease and when the form is submitted, the fields of the  
ProjectRelease are updated according to the values in the form.  I  
want to do the same thing but instead of creating a single  
ProjectRelease, I want to create a list of ProjectReleases.

Does that help any?

--Chris

On Jan 26, 2006, at 12:36 PM, Jesse Kuhnert wrote:

> Hmmm....But that only causes more confusion I'm afraid :(
>
> Ohhhhhh....I think what you are doing sort of sounds right, but you  
> still
> can't expect the For component to be able to know the difference  
> between all
> of your objects if the equals() method on them doesn't enforce some  
> sort of
> uniqueness.
>
> Have you tried playing with the "match" parameter to For? I've  
> normally used
> the "ListEdit" component for things like this in the past. Would  
> love to
> hear if "match" or some of the other parameters solve your problem.
>
> On 1/26/06, Chris Conrad <cc...@vasoftware.com> wrote:
>>
>> Sorry to reply twice, but I thought some code snippets might make
>> things clearer.  Here is what I do in my pageBeginRender:
>>
>>              rsvpList = new ArrayList<Rsvp>(numberAttending);
>>
>>              for (int i = 0; i < numberAttending; i++) {
>>                  Rsvp rsvp = new Rsvp();
>>                  rsvp.setId(i);
>>                  rsvp.setAttending(true);
>>
>>                  rsvpList.add(i, rsvp);
>>              }
>>
>>              setRsvpList(rsvpList);
>>
>> My listener method looks like:
>>
>>          // Reset the ids to 0
>>          List<Rsvp> rsvpList = getRsvpList();
>>          for (Rsvp rsvp : rsvpList) {
>>              rsvp.setId(0);
>>          }
>>
>>          getRsvpData().setRsvpList(rsvpList);
>>
>> And then in my HTML template I use it like this:
>>
>>          <div jwcid="@For" source="ognl:rsvpList"
>> value="ognl:currentRsvp">
>>              <div jwcid="@Any" element="div"  
>> class="ognl:evenOdd.next">
>>                  <p class="floatLeft">
>>                      <label jwcid="@FieldLabel"
>> field="component:guestName">Guest's Name</label>
>>                      <input jwcid="guestName" size="30"/>
>>                  </p>
>>
>>                  <p class="floatLeft">
>>                      <label jwcid="@FieldLabel"
>> field="component:meal">Meal</label>
>>                      <input jwcid="meal"/>
>>                  </p>
>>                  <br class="clear"/>
>>              </div>
>>
>> The bit that bothers me is that in my pageBeginRender I need to do  
>> this:
>>                  rsvp.setId(i);
>>
>> and in my listener I need to do this:
>>
>>          // Reset the ids to 0
>>          List<Rsvp> rsvpList = getRsvpList();
>>          for (Rsvp rsvp : rsvpList) {
>>              rsvp.setId(0);
>>          }
>>
>> I need to do that exclusively so that the For component can update
>> the List correctly.
>>
>> Hopefully that makes things a little clearer.
>>
>> --Chris
>>
>> On Jan 26, 2006, at 11:58 AM, Jesse Kuhnert wrote:
>>
>>> Hmmm. .
>>>
>>> I do these sort of things a lot, esp. with hibernate. I've found
>>> the For
>>> component to incredibly useful, but maybe the identification of
>>> objects part
>>> could be made more clear?
>>>
>>> I think the PropertySelectionModel problem could be solved if you
>>> used the
>>> "BeanPropertySelectionModel"  class found in
>>> http://tacos.sourceforge.netinstead. It makes turning a list of
>>> hibernate objects into the selection
>>> model a one-line argument.
>>>
>>> Let me know if you try that and still find problems.
>>>
>>> On 1/26/06, Chris Conrad <cc...@vasoftware.com> wrote:
>>>>
>>>> Hello everyone,
>>>>
>>>> I'm working a tiny little RSVP for a friend.  While doing so I  
>>>> found,
>>>> what seems to me at least, a very non-intuitive result from the For
>>>> component.  Basically the behavior I want is:
>>>>
>>>> 1. The user navigates to the RSVP page and is provided a drop down
>>>> box to select the number of people who will be attending the event.
>>>>
>>>> 2. The user is given a list of text entry boxes (to enter the  
>>>> name of
>>>> the guest) and drop downs (to select the meal the guest wants).
>>>>
>>>> 1 was simple to accomplish though having to create a
>>>> PropertySelectionModel is kinda a pain for something this simple.
>>>> Where things got hairy is 2.  Basically the code flow is: in the
>>>> listener for the form submit in #1, I grab the number of guests
>>>> attending and set that on the meal selection page.  The meal
>>>> selection page's pageBeginRender creates a List of x RSVP objects
>>>> where x is the number of guests attending.  Then the meal selection
>>>> page uses a For component to loop through the List of RSVP  
>>>> objects so
>>>> that, in the first pass everything is blank and then when the guest
>>>> submits, those RSVP objects in the List get filled in with the
>>>> details the guest entered.
>>>>
>>>> Now, what actually happened is the first RSVP object in the list is
>>>> continually updated over and the others are never touched.  When
>>>> tracing through the For components code, it appears to be trying to
>>>> match the serialized object saved in the form against the ones  
>>>> in the
>>>> List to "intelligently" pick which one to update.  But since all of
>>>> the RSVP objects were the same to start with, and the For component
>>>> doesn't update it's internal mapping after updating an object, it
>>>> just ignored everything in the list after the first item.  Or, I
>>>> guess more accurately, it continually matched the first item in the
>>>> List and so it just repeatedly updated that one RSVP object. To  
>>>> work
>>>> around this, I needed to set the RSVP's id in the  
>>>> pageBeginRender to
>>>> a different value for each RSVP object and then reset them back  
>>>> to 0
>>>> just before sending them to Hibernate to persist (if I don't reset
>>>> them to 0, Hibernate things it's a detached object and ends up
>>>> updating a row instead of adding a new row).
>>>>
>>>> This work around seems very much like a hack to me.  Is there a way
>>>> to make the For component do the right thing (i.e. actually iterate
>>>> over the array when rewinding instead of assuming it knows what  
>>>> it's
>>>> doing)? I did try playing with the match parameter and that
>>>> completely breaks everything, none of the objects in the List get
>>>> updated.  It seems that my use case isn't so terribly strange  
>>>> that it
>>>> would be this difficult to accomplish in Tapestry.
>>>>
>>>> Thanks,
>>>> --Chris
>>>>
>>>> ------------------------------------------------------------------- 
>>>> --
>>>> To unsubscribe, e-mail: tapestry-user- 
>>>> unsubscribe@jakarta.apache.org
>>>> For additional commands, e-mail: tapestry-user-
>>>> help@jakarta.apache.org
>>>>
>>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: tapestry-user- 
>> help@jakarta.apache.org
>>
>>


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


Re: Non-intuitive behavior from the For component

Posted by Jesse Kuhnert <jk...@gmail.com>.
Hmmm....But that only causes more confusion I'm afraid :(

Ohhhhhh....I think what you are doing sort of sounds right, but you still
can't expect the For component to be able to know the difference between all
of your objects if the equals() method on them doesn't enforce some sort of
uniqueness.

Have you tried playing with the "match" parameter to For? I've normally used
the "ListEdit" component for things like this in the past. Would love to
hear if "match" or some of the other parameters solve your problem.

On 1/26/06, Chris Conrad <cc...@vasoftware.com> wrote:
>
> Sorry to reply twice, but I thought some code snippets might make
> things clearer.  Here is what I do in my pageBeginRender:
>
>              rsvpList = new ArrayList<Rsvp>(numberAttending);
>
>              for (int i = 0; i < numberAttending; i++) {
>                  Rsvp rsvp = new Rsvp();
>                  rsvp.setId(i);
>                  rsvp.setAttending(true);
>
>                  rsvpList.add(i, rsvp);
>              }
>
>              setRsvpList(rsvpList);
>
> My listener method looks like:
>
>          // Reset the ids to 0
>          List<Rsvp> rsvpList = getRsvpList();
>          for (Rsvp rsvp : rsvpList) {
>              rsvp.setId(0);
>          }
>
>          getRsvpData().setRsvpList(rsvpList);
>
> And then in my HTML template I use it like this:
>
>          <div jwcid="@For" source="ognl:rsvpList"
> value="ognl:currentRsvp">
>              <div jwcid="@Any" element="div" class="ognl:evenOdd.next">
>                  <p class="floatLeft">
>                      <label jwcid="@FieldLabel"
> field="component:guestName">Guest's Name</label>
>                      <input jwcid="guestName" size="30"/>
>                  </p>
>
>                  <p class="floatLeft">
>                      <label jwcid="@FieldLabel"
> field="component:meal">Meal</label>
>                      <input jwcid="meal"/>
>                  </p>
>                  <br class="clear"/>
>              </div>
>
> The bit that bothers me is that in my pageBeginRender I need to do this:
>                  rsvp.setId(i);
>
> and in my listener I need to do this:
>
>          // Reset the ids to 0
>          List<Rsvp> rsvpList = getRsvpList();
>          for (Rsvp rsvp : rsvpList) {
>              rsvp.setId(0);
>          }
>
> I need to do that exclusively so that the For component can update
> the List correctly.
>
> Hopefully that makes things a little clearer.
>
> --Chris
>
> On Jan 26, 2006, at 11:58 AM, Jesse Kuhnert wrote:
>
> > Hmmm. .
> >
> > I do these sort of things a lot, esp. with hibernate. I've found
> > the For
> > component to incredibly useful, but maybe the identification of
> > objects part
> > could be made more clear?
> >
> > I think the PropertySelectionModel problem could be solved if you
> > used the
> > "BeanPropertySelectionModel"  class found in
> > http://tacos.sourceforge.netinstead. It makes turning a list of
> > hibernate objects into the selection
> > model a one-line argument.
> >
> > Let me know if you try that and still find problems.
> >
> > On 1/26/06, Chris Conrad <cc...@vasoftware.com> wrote:
> >>
> >> Hello everyone,
> >>
> >> I'm working a tiny little RSVP for a friend.  While doing so I found,
> >> what seems to me at least, a very non-intuitive result from the For
> >> component.  Basically the behavior I want is:
> >>
> >> 1. The user navigates to the RSVP page and is provided a drop down
> >> box to select the number of people who will be attending the event.
> >>
> >> 2. The user is given a list of text entry boxes (to enter the name of
> >> the guest) and drop downs (to select the meal the guest wants).
> >>
> >> 1 was simple to accomplish though having to create a
> >> PropertySelectionModel is kinda a pain for something this simple.
> >> Where things got hairy is 2.  Basically the code flow is: in the
> >> listener for the form submit in #1, I grab the number of guests
> >> attending and set that on the meal selection page.  The meal
> >> selection page's pageBeginRender creates a List of x RSVP objects
> >> where x is the number of guests attending.  Then the meal selection
> >> page uses a For component to loop through the List of RSVP objects so
> >> that, in the first pass everything is blank and then when the guest
> >> submits, those RSVP objects in the List get filled in with the
> >> details the guest entered.
> >>
> >> Now, what actually happened is the first RSVP object in the list is
> >> continually updated over and the others are never touched.  When
> >> tracing through the For components code, it appears to be trying to
> >> match the serialized object saved in the form against the ones in the
> >> List to "intelligently" pick which one to update.  But since all of
> >> the RSVP objects were the same to start with, and the For component
> >> doesn't update it's internal mapping after updating an object, it
> >> just ignored everything in the list after the first item.  Or, I
> >> guess more accurately, it continually matched the first item in the
> >> List and so it just repeatedly updated that one RSVP object. To work
> >> around this, I needed to set the RSVP's id in the pageBeginRender to
> >> a different value for each RSVP object and then reset them back to 0
> >> just before sending them to Hibernate to persist (if I don't reset
> >> them to 0, Hibernate things it's a detached object and ends up
> >> updating a row instead of adding a new row).
> >>
> >> This work around seems very much like a hack to me.  Is there a way
> >> to make the For component do the right thing (i.e. actually iterate
> >> over the array when rewinding instead of assuming it knows what it's
> >> doing)? I did try playing with the match parameter and that
> >> completely breaks everything, none of the objects in the List get
> >> updated.  It seems that my use case isn't so terribly strange that it
> >> would be this difficult to accomplish in Tapestry.
> >>
> >> Thanks,
> >> --Chris
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> >> For additional commands, e-mail: tapestry-user-
> >> help@jakarta.apache.org
> >>
> >>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>

Re: Non-intuitive behavior from the For component

Posted by Chris Conrad <cc...@vasoftware.com>.
Sorry to reply twice, but I thought some code snippets might make  
things clearer.  Here is what I do in my pageBeginRender:

             rsvpList = new ArrayList<Rsvp>(numberAttending);

             for (int i = 0; i < numberAttending; i++) {
                 Rsvp rsvp = new Rsvp();
                 rsvp.setId(i);
                 rsvp.setAttending(true);

                 rsvpList.add(i, rsvp);
             }

             setRsvpList(rsvpList);

My listener method looks like:

         // Reset the ids to 0
         List<Rsvp> rsvpList = getRsvpList();
         for (Rsvp rsvp : rsvpList) {
             rsvp.setId(0);
         }

         getRsvpData().setRsvpList(rsvpList);

And then in my HTML template I use it like this:

         <div jwcid="@For" source="ognl:rsvpList"  
value="ognl:currentRsvp">
             <div jwcid="@Any" element="div" class="ognl:evenOdd.next">
                 <p class="floatLeft">
                     <label jwcid="@FieldLabel"  
field="component:guestName">Guest's Name</label>
                     <input jwcid="guestName" size="30"/>
                 </p>

                 <p class="floatLeft">
                     <label jwcid="@FieldLabel"  
field="component:meal">Meal</label>
                     <input jwcid="meal"/>
                 </p>
                 <br class="clear"/>
             </div>

The bit that bothers me is that in my pageBeginRender I need to do this:
                 rsvp.setId(i);

and in my listener I need to do this:

         // Reset the ids to 0
         List<Rsvp> rsvpList = getRsvpList();
         for (Rsvp rsvp : rsvpList) {
             rsvp.setId(0);
         }

I need to do that exclusively so that the For component can update  
the List correctly.

Hopefully that makes things a little clearer.

--Chris

On Jan 26, 2006, at 11:58 AM, Jesse Kuhnert wrote:

> Hmmm. .
>
> I do these sort of things a lot, esp. with hibernate. I've found  
> the For
> component to incredibly useful, but maybe the identification of  
> objects part
> could be made more clear?
>
> I think the PropertySelectionModel problem could be solved if you  
> used the
> "BeanPropertySelectionModel"  class found in
> http://tacos.sourceforge.netinstead. It makes turning a list of
> hibernate objects into the selection
> model a one-line argument.
>
> Let me know if you try that and still find problems.
>
> On 1/26/06, Chris Conrad <cc...@vasoftware.com> wrote:
>>
>> Hello everyone,
>>
>> I'm working a tiny little RSVP for a friend.  While doing so I found,
>> what seems to me at least, a very non-intuitive result from the For
>> component.  Basically the behavior I want is:
>>
>> 1. The user navigates to the RSVP page and is provided a drop down
>> box to select the number of people who will be attending the event.
>>
>> 2. The user is given a list of text entry boxes (to enter the name of
>> the guest) and drop downs (to select the meal the guest wants).
>>
>> 1 was simple to accomplish though having to create a
>> PropertySelectionModel is kinda a pain for something this simple.
>> Where things got hairy is 2.  Basically the code flow is: in the
>> listener for the form submit in #1, I grab the number of guests
>> attending and set that on the meal selection page.  The meal
>> selection page's pageBeginRender creates a List of x RSVP objects
>> where x is the number of guests attending.  Then the meal selection
>> page uses a For component to loop through the List of RSVP objects so
>> that, in the first pass everything is blank and then when the guest
>> submits, those RSVP objects in the List get filled in with the
>> details the guest entered.
>>
>> Now, what actually happened is the first RSVP object in the list is
>> continually updated over and the others are never touched.  When
>> tracing through the For components code, it appears to be trying to
>> match the serialized object saved in the form against the ones in the
>> List to "intelligently" pick which one to update.  But since all of
>> the RSVP objects were the same to start with, and the For component
>> doesn't update it's internal mapping after updating an object, it
>> just ignored everything in the list after the first item.  Or, I
>> guess more accurately, it continually matched the first item in the
>> List and so it just repeatedly updated that one RSVP object. To work
>> around this, I needed to set the RSVP's id in the pageBeginRender to
>> a different value for each RSVP object and then reset them back to 0
>> just before sending them to Hibernate to persist (if I don't reset
>> them to 0, Hibernate things it's a detached object and ends up
>> updating a row instead of adding a new row).
>>
>> This work around seems very much like a hack to me.  Is there a way
>> to make the For component do the right thing (i.e. actually iterate
>> over the array when rewinding instead of assuming it knows what it's
>> doing)? I did try playing with the match parameter and that
>> completely breaks everything, none of the objects in the List get
>> updated.  It seems that my use case isn't so terribly strange that it
>> would be this difficult to accomplish in Tapestry.
>>
>> Thanks,
>> --Chris
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: tapestry-user- 
>> help@jakarta.apache.org
>>
>>


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


Re: Non-intuitive behavior from the For component

Posted by Jesse Kuhnert <jk...@gmail.com>.
Hmmm. .

I do these sort of things a lot, esp. with hibernate. I've found the For
component to incredibly useful, but maybe the identification of objects part
could be made more clear?

I think the PropertySelectionModel problem could be solved if you used the
"BeanPropertySelectionModel"  class found in
http://tacos.sourceforge.netinstead. It makes turning a list of
hibernate objects into the selection
model a one-line argument.

Let me know if you try that and still find problems.

On 1/26/06, Chris Conrad <cc...@vasoftware.com> wrote:
>
> Hello everyone,
>
> I'm working a tiny little RSVP for a friend.  While doing so I found,
> what seems to me at least, a very non-intuitive result from the For
> component.  Basically the behavior I want is:
>
> 1. The user navigates to the RSVP page and is provided a drop down
> box to select the number of people who will be attending the event.
>
> 2. The user is given a list of text entry boxes (to enter the name of
> the guest) and drop downs (to select the meal the guest wants).
>
> 1 was simple to accomplish though having to create a
> PropertySelectionModel is kinda a pain for something this simple.
> Where things got hairy is 2.  Basically the code flow is: in the
> listener for the form submit in #1, I grab the number of guests
> attending and set that on the meal selection page.  The meal
> selection page's pageBeginRender creates a List of x RSVP objects
> where x is the number of guests attending.  Then the meal selection
> page uses a For component to loop through the List of RSVP objects so
> that, in the first pass everything is blank and then when the guest
> submits, those RSVP objects in the List get filled in with the
> details the guest entered.
>
> Now, what actually happened is the first RSVP object in the list is
> continually updated over and the others are never touched.  When
> tracing through the For components code, it appears to be trying to
> match the serialized object saved in the form against the ones in the
> List to "intelligently" pick which one to update.  But since all of
> the RSVP objects were the same to start with, and the For component
> doesn't update it's internal mapping after updating an object, it
> just ignored everything in the list after the first item.  Or, I
> guess more accurately, it continually matched the first item in the
> List and so it just repeatedly updated that one RSVP object. To work
> around this, I needed to set the RSVP's id in the pageBeginRender to
> a different value for each RSVP object and then reset them back to 0
> just before sending them to Hibernate to persist (if I don't reset
> them to 0, Hibernate things it's a detached object and ends up
> updating a row instead of adding a new row).
>
> This work around seems very much like a hack to me.  Is there a way
> to make the For component do the right thing (i.e. actually iterate
> over the array when rewinding instead of assuming it knows what it's
> doing)? I did try playing with the match parameter and that
> completely breaks everything, none of the objects in the List get
> updated.  It seems that my use case isn't so terribly strange that it
> would be this difficult to accomplish in Tapestry.
>
> Thanks,
> --Chris
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tapestry-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: tapestry-user-help@jakarta.apache.org
>
>