That works! Thanks Robert! I had tried just setting match to false but it resulted in an odd NPE (I don't remember the exact details right now). But setting both volatile to true and match to false works like a charm.

Thanks again.
--Chris

On Jan 27, 2006, at 7:21 AM, Robert Zeigler wrote:

It seems to me that what ought to happen is that he needs to set
"volatile" to true, and "match" to false. I don't use "For"  yet since
I'm still using tapestry 3.0.3, but I do use Base:For (albeit a bit
older version which doesn't use the match parameter). In any event, it
seems that setting that to true should result in the correct behavior:
updating the objects in the order in which they are pulled from the
iterator (like Foreach does).  You wouldn't even have to store your
objects in the session. You could store the # of objects in a hidden
field at the top of the form and use the hidden field's listener method to restore the appropriately sized list which would then be used by For. Not that you have to use some care here since you have to guarantee that
you have the same # of objects in page render and page rewind (this is
what volatile=false + match=true solves). But in this case, that should be trivial. Give it a whirl and see what happens? I've done stuff like
this frequently with Foreach and with base:For. Give it a whirl. :)

Robert

Schulte Marcus wrote:
No, it would definitely not ;). But as long as he uses session- persistence
for his rsvpList it should work, right?


I don't think that would be consistently unique beyond the
objects life.

On 1/27/06, Schulte Marcus <[EMAIL PROTECTED]> wrote:

Hm, interesting problem. Now, your objects are equal but

they are not the

same. So, I guess, you could use a keyExpression parameter

referring to

the
objects' hashcode. In standard vm's, Object.hashCode()

returns different

values for different instances.

so, I'd try:

<div jwcid="@For" source="ognl:rsvpList" value="ognl:currentRsvp"
keyExpression="hashCode">

would that workf for you?

Marcus


-----Original Message-----
From: Chris Conrad [mailto:[EMAIL PROTECTED]
Sent: Thursday, January 26, 2006 9:49 PM
To: Tapestry users
Subject: Re: Non-intuitive behavior from the For component


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 <[EMAIL PROTECTED]> 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 <[EMAIL PROTECTED]> 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-
[EMAIL PROTECTED]
For additional commands, e-mail: tapestry-user-
[EMAIL PROTECTED]





-------------------------------------------------------------------- -

To unsubscribe, e-mail:

[EMAIL PROTECTED]

For additional commands, e-mail: tapestry-user-
[EMAIL PROTECTED]





-------------------------------------------------------------------- -

To unsubscribe, e-mail:

[EMAIL PROTECTED]

For additional commands, e-mail:

[EMAIL PROTECTED]


-------------------------------------------------------------------- -

To unsubscribe, e-mail: tapestry-user- [EMAIL PROTECTED]
For additional commands, e-mail:

[EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: tapestry-user- [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to