0

Consider following scenario. Have a page with some persistent object obj:

public class SomePage {
   @Persistent
   @Property
   SomeBean obj;

   @Property
   @PageActivationContext
   private SomeActivation actObj;

   ...

   void onValidateFromForm() { ... }
}

This obj is edited on a page:

<t:textfield t:id="value" t:value="obj.value"/>

Lets consider initialization procedure of obj state like this:

(*) obj.value = actObj.value;

(I strongly need to unbind value from actObj, please don't ask why).

Have also a validation method. When validation fails, I'd like to show errors list on page and keep also all values, which user filled on form and which were stored into obj.

So:

  1. when page firstly initialized with specific actObj I'd like to initialize obj
  2. when page validation fails, I don't want to reinitialize obj, because I want to keep its values and show them user with errors list.

The question is: where I should place initialization block (*) ?

Andremoniy
  • 34,031
  • 20
  • 135
  • 241

2 Answers2

0

You should be able to use onActivate() as this will occur before the request parameters are applied. So your submit event will first set the value from the activation context and then overwrite it with the value from the text field.

Note that tapestry only does a redirect after post when validation succeeds. When validation fails tapestry renders the errors in the POST response. For this reason, you might find that you don't need @Persist at all and can go stateless via @PageActivationContext / onActivate() / onPassivate()

lance-java
  • 25,497
  • 4
  • 59
  • 101
  • No, this will not work. When I change state of this object from form, before `onValidateFromForm()` it will always reinitialize object's state from data base, so all my changes will go on. – Andremoniy Jul 12 '13 at 14:23
  • Are you sure? The value will be looked up from the database but then immediately overridden by the field value from the request parameter. – lance-java Jul 12 '13 at 14:44
0

You can use activation handler instead of annotation, so:

@Persistent
@Property
private SomeBean obj;

@Property
private SomeActivation actObj;

@OnEvent(EventConstants.ACTIVATE)
void activatePage(SomeActivation actObj) {
  this.actObj = actObj;
  if (obj == null) {
    obj = // initialize
    obj.value = actObj.value
  }
}

@OnEvent(EventConstants.PASSIVATE)
Object passivatePage() {
  return actObj;
}

@OnEvent(value = EventConstants.SUCCESS, component = "form")
void success() {
  // do some staff

  // reset obj
  obj = null;
}

@OnEvent(value = EventConstants.FAILURE, component = "form")
void failure() {
  // do some staff
}
sody
  • 3,731
  • 1
  • 23
  • 28
  • Well, and what I should do in the case, when user clicks on other link on the page, so `success()` method will not be invoked? In this way `obj` will not receive `null` value, and on new `onActivate()` event it will not be reinitialized. – Andremoniy Jul 12 '13 at 14:10
  • if you don't need to save this value you don't need @Persist – sody Jul 12 '13 at 14:14
  • I need to save this value until I'm working with same `actObj`. And I need to reinitialize `obj` when `actObj` changes. – Andremoniy Jul 12 '13 at 14:19
  • If you need to just edit some properties of activation value(actObj) you don't need obj at all. All inputs are saved between requests if validation fails. Just use actObj directly. – sody Jul 12 '13 at 14:21
  • I can't use just `actObj` because I do not want to save its state to DB until values will be valid. – Andremoniy Jul 12 '13 at 14:24
  • save it to DB on success event from form – sody Jul 12 '13 at 14:26
  • I'd be glad doing so. But before `onValidationFromForm()` method being invoked, Tapestry forcibly reinitializes my `actObj` from DB (it goes to `onActivate()` **before** `onValidation...()`). So all changes become eliminated. – Andremoniy Jul 12 '13 at 14:28
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/33368/discussion-between-sody-and-andremoniy) – sody Jul 12 '13 at 14:38