This (nested first) is the behavior for 1.5.
In 1.4, you could override the 'Form.delegateSubmit()' method,
rewriting its logic to execute forms in reverse order, **IF**
'Form.onSubmit()' wasn't protected (thus, you can't call it on nested
forms from your form subclass).
You can, however, use reflection to cheat :)
@SuppressWarnings("rawtypes")
public class HomePage extends WebPage {
public HomePage(final PageParameters parameters) {
class SelfLoggingForm extends Form {
public SelfLoggingForm(String id) {
super(id);
add(new Button("s"));
}
@Override
protected void onSubmit() {
System.out.println(this.getId());
}
@Override
protected void delegateSubmit(IFormSubmittingComponent
submittingComponent)
{
// when the given submitting component is not null, it
means that it was the
// submitting component
Form<?> formToProcess = this;
if (submittingComponent != null)
{
// use the form which the submittingComponent has
submitted for further processing
formToProcess = submittingComponent.getForm();
submittingComponent.onSubmit();
}
// this list will hold the forms for execution in reverse order
final List<Form<?>> forms = new ArrayList<Form<?>>();
// Model was successfully updated with valid data
forms.add(formToProcess);
// call onSubmit on nested forms
formToProcess.visitChildren(Form.class, new IVisitor<Form<?>>()
{
public Object component(Form<?> component)
{
Form<?> form = component;
if (form.isEnabledInHierarchy() &&
form.isVisibleInHierarchy())
{
forms.add(form);
return IVisitor.CONTINUE_TRAVERSAL;
}
return IVisitor.CONTINUE_TRAVERSAL_BUT_DONT_GO_DEEPER;
}
});
Collections.reverse(forms);
for (Form<?> form : forms) {
invokeOnSubmit(form);
}
}
private void invokeOnSubmit(Form<?> form) {
try {
final Method onSubmitMethod =
Form.class.getDeclaredMethod("onSubmit", new Class[0]);
onSubmitMethod.setAccessible(true);
onSubmitMethod.invoke(form);
} catch (Exception ex) {
throw new IllegalStateException(ex.getMessage(), ex);
}
}
}
add(new SelfLoggingForm("a")
.add(new SelfLoggingForm("b")
.add(new SelfLoggingForm("c"))));
}
}
<html
xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd">
<body>
<form wicket:id="a">
<form wicket:id="b">
<form wicket:id="c">
<button type="submit" wicket:id="s">C</button>
</form>
<button type="submit" wicket:id="s">B</button>
</form>
<button type="submit" wicket:id="s">A</button>
</form>
</body>
</html>
On Wed, Oct 19, 2011 at 6:30 PM, Bruno Borges <[email protected]> wrote:
> I wrote this message to the Users list but I now I think it would be better
> to ask the devs
>
> ...
>
> After playing with Nested Forms in WIcket 1.4.18, I found out that the
> onSubmit method of these forms is called at the end of the process.
>
> If a parent form has a button and this button is submited, its onSubmit
> method is called before anything.
> Then, parent form's onSubmit method is called.
> Then, it will navigate through all nested forms calling their onSubmit
> method.
> The problem is that I have a nested forms that changes a value in the model
> that is associated with the parent form.
>
> My usecase has an AddressPanel with a form inside that manipulates the
> "person.address" object. This panel is created by informing two
> IModel<Address> objects.
> One is to be used as the Person's address. The other one is to be used as
> copy of, because of a CheckBox that states "Use the same address as of
> account holder".
>
> On its onSubmit method, is where I clone the account holder address to the
> actual person.address.
>
> But because of the order of how Wicket calls onSubmit methods, this
> implementation fails.
>
> Any suggestion?
>
> Should Wicket call all nested forms' onSubmit methods before calling the
> Button's onSubmit (or the parent form onSubmit) ?
>
> Thanks,
>
> *Bruno Borges*
> (21) 7672-7099
> *www.brunoborges.com*
>