[ 
https://issues.apache.org/jira/browse/WICKET-1826?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13500398#comment-13500398
 ] 

Stijn de Witt commented on WICKET-1826:
---------------------------------------

I could not use the patch, because the code it is altering is in a piece of 
final Wicket code and I am not allowed to (or willing) to use a custom Wicket 
version that was built from sources by ourselves.

So I had a look at the workaround. The instructions for using it are a bit 
vague... Should we modify the nested form (the one inside the modal window) or 
the root form (the one on the page itself)? I am not sure. I initially tried 
with the nested form but the change broke my whole environment. Somewhere it is 
trying to set the default submit button by calling setDeafultButton, but that 
method then goed into an infinite loop. It's code calls both isRootForm() and 
getRootForm(), but in the sugested workaround we override getRootForm in a way 
that makes it inconsistent with isRootForm. If getRootForm returns this, than 
isRootForm on this should return true... I altered it so that that is indeed 
true, and that made it work sorta, but the issue was not fixed by it...

So I dug deeper and then found a (the) solution.

First some observations:

1) Wicket supports nested forms, but HTML does not. To deal with that, Wicket 
renders divs instead of forms for any nested forms

2) Wicket's ModalWindow component renders a form tag all of it's own, which 
looks like this:
<form 
style="background-color:transparent;padding:0px;margin:0px;border-width:0px;position:static"><!--
 all modal window content is in here, including the nested form DIV --></form>

3) Wicket's docs state that the modal window should be inside a Form to prevent 
nested forms from giving issues:
"If you want to use form in modal window component make sure that you put the 
modal window itself in another form (nesting forms is legal in Wicket) and that 
the form on modal window is submitted before the window get closed."
http://wicket.apache.org/apidocs/1.5/org/apache/wicket/extensions/ajax/markup/html/modal/ModalWindow.html
If you don't do this the way the docs prescribe, you may get hit by issues such 
as Wicket 2214 ( https://issues.apache.org/jira/browse/WICKET-2214 )

4) When you do nest the whole modal window inside a Wicket Form, like this:
...
<body>
  ...
  <form wicket:id="modalForm" class="modalForm">
    <div wicket:id="modalWindow">[modalWindow]</div>
  </form>
  
  <div id="ajax-indicator" class="ajax-indicator">...</div>
</body>

You will get HTML that looks like this:

  <form class="modalForm" ... ></form>
  <div class="ajax-indicator">...</div>
  <div class="wicket-modal">
    <form 
style="background-color:transparent;padding:0px;margin:0px;border-width:0px;position:static">
      <!-- modal window content -->
      <div class="modalwindow" id="form4fa5">
        ...
        <input type="button" onclick="var 
wcall=wicketSubmitFormById('buttonForm4fa5', ..."/>
      </div>
    </form>    
  </div>

Surprisingly, in the HTML the modal window is not nested inside, but positioned 
side by side with the modalForm.
The button's onclick does a wicketSubmitFormById, passing the id of the nested 
form (which is rendered as a div).
The implementation of wicketSubmitFormById grabs the div with id "form4fa5" and 
from there on looks up in the element tree until it finds a form element. It 
finds the <form style="background-color:transparent;..."> that was rendered by 
the modal window component. It then grabs all inputs from this form and submits 
them with an ajax post.

5) On the server side, the post request is being handled by a Wicket behavior 
named AjaxFormSubmitBehavior.
(I am not sure whether this is the only way to do it with ajax, but this is how 
we are doing it)

6) That behavior calls onFormSubmitted() on the root form, which calls 
inputChanged on all it's form components, which try to find their input in the 
request but fail because only the form generated by the modalwindow component 
was ever submitted. This is the final cause of this issue.

Which brings me to the workaround.
I can't see how the root form can ever get submitted when it is not the same as 
the nested form, so it seems unreasonable to fire the onFormSubmitted method on 
it. So I extended AjaxFormSubmitBehavior and made an override for onEvent 
(which thankfully was not final. Thank you!!) that only calls onFormSubmitted 
on the nested form. So I just replaced it's first line:

getForm().getRootForm().onFormSubmitted();

with:

getForm().onFormSubmitted();

This fixes my issue and I don't see any side-effects.

Hopefully this will help you guys fix form handling for nested forms in 
dialogs, because it seems it's still broken in Wicket 1.5 as well (don't know 
about Wicket 6).

-Stijn



Also see: 

WICKET-3404: Improve ModalWindow form handling
https://issues.apache.org/jira/browse/WICKET-3404

Fwd: wicket nested form and modal
http://apache-wicket.1842946.n4.nabble.com/Fwd-wicket-nested-form-and-modal-td3234777.html
                
> Forms + ModalWindow + AjaxSubmitLink + FormComponent#isInputNullable
> --------------------------------------------------------------------
>
>                 Key: WICKET-1826
>                 URL: https://issues.apache.org/jira/browse/WICKET-1826
>             Project: Wicket
>          Issue Type: Bug
>          Components: wicket, wicket-extensions
>    Affects Versions: 1.3.3
>            Reporter: German Morales
>            Priority: Minor
>         Attachments: bug.zip, modalwindowform.jar, modalwindowform.jar, 
> WICKET-1826.patch
>
>
> Submiting a form which is inside a ModalWindow, wicket javascript sends only 
> the information for the modal window's form, but not for the root form of the 
> page (because ModalWindow hangs its own div at body level).
> On Wicket server side, the form processing is done for the root form, which 
> calls inputChanged for all the components in the page, but the javascript 
> side didn't send the information for them, and then some of them go wrong.
> That happens to FormComponents which have isInputNullable in true.
> More description and proposed solutions in the (to be) attached quickstart 
> project.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to