Feel free to ignore my epic -- I got option B working after I changed over to using a ListEditMap with the ListEdit component. After a couple hours sleep, I now realize that option A isn't possible without a form-submission.
It's messy, though -- it'd be nice if I could keep the ValidField validators from running when I use the "Add Shift" submit button and let them go when I use the "Create Profile" submit button. Is that possible? Otherwise I'll just do all the validation manually from the Form's listener. Jim -----Original Message----- From: Jim Steinberger [mailto:[EMAIL PROTECTED] Sent: Saturday, August 27, 2005 10:12 AM To: Tapestry users Subject: RE: Forms with dynamic/arbitrary number of parameters (I'm sorry -- I'm using Tapestry 3.0.3) Jim Steinberger [EMAIL PROTECTED] -----Original Message----- From: Jim Steinberger [mailto:[EMAIL PROTECTED] Sent: Saturday, August 27, 2005 9:52 AM To: Tapestry users Subject: Forms with dynamic/arbitrary number of parameters Heya, I have a form for submitting a person's work-profile, including the shifts s/he's willing to work. S/he can have 0 shifts, or many shifts. The way I envision it, the clean form will have only an "Add Shift" button, and clicking that button will result in a "Shift 1: [ select box ] [ text box ] (... etc.)" line appearing along with a "Remove This Shift" button, and that same "Add Shift" on its own line. Despite my very meager Tapestry experience, I'm trying to be fancy: <div jwcid="@tacos:Part" id="shifts"> <div jwcid="@ListEdit" source="ognl:shifts" value="ognl:shift" index="ognl:shiftIndex"> Shift: <span jwcid="@Insert" value="ognl:shiftIndex + 1" /> <select jwcid="@PropertySelection" value="ognl:shift.dayOfWeek" model="ognl:@[EMAIL PROTECTED]" /> <br /> </div> <br /> <a jwcid="@tacos:PartialLink" refreshParts="shifts" listener="ognl:listeners.addShift" parameters="ognl:profile">Add Shift</a> <br /> </div> ["ognl:shift" refers to a transient Shift property-object, which has a single property "dayOfWeek" right now. "ognl:shifts" refers to a persistent ArrayList property -- I made it persistent so the Shifts added so far would survive the multiple requests, given that using the PartialLink component means there's no form-submission] i.e. instead of redrawing the whole page, I'm trying to have the "Add Shift" link only redraw that part of the page, using the Tacos Part/PartLink components. So far, it's working perfectly as far as demo-purposes go, with every click of "Add Shift" resulting in that section of page getting another Shift-line complete with working select-box, without redrawing the whole page. If I set any select-box values before I "Add Shift", though, those values are lost (since there's no form-submission) when that area is redrawn. So, now I want: A) Select boxes of Shifts 1 - (n-1) to retain their value when I add Shift n And I need: B) The select-boxes' values to propogate to the "dayOfWeek" properties of the "shifts" ArrayList elements so I can properly persist them along with the rest of the profile when the entire form is submitted. Is this set of behaviors elegantly possible using Tapestry? I do understand that "A" could very well not be (elegantly) possible because it requires a form-submission to make those selected values visible to the Page, and thus I'd need to submit the whole form and redraw the whole page. (If I have to go that way, would I take out the Tacos components and change "Add Shift" to a Submit component, and have that component's listener throw a PageRedirectException at the end so the Form's listener won't be called?) Alternatively, I would be happy with only "B", in which the user would add a bunch of Shifts but each select box would have default values (in the example of what I have so far: "Monday"), and the user wouldn't bother setting them until s/he's ready to submit the whole page. I'm trying to do that now, but either I'm doing something wrong or dynamically generated form inputs aren't rewound, because when the form rewinds, in the listener I print out the "dayOfWeek" property of each Shift in the "shifts" ArrayList, and they are all null. This log-snippet might help clarify (btw, ProfileNewPage inherits from ProfileCrudPage which inherits from ProtectedPage): ... -- Adding the sixth Shift to the page using the PartialLink's listener. {08:44:47 27-08-2005} pages.ProfileCrudPage: ** ** ** ** ** ** ** ** ** {08:44:47 27-08-2005} pages.ProfileCrudPage: Entering addShift listener {08:44:47 27-08-2005} pages.ProfileCrudPage: Successfully added shift. {08:44:47 27-08-2005} pages.ProfileCrudPage: There are currently 6 shifts to iterate over. {08:44:47 27-08-2005} pages.ProfileCrudPage: ** ** ** ** ** ** ** ** ** {08:44:47 27-08-2005} pages.ProfileCrudPage: -- -- -- -- -- -- -- -- -- {08:44:47 27-08-2005} pages.ProtectedPage: pageBeginRender in Page: NewProfile {08:44:48 27-08-2005} pages.ProfileCrudPage: Rendering (Page is not rewinding) {08:44:48 27-08-2005} pages.ProfileCrudPage: General Profile was null -- resetting to a new one. {08:44:48 27-08-2005} pages.ProfileCrudPage: There are going to be 6 shifts to iterate over. {08:44:48 27-08-2005} pages.ProfileCrudPage: Finished beginning the render. {08:44:48 27-08-2005} pages.ProfileCrudPage: -- -- -- -- -- {08:44:48 27-08-2005} pages.ProfileCrudPage: -- -- -- -- -- {08:44:48 27-08-2005} pages.ProfileCrudPage: Page is done rendering, not rewinding. {08:44:48 27-08-2005} pages.ProfileCrudPage: -- -- -- -- -- -- -- -- -- ... -- At this point, I submit the entire Form (With "Monday", "Tuesday", "Wednesday", etc. selected, respectively for each of the six Shifts) {08:45:14 27-08-2005} pages.ProfileCrudPage: -- -- -- -- -- -- -- -- -- {08:45:14 27-08-2005} pages.ProfileCrudPage: Rendering (Page is rewinding) {08:45:14 27-08-2005} pages.ProfileCrudPage: General Profile was null -- resetting to a new one. {08:45:14 27-08-2005} pages.ProfileCrudPage: There are going to be 6 shifts to iterate over. {08:45:14 27-08-2005} pages.ProfileCrudPage: Finished beginning the render. {08:45:14 27-08-2005} pages.ProfileCrudPage: -- -- -- -- -- ... -- The Form's listener {08:45:14 27-08-2005} pages.ProfileNewPage: ** ** ** ** ** ** ** ** ** {08:45:14 27-08-2005} pages.ProfileNewPage: Entering saveProfile listener {08:45:14 27-08-2005} pages.ProfileNewPage: saveProfile listener: There were 6 shifts selected. {08:45:14 27-08-2005} pages.ProfileNewPage: Shift: null {08:45:14 27-08-2005} pages.ProfileNewPage: Shift: null {08:45:14 27-08-2005} pages.ProfileNewPage: Shift: null {08:45:14 27-08-2005} pages.ProfileNewPage: Shift: null {08:45:14 27-08-2005} pages.ProfileNewPage: Shift: null {08:45:14 27-08-2005} pages.ProfileNewPage: Shift: null {08:45:14 27-08-2005} pages.ProfileNewPage: ** ** ** ** ** ** ** ** ** {08:45:14 27-08-2005} pages.ProfileCrudPage: -- -- -- -- -- {08:45:14 27-08-2005} pages.ProfileCrudPage: Page is done rewinding {08:45:14 27-08-2005} pages.ProfileCrudPage: -- -- -- -- -- -- -- -- -- I'm likely fundamentally misunderstanding something, like the ListEdit component -- I know it needs to write hidden values up near the top of the form, which can't happen if I'm only re-rendering a small piece of the form, but I figured the form-rewinding would take care of it, since at that point it would see (and from the log-snippet, clearly does see) there are six persistent shift objects that the ListEdit component will be iterating over. So I don't understand why the select-box values are not being set to those objects during the rewinding phase, unless the original form submission needs those entries to be embedded in its hidden Form0 property ... but ... when I submit the page right now, since I haven't filled in the rest of the form, there is a validation problem, and I immediately go back to that page. When I view the source, I see that the six Shift select-box parameters have been properly added to the Form0 property, and there are also six corresponding hidden ListEdit properties ... so I would at least expect it to work if I submit a second time from this second seemingly-properly-formed page. But alas I still get six null Shift values. I'm sorry that this is a lot of info. Any input on any piece would be much-appreciated, and as I am on urgent crunch-time at this point, I'm more than willing to compromise the design here in order to get a brute-force method working. Jim Steinberger Dynamic Edge, Inc. [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]
