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*
>

Reply via email to