This is an automated email from the ASF dual-hosted git repository.
bitstorm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/wicket.git
The following commit(s) were added to refs/heads/master by this push:
new 03dc5e159f WICKET-7144 process form component panel children on ajax
(#1554)
03dc5e159f is described below
commit 03dc5e159fd8dca11aa969ff6591c5bbc6f1de22
Author: Johan Stuyts <[email protected]>
AuthorDate: Wed Sep 16 15:51:09 2026 +0200
WICKET-7144 process form component panel children on ajax (#1554)
* WICKET-7144 Changed AjaxFormComponentUpdatingBehavior to support inner
form
components submission
* WICKET-7144 enable recursive serialization if inner components must be
updated.
Added paragraph to documentation about form component panels in combination
with AjaxFormComponentUpdatingBehavior. Removed obsolete Javadoc on how to
Ajaxify form component panels.
Added example showing that the new behavior works.
---------
Co-authored-by: Andrea Del Bene <[email protected]>
---
.../AjaxFormComponentUpdatingBehaviorTest.java | 94 +++++++++++++++++++++
.../form/FormComponentPanelProcessingTest.java | 98 ++++++++++++++++++++++
.../form/AjaxFormComponentUpdatingBehavior.java | 81 +++++++++++++++++-
.../examples/ajax/builtin/AjaxApplication.java | 1 +
.../ajax/builtin/FormComponentPanelPage.html | 13 +++
.../ajax/builtin/FormComponentPanelPage.java | 68 +++++++++++++++
.../apache/wicket/examples/ajax/builtin/Index.html | 4 +-
.../html/form/datetime/AbstractDateTimeField.java | 22 -----
.../markup/html/form/palette/Palette.java | 23 -----
.../src/main/asciidoc/ajax/ajax_3.adoc | 5 +-
10 files changed, 360 insertions(+), 49 deletions(-)
diff --git
a/wicket-core-tests/src/test/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehaviorTest.java
b/wicket-core-tests/src/test/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehaviorTest.java
new file mode 100644
index 0000000000..514af1282c
--- /dev/null
+++
b/wicket-core-tests/src/test/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehaviorTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.ajax.form;
+
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
+import org.apache.wicket.markup.html.form.FormComponentPanel;
+import org.apache.wicket.markup.html.form.TextField;
+import org.apache.wicket.util.tester.WicketTestCase;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class AjaxFormComponentUpdatingBehaviorTest extends WicketTestCase
+{
+ @Test
+ void
enablesRecursiveSerializationIfFormComponentPanelAndInnerComponentsMustBeUpdated()
+ {
+ FormComponentPanel<Object> formComponentPanel = new
FormComponentPanel<>("some_id") {};
+ var behavior = new AjaxFormComponentUpdatingBehavior("some_event")
+ {
+ @Override
+ protected void onUpdate(AjaxRequestTarget target)
+ {
+ }
+ };
+ formComponentPanel.add(behavior);
+ AjaxRequestAttributes attributes = new AjaxRequestAttributes();
+
+ behavior.updateAjaxAttributes(attributes);
+
+ assertTrue(attributes.isSerializeRecursively());
+ }
+
+ @Test
+ void doesNotModifyRecursiveSerializationIfNotFormComponentPanel()
+ {
+ TextField textField = new TextField<>("some_id");
+ var behavior = new AjaxFormComponentUpdatingBehavior("some_event")
+ {
+ @Override
+ protected void onUpdate(AjaxRequestTarget target)
+ {
+ }
+ };
+ textField.add(behavior);
+ AjaxRequestAttributes attributes = new AjaxRequestAttributes();
+ attributes.setSerializeRecursively(true);
+
+ behavior.updateAjaxAttributes(attributes);
+
+ assertTrue(attributes.isSerializeRecursively());
+ }
+
+ @Test
+ void doesNotModifyRecursiveSerializationIfInnerComponentsMustNotBeUpdated()
+ {
+ FormComponentPanel<Object> formComponentPanel = new
FormComponentPanel<>("some_id") {};
+ var behavior = new AjaxFormComponentUpdatingBehavior("some_event")
+ {
+ @Override
+ protected void onUpdate(AjaxRequestTarget target)
+ {
+ }
+
+ @Override
+ protected boolean updateInnerComponents()
+ {
+ return false;
+ }
+ };
+ formComponentPanel.add(behavior);
+ AjaxRequestAttributes attributes = new AjaxRequestAttributes();
+ attributes.setSerializeRecursively(true);
+
+ behavior.updateAjaxAttributes(attributes);
+
+ assertTrue(attributes.isSerializeRecursively());
+ }
+}
diff --git
a/wicket-core-tests/src/test/java/org/apache/wicket/markup/html/form/FormComponentPanelProcessingTest.java
b/wicket-core-tests/src/test/java/org/apache/wicket/markup/html/form/FormComponentPanelProcessingTest.java
index cb047e8fc5..4c867a094b 100644
---
a/wicket-core-tests/src/test/java/org/apache/wicket/markup/html/form/FormComponentPanelProcessingTest.java
+++
b/wicket-core-tests/src/test/java/org/apache/wicket/markup/html/form/FormComponentPanelProcessingTest.java
@@ -22,6 +22,8 @@ import static org.junit.jupiter.api.Assertions.fail;
import java.io.Serializable;
import org.apache.wicket.MarkupContainer;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.markup.IMarkupResourceStreamProvider;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.model.IModel;
@@ -66,6 +68,42 @@ class FormComponentPanelProcessingTest extends WicketTestCase
assertEquals(true, fcp.isChildClearInputCalled());
}
+ @Test
+ void ajaxFormComponentUpdatingBehavior()
+ {
+ AjaxFormComponentUpdatingBehavior ajaxBehavior = new
AjaxFormComponentUpdatingBehavior("update")
+ {
+
+ @Override
+ protected void onUpdate(AjaxRequestTarget target)
+ {
+ //"updating"
+ }
+ };
+
+ OuterFormComponentPanel ofcp = new
OuterFormComponentPanel("outPanel");
+ ofcp.add(ajaxBehavior);
+ ofcp.setOutputMarkupId(true);
+
+ tester.startComponentInPage(ofcp);
+
+ tester.executeBehavior(ajaxBehavior);
+
+ //inner component has a required field we haven't set
+ assertEquals(false, ofcp.isValid());
+ assertEquals(false, ofcp.childModelUpdated);
+
+ //let's set the inner field
+ tester.getRequest()
+ .getPostParameters()
+ .setParameterValue(((TextField<?>)
ofcp.inner.get("subfield")).getInputName(), "textVal");
+
+ //now submission should regularly happen
+ tester.executeBehavior(ajaxBehavior);
+ assertEquals(true, ofcp.childModelUpdated);
+ assertEquals(true, ofcp.inner.isValid());
+ }
+
private static class TestFormComponentPanel extends
FormComponentPanel<Serializable>
implements
IMarkupResourceStreamProvider
@@ -169,4 +207,64 @@ class FormComponentPanelProcessingTest extends
WicketTestCase
}
}
+
+ private static class OuterFormComponentPanel extends
FormComponentPanel<String> implements
+ IMarkupResourceStreamProvider
+ {
+ public InnerFormComponentPanel inner = new
InnerFormComponentPanel("inner");
+ public boolean childModelUpdated;
+
+ public OuterFormComponentPanel(String id)
+ {
+ super(id, Model.of());
+
+ add(inner);
+ add(new TextField<String>("username",
Model.of("")));
+ }
+
+ @Override
+ public void updateModel()
+ {
+ super.updateModel();
+ childModelUpdated = true;
+ }
+
+ @Override
+ public IResourceStream
getMarkupResourceStream(MarkupContainer container,
+ Class<?> containerClass)
+ {
+ return new StringResourceStream(
+ "<wicket:panel><span
wicket:id=\"inner\"></span><input type=\"text\" id=\"username\"
name=\"username\" wicket:id=\"username\"></wicket:panel>");
+ }
+
+ }
+
+ private static class InnerFormComponentPanel extends
FormComponentPanel<String> implements
+ IMarkupResourceStreamProvider
+ {
+ public boolean wasAskedToProcessInput;
+
+ public InnerFormComponentPanel(String id)
+ {
+ super(id, Model.of());
+ add(new TextField<String>("subfield",
Model.of("")).setRequired(true));
+ }
+
+
+ @Override
+ public void validate()
+ {
+ wasAskedToProcessInput = true;
+
+ super.validate();
+ }
+
+ @Override
+ public IResourceStream
getMarkupResourceStream(MarkupContainer container,
+ Class<?> containerClass)
+ {
+ return new StringResourceStream(
+ "<wicket:panel><input type=\"text\"
id=\"subfield\" name=\"subfield\" wicket:id=\"subfield\"
required></wicket:panel>");
+ }
+ }
}
diff --git
a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
index 2730827175..9dedfe431f 100644
---
a/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
+++
b/wicket-core/src/main/java/org/apache/wicket/ajax/form/AjaxFormComponentUpdatingBehavior.java
@@ -17,6 +17,7 @@
package org.apache.wicket.ajax.form;
import java.util.Locale;
+import java.util.Objects;
import org.apache.wicket.Application;
import org.apache.wicket.Component;
@@ -25,8 +26,8 @@ import org.apache.wicket.ajax.AjaxEventBehavior;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
import org.apache.wicket.ajax.attributes.AjaxRequestAttributes.Method;
-import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
import org.apache.wicket.markup.html.form.FormComponent;
+import org.apache.wicket.markup.html.form.FormComponentPanel;
import org.apache.wicket.markup.html.form.validation.IFormValidator;
import org.apache.wicket.util.lang.Args;
import org.danekja.java.util.function.serializable.SerializableConsumer;
@@ -121,6 +122,10 @@ public abstract class AjaxFormComponentUpdatingBehavior
extends AjaxEventBehavio
super.updateAjaxAttributes(attributes);
attributes.setMethod(Method.POST);
+ if (getComponent() instanceof FormComponentPanel &&
updateInnerComponents())
+ {
+ attributes.setSerializeRecursively(true);
+ }
}
@Override
@@ -133,6 +138,19 @@ public abstract class AjaxFormComponentUpdatingBehavior
extends AjaxEventBehavio
target.focusComponent(null);
}
+ if (updateInnerComponents())
+ {
+ visitInnerComponents(target, formComponent);
+ }
+ else
+ {
+ visitSingleComponent(target, formComponent);
+ }
+
+ }
+
+ private void visitSingleComponent(AjaxRequestTarget target,
FormComponent<?> formComponent)
+ {
try
{
formComponent.inputChanged();
@@ -158,9 +176,55 @@ public abstract class AjaxFormComponentUpdatingBehavior
extends AjaxEventBehavio
{
onError(target, e);
}
+
formComponent.updateAutoLabels(target, false);
}
+ private void visitInnerComponents(final AjaxRequestTarget target, final
FormComponent<?> formComponent)
+ {
+ try
+ {
+ Boolean validateresult =
FormComponent.visitFormComponentsPostOrder(formComponent, (component, visit) ->
+ {
+ component.inputChanged();
+ component.validate();
+
+ if (!component.isValid())
+ {
+ visit.stop(false);
+ }
+ });
+
+ if (Objects.requireNonNullElse(validateresult, true))
+ {
+ if (getUpdateModel())
+ {
+
FormComponent.visitFormComponentsPostOrder(formComponent, (component, visit) ->
+ {
+ component.valid();
+ component.updateModel();
+ });
+ }
+
+ onUpdate(target);
+ }
+ else
+ {
+ formComponent.invalid();
+ onError(target, null);
+ }
+ }
+ catch (RuntimeException e)
+ {
+ onError(target, e);
+ }
+
+ FormComponent.visitFormComponentsPostOrder(formComponent,
(component, visit) ->
+ {
+ component.updateAutoLabels(target, false);
+ });
+ }
+
/**
* Gives the control to the application to decide whether the form
component model should
* be updated automatically or not. Make sure to call {@link
org.apache.wicket.markup.html.form.FormComponent#valid()}
@@ -173,6 +237,21 @@ public abstract class AjaxFormComponentUpdatingBehavior
extends AjaxEventBehavio
return true;
}
+ /**
+ * Whether to update the inner components. Enabled by default so this
behavior works as expected for
+ * {@link org.apache.wicket.markup.html.form.FormComponentPanel}s: the
model has been updated using the input of
+ * the inner components of the panel on calling {@link
#onUpdate(AjaxRequestTarget)}.
+ * <p>
+ * This is new behavior from Wicket 11. Before Wicket 11 using Ajax
with <code>FormComponentPanel</code>s was more
+ * cumbersome. If you need to revert to the pre-Wicket 11 behavior,
return <code>false</code>.
+ *
+ * @return <code>true</code> to process the inner components,
<code>false</code> otherwise.
+ */
+ protected boolean updateInnerComponents()
+ {
+ return true;
+ }
+
/**
* Determines whether the focus will not be restored when the event is
blur. By default this is
* true, as we don't want to re-focus component on blur event.
diff --git
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
index cbeed2d733..68e670ae15 100644
---
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
+++
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
@@ -52,6 +52,7 @@ public class AjaxApplication extends WicketExampleApplication
mountPage("autocomplete", AutoCompletePage.class);
mountPage("choice", ChoicePage.class);
+ mountPage("form-component-panel", FormComponentPanelPage.class);
mountPage("clock", ClockPage.class);
mountPage("editable-label", EditableLabelPage.class);
mountPage("effects", EffectsPage.class);
diff --git
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FormComponentPanelPage.html
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FormComponentPanelPage.html
new file mode 100644
index 0000000000..d3ec8f96c4
--- /dev/null
+++
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FormComponentPanelPage.html
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<wicket:extend xmlns:wicket="http://wicket.apache.org">
+
+This example demonstrates a AjaxFormComponentUpdatingBehavior in combination
with a FormComponentPanel.
+
+Whenever the input numbers are changed it will submit the new value to the
server via Ajax and update the result.
+
+<br/><br/>
+<form wicket:id="form">
+ <span wicket:id="multiply">[multiply]</span>
+ = <span wicket:id="multiplyLabel">[result]</span>
+</form>
+</wicket:extend>
diff --git
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FormComponentPanelPage.java
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FormComponentPanelPage.java
new file mode 100644
index 0000000000..89cfe99d1c
--- /dev/null
+++
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FormComponentPanelPage.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.examples.ajax.builtin;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
+import org.apache.wicket.examples.forminput.Multiply;
+import org.apache.wicket.markup.html.basic.Label;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
+
+/**
+ * FormComponentPanel with Ajax example
+ */
+public class FormComponentPanelPage extends BasePage
+{
+ /**
+ * The result of the multiplication.
+ */
+ private final IModel<Integer> result = Model.of(0);
+
+ /**
+ * Constructor.
+ */
+ public FormComponentPanelPage()
+ {
+ Form<?> form = new Form("form");
+ add(form);
+
+ Multiply multiply = new Multiply("multiply", result);
+ Component multiplyLabel = new Label("multiplyLabel", result)
+ .setOutputMarkupId(true);
+ multiply.add(new AjaxFormComponentUpdatingBehavior("input
change")
+ {
+ @Override
+ protected void onUpdate(AjaxRequestTarget target)
+ {
+ target.add(multiplyLabel);
+ }
+
+ @Override
+ protected void onError(AjaxRequestTarget target,
RuntimeException e)
+ {
+ result.setObject(null);
+ target.add(multiplyLabel);
+ }
+ });
+ form.add(multiply);
+ // display the multiply result
+ form.add(multiplyLabel);
+ }
+}
diff --git
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
index 87813e529e..74574a775a 100644
---
a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
+++
b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/Index.html
@@ -6,6 +6,8 @@
<br/><br/>
<a href="ChoicePage.html">Drop Down Choice Example</a>: demonstrates the
linked select boxes usecase
<br/><br/>
+<a href="FormComponentPanelPage.html">Form Component Panel Example</a>:
demonstrates the form component panel usecase
+<br/><br/>
<a href="ClockPage.html">Clock Example</a>: demonstrates a self-updating
component via AjaxSelfUpdatingTimerBehavior
<br/><br/>
<a href="EditableLabelPage.html">Editable Label Example</a>: shows a label
that can be edited inline via ajax
@@ -39,4 +41,4 @@
<a href="AjaxDownloadPage.html">Ajax Download</a>: download initiated via Ajax
</wicket:link>
-</wicket:extend>
\ No newline at end of file
+</wicket:extend>
diff --git
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.java
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.java
index cd81b566f2..afc5f7bf29 100644
---
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.java
+++
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/datetime/AbstractDateTimeField.java
@@ -22,7 +22,6 @@ import java.time.format.FormatStyle;
import java.time.temporal.Temporal;
import java.util.Date;
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.core.util.string.CssUtils;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.html.basic.Label;
@@ -33,28 +32,7 @@ import org.apache.wicket.util.convert.ConversionException;
/**
* Works on a {@link java.time.temporal.Temporal} object, aggregating a {@link
LocalDateTextField} and a {@link TimeField}.
- * <p>
- * <strong>Ajaxifying an AbstractDateTimeField</strong>:
- * If you want to update this component with an {@link
AjaxFormComponentUpdatingBehavior}, you have to attach it
- * to the contained components by overriding {@link #newDateField(String,
IModel)}:
- *
- * <pre>{@code
- * DateTimeField dateTimeField = new DateTimeField(...) {
- * protected DateTextField newDateTextField(String id, PropertyModel<Date>
dateFieldModel)
- * {
- * DateTextField dateField = super.newDateTextField(id, dateFieldModel);
- * dateField.add(new AjaxFormComponentUpdatingBehavior("change") {
- * protected void onUpdate(AjaxRequestTarget target) {
- * processInput(); // let DateTimeField process input too
*
- * ...
- * }
- * });
- * return recorder;
- * }
- * }
- * }</pre>
- *
* @author eelcohillenius
*/
abstract class AbstractDateTimeField<T extends Temporal> extends
FormComponentPanel<T>
diff --git
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/palette/Palette.java
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/palette/Palette.java
index 85648a600e..71536e5707 100644
---
a/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/palette/Palette.java
+++
b/wicket-extensions/src/main/java/org/apache/wicket/extensions/markup/html/form/palette/Palette.java
@@ -22,7 +22,6 @@ import java.util.List;
import java.util.Map;
import org.apache.wicket.Component;
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.extensions.markup.html.form.palette.component.Choices;
import
org.apache.wicket.extensions.markup.html.form.palette.component.Recorder;
import
org.apache.wicket.extensions.markup.html.form.palette.component.Selection;
@@ -50,28 +49,6 @@ import org.apache.wicket.request.resource.ResourceReference;
* When creating a Palette object make sure your IChoiceRenderer returns a
specific ID, not the
* index.
* <p>
- * <strong>Ajaxifying the palette</strong>: If you want to update a Palette
with an
- * {@link AjaxFormComponentUpdatingBehavior}, you have to attach it to the
contained
- * {@link Recorder} by overriding {@link #newRecorderComponent()} and calling
- * {@link #processInput()}:
- *
- * <pre>{@code
- * Palette palette=new Palette(...) {
- * protected Recorder newRecorderComponent()
- * {
- * Recorder recorder=super.newRecorderComponent();
- * recorder.add(new AjaxFormComponentUpdatingBehavior("change") {
- * protected void onUpdate(AjaxRequestTarget target) {
- * processInput(); // let Palette process input too
- *
- * ...
- * }
- * });
- * return recorder;
- * }
- * }
- * }</pre>
- *
* You can add a {@link DefaultTheme} to style this component in a left to
right fashion.
*
* @author Igor Vaynberg ( ivaynberg )
diff --git a/wicket-user-guide/src/main/asciidoc/ajax/ajax_3.adoc
b/wicket-user-guide/src/main/asciidoc/ajax/ajax_3.adoc
index ac327c0f04..d281414983 100644
--- a/wicket-user-guide/src/main/asciidoc/ajax/ajax_3.adoc
+++ b/wicket-user-guide/src/main/asciidoc/ajax/ajax_3.adoc
@@ -85,10 +85,12 @@ NOTE: _AjaxFormSubmitBehavior_ does not prevent JavaScript
default event handlin
=== AjaxFormComponentUpdatingBehavior
-This behavior updates the model of the form component it is attached to when a
given event occurs. The standard form submitting process is skipped and the
behavior validates only its form component.
+This behavior updates the model of the form component it is attached to when a
given event occurs. The standard form submitting process is skipped and the
behavior validates only its form component.
The behavior doesn't work with radio buttons and checkboxes. For these kinds
of components we must use _AjaxFormChoiceComponentUpdatingBehavior_:
+From Wicket 11 it will also process the inner components of
_FormComponentPanels_( regardless of the kind of descendant components). This
ensures the model of the _FormComponentPanel_ has been updated before
_onUpdate(...)_ is invoked. Note that this will force recursive serialization
of the data of the inner components. To restore the pre-Wicket 11 behavior
return _false_ from _updateInnerComponents()_.
+
[source,java]
----
Form<Void> form = new Form<>("form");
@@ -121,4 +123,3 @@ add(dynamicLabel);
----
NOTE: By default AJAX components and behaviors are _stateful_, but as we will
see very soon they can be easily turned to stateless if we need to use them in
stateless pages.
-