Hi,

Using a FormComponentPanel with Ajax is quite cumbersome from the client 
perspective: you have to add Ajax behavior to its nested components. And if a 
panel has more than 1 nested components, you need to add multiple behaviors. 
Combining the values of the nested components in the behaviors is also 
cumbersome. It would be nice if you could add an Ajax behavior to the panel, 
and simply be able to access the model object of the panel in the behavior.

I figured out a way to be able to add a AjaxFormComponentUpdatingBehavior to a 
FormComponentPanel, and in onUpdate(...) have an up-to-date model of the panel.

If you add the following to the Multiply example, convertInput() of Multiply 
will see the correct values for the converted inputs of the nested form 
components:

@Override
public void validate() {
    processInputIfNeeded(lhs);
    processInputIfNeeded(rhs);

    super.validate();
}

private void processInputIfNeeded(FormComponent<?> nestedComponent) {
    if (nestedComponent instanceof FormComponentPanel<?> || 
!Objects.equals(nestedComponent.getInput(), nestedComponent.getRawInput())) {
        nestedComponent.processInput();
    }
}

But for this to work properly, recursive serialization must be enabled for the 
attributes of the behavior. Otherwise the data of the nested components is not 
sent to the server. So a client adding this behavior must make sure to do this 
by overriding updateAjaxAttributes. As this is error-prone (and not how you use 
the behavior with other form components), I figured I could solve it with an 
AjaxRequestTarget.IListener.

Here I run into a problem: the method to get the component of an Ajax behavior 
is not public. If the method was public, I can see the following solution to 
easily allow Ajax updates for FormComponentPanels:
* Extension of FormComponentPanel with processInputIfNeeded(...), so sub 
classes do not have to copy this logic.
* Addition of a flag (which is not set by default) to FormComponentPanel, 
telling the listener that recursive serialization must be enabled for 
AjaxFormComponentUpdatingBehaviors attached to the panel.
* An AjaxRequestTarget.IListener implementation that will enable recursive 
serialization if the behavior is a AjaxFormComponentUpdatingBehavior and the 
FormComponentPanel has the flag set.

Creating and using FormComponentPanels that can be used with Ajax updates is 
then possible by:
* Adding a listener to the application.
* Setting the flag on a panel.
* Overriding validate() and invoking processInputIfNeeded(...) for each nested 
component.

The only issue with this approach I found so far is that processInput() will be 
called on nested FormComponentPanels in situations where it is not needed.

So my questions are:
* Is there a reason to not expose the component of an Ajax behavior?
* Will my approach break in some situations? Result in unnecessary expensive 
processing? ...

Thanks in advance for your answers.

--
Best regards / Met vriendelijke groet,

Johan Stuyts
Squins IT Solutions BV
Oranjestraat 30
2983 HS  Ridderkerk
The Netherlands
www.squins.com
Chamber of commerce Rotterdam: 24435103

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Reply via email to