Really important work Geoff, thanks. Which version are you using? I hope you
go through the extra work to keep up with the versions.

Davor, you say the invalidated form is persisted in session by default. Does
multi-window support work in this case, i.e. if the same user opens another
edit page for the same object, changes somethings and submits the first one,
what would happen?

Kalle


On 1/28/08, Davor Hrg <[EMAIL PROTECTED]> wrote:
>
> things are a bit different in newer versions,
>
> for one, form persists submited data if validation fails,
> and does not update data on your entity.
>
> the invalidated form is persisted default (session if without @Meta)
> and suits my use fine, I reset form only if new entityid shows up,
> if you go to: "edit/3" and have validation errors ,and go to another page,
> then return to "edit/3" validation errors are stil there, and last
> submited data,
> if you go to edit/4 errors are reset and new data from db loaded...
>
> not that this suits everybody else, but is fine for me..
>
> Davor Hrg
>
> On Jan 28, 2008 3:01 PM, Martin Grotzke <[EMAIL PROTECTED]>
> wrote:
> > Hi Geoff,
> >
> > if validation fails the page is displayed again, and the person will be
> > loaded again in the according GET request - so all input from the user
> > will be lost.
> >
> > We're using flash persistence for this: the person would get annotated
> > with @Persist("flash"), would be reset in cleanupRender and loaded in
> > onActivate only if the entity (field) is null.
> >
> > With this two subsequent request like
> >
> > /person/edit/1
> > and
> > /person/edit/2
> >
> > display the correct data, as the person is not persisted after
> > cleanupRender has been invoked.
> >
> > When first page is submitted, the person with id 1 is loaded from the
> > backend in onActivate, in populated by tapestry, and validated by
> > yourself. If then some validation error occurs and the page is displayed
> > again (by using redirect after POST), the person is still existing in
> > persist/flash with the populated values.
> >
> > When redirect is done in onSuccessFromYourForm the entity should be also
> > reset / removed from persist/flash...
> >
> > Btw: our experiences are based on T5.0.5, but I suppose these still
> > apply to later versions of T5...
> >
> > Cheers,
> > Martin
> >
> >
> >
> > On Mon, 2008-01-28 at 23:46 +1100, Geoff Callender wrote:
> > > Here's Mark V of the single page edit.  In previous attempts I was
> > > clinging onto client-side persistence of the entity to ensure
> > > optimistic locking, and then "the penny finally dropped" - all you
> > > need to ensure optimistic locking is to ensure the entity's version is
> > > retained - and you can do that with a hidden field.  So client-side
> > > persistence really isn't necessary.  Hallelujah!
> > >
> > >       private Long _personId;
> > >
> > >       private Person _person;
> > >
> > >       void onActivate(Long id) throws Exception {
> > >               _personId = id;
> > >               _person = getPersonService().findPerson(_personId);
> > >       }
> > >
> > >       Long onPassivate() {
> > >               return _personId;
> > >       }
> > >
> > >       void onValidateFromForm() {
> > >               if (...a bit of validation logic detects an error...) {
> > >                       _form.recordError(...);
> > >                       return;
> > >               }
> > >               try {
> > >                       // move this back to onSuccess() once
> TAPESTRY-1972 has been
> > > resolved.
> > >                       getPersonService().changePerson(_person);
> > >               }
> > >               catch (Exception e) {
> > >                       _form.recordError(ExceptionUtil.getRootCause
> (e));
> > >               }
> > >       }
> > >
> > >       Object onSuccess() {
> > >               _nextPage.onActivate(_personId);
> > >               return _nextPage;
> > >       }
> > >
> > >       void cleanupRender() {
> > >               _form.clearErrors();
> > >       }
> > >
> > > and in the html form, use the Hidden component that's been discussed
> > > in this mailing list:
> > >
> > >               <t:hidden t:id="version" value="person.version"/>
> > >
> > > or if you're using BeanEditForm:
> > >
> > >       <t:beaneditform t:id="form" object="person" submitLabel="Save">
> > >               <t:parameter name="version">
> > >                       <t:hidden t:id="version" value="person.version
> "/>
> > >               </t:parameter>
> > >       </t:beaneditform>
> > >
> > > Yes, onActivate(...) is called twice if there's an error detected
> > > server-side, but that's due to the redirect-after-post paradigm, so
> > > it's a cost with a pretty big benefit.
> > >
> > > One last note, the cleanupRender() method can be removed if T5 moves
> > > to "flash" persistence on the form's ValidationTracker.
> > >
> > > Anything I've missed?
> > >
> > > Cheers,
> > >
> > > Geoff
> > >
> > > On 12/12/2007, at 7:39 AM, Geoff Callender wrote:
> > >
> > > > I'm planning on doing one, but not today.  If you know your way
> > > > around T4 then the web flow example in JumpStart Max 2.0.0 may help
> > > > you. It's at http://files.doublenegative.com.au/jumpstart/ .
> > > >
> > > > Here's Mk IV of the single page edit.  It seems that recording
> > > > errors in onSuccess() can cause fields to revert when you redisplay
> > > > with error, so I've moved some of it to onValidate().   The notes
> > > > from before are still relevant.
> > > >
> > > >     private Long _personId;
> > > >
> > > >     // "client" is used so that  even if you use the Back button
> > > >     // to get to me, I will have the right Person object.
> > > >     @Persist("client")
> > > >     private Person _person;
> > > >
> > > >     void onActivate(Long id) throws Exception { _personId = id; }
> > > >
> > > >     Long onPassivate() { return _person.getId(); }
> > > >
> > > >     void setupRender() throws Exception {
> > > >             if (!_form.getHasErrors()) {
> > > >                     _person =
> getPersonService().findPerson(_personId);
> > > >             }
> > > >     }
> > > >
> > > >     void onValidate() throws Exception {
> > > >             if (...a bit of validation logic detects an error...) {
> > > >                     _form.recordError(...);
> > > >                     return;
> > > >             }
> > > >             try {
> > > >                     getPersonService().changePerson(_person);
> > > >             }
> > > >             catch (Exception e) {
> > > >                     _form.recordError(ExceptionUtil.getRootCause
> (e));
> > > >                     return;
> > > >             }
> > > >     }
> > > >
> > > >     Object onSuccess() {
> > > >             _nextPage.onActivate(_personId);
> > > >             return _nextPage;
> > > >     }
> > > >
> > > >     void cleanupRender() {
> > > >                _form.clearErrors();
> > > >     }
> > > >
> > > > Cheers,
> > > >
> > > > Geoff
> > > >
> > > > On 12/12/2007, at 4:53 AM, jeffrey ai wrote:
> > > >
> > > >>
> > > >> Geoff, I think your code is great for **ONE** edit-page.
> > > >> Our project is looking for a web flow from T5, like the Spring one.
> > > >> Do you have any idea about it?
> > > >> Howard mentioned he may add this feature in the next release.
> > > >> Might be a little late to us, but I am expecting to see it.
> > > >>
> > > >> Cheers,
> > > >> Jeffrey Ai
> > > >>
> > > >>
> > > >> Geoff Callender-2 wrote:
> > > >>>
> > > >>> Hi,
> > > >>>
> > > >>> In search of best practice for an "edit" page, here's my 3rd
> > > >>> attempt.
> > > >>> It's looking pretty clean-cut to me, but I'm looking for
> suggestions
> > > >>> on how to improve it further.
> > > >>>
> > > >>>   private Long _personId;
> > > >>>
> > > >>>   @Persist("client")
> > > >>>   // Persistence is needed here because this is a detached Entity
> > > >>> Bean.  When we call the service to
> > > >>>   // accept our changes, it will need its id and version fields
> > > >>> intact
> > > >>> to be able to do optimistic
> > > >>>   // locking check and a successful merge. "client" is used so
> that
> > > >>> even if you use the Back button
> > > >>>   // to get to this page, we will have the right Person object.
> > > >>>   private Person _person;
> > > >>>
> > > >>>   void onActivate(Long id) throws Exception { _personId = id; }
> > > >>>
> > > >>>   Long onPassivate() { return _person.getId(); }
> > > >>>
> > > >>>   void setupRender() throws Exception {
> > > >>>           if (!_form.getHasErrors()) {
> > > >>>                   _person =
> getPersonService().findPerson(_personId);
> > > >>>           }
> > > >>>   }
> > > >>>
> > > >>>   void onValidate() throws Exception {
> > > >>>           if (...a bit of validation logic detects an error...) {
> > > >>>                   _form.recordError(...);
> > > >>>           }
> > > >>>   }
> > > >>>
> > > >>>   Object onSuccess() {
> > > >>>           try {
> > > >>>                   getPersonService().changePerson(_person);
> > > >>>                   _nextPage.onActivate(_personId);
> > > >>>                   return _nextPage;
> > > >>>           }
> > > >>>           catch (Exception e) {
> > > >>>                   _form.recordError(ExceptionUtil.getRootCause
> (e));
> > > >>>                   return null;
> > > >>>           }
> > > >>>   }
> > > >>>
> > > >>>   void cleanupRender() {
> > > >>>              _form.clearErrors();
> > > >>>   }
> > > >>>
> > > >>> Some notes:
> > > >>>
> > > >>> 1. Detached object - Person is a detached entity.  I am
> deliberately
> > > >>> avoiding refreshing it every time in setupRender() because a) it
> > > >>> would
> > > >>> overwrite the user's changes, and b) it would defeat optimistic
> > > >>> locking: if someone else has changed the object then I DO want
> > > >>> getPersonService().changePerson(_person) to reject the transaction
> > > >>> when Save is pressed.
> > > >>>
> > > >>> 2. Thread-safety - I'm using "client" persistence to avoid the
> whole
> > > >>> thread-safety issue caused by the user opening a new window or
> > > >>> tabs in
> > > >>> same browser (T5 can't tell them apart so they share the same
> > > >>> HttpSession).
> > > >>>
> > > >>> 3. onPrepareFromForm() - I'm avoiding it because it gets called
> too
> > > >>> often (something to do with "rewind"?).  setupRender() seems
> better
> > > >>> for the job.  Any downside t this?
> > > >>>
> > > >>> 4. cleanupRender() - if/when 5.0.7 uses flash persistence on the
> > > >>> form's ValidationTracker then I'll ditch this method.
> > > >>>
> > > >>> Suggestions please!
> > > >>>
> > > >>> Thanks,
> > > >>>
> > > >>> Geoff
> > > >>>
> > > >>>
> > > >>>
> > > >>
> > > >> --
> > > >> View this message in context:
> http://www.nabble.com/T5%3A-Edit-page-best-practice---Mk-III-tp14249141p14279495.html
> > > >> Sent from the Tapestry - User mailing list archive at Nabble.com.
> > > >>
> > > >>
> > > >>
> ---------------------------------------------------------------------
> > > >> To unsubscribe, e-mail: [EMAIL PROTECTED]
> > > >> For additional commands, e-mail: [EMAIL PROTECTED]
> > > >>
> > > >
> > >
> > --
> > Martin Grotzke
> > http://www.javakaffee.de/blog/
> >
> >
> >
> > ---------------------------------------------------------------------
> > 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