You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2017/04/04 15:38:10 UTC

[3/8] wicket git commit: WICKET-6348 move selection change into behavior

WICKET-6348 move selection change into behavior


Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/e2af7563
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/e2af7563
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/e2af7563

Branch: refs/heads/master
Commit: e2af75630ceaa3da0b7b00a88c87adac3dc7a3f6
Parents: 25567ba
Author: Sven Meier <sv...@apache.org>
Authored: Wed Mar 29 11:40:33 2017 +0200
Committer: Sven Meier <sv...@apache.org>
Committed: Tue Apr 4 17:30:04 2017 +0200

----------------------------------------------------------------------
 .../apache/wicket/markup/html/form/Check.java   |  20 ---
 .../wicket/markup/html/form/CheckBox.java       | 121 +---------------
 .../wicket/markup/html/form/CheckGroup.java     |  91 +-----------
 .../wicket/markup/html/form/DropDownChoice.java | 119 +---------------
 .../apache/wicket/markup/html/form/Radio.java   |  20 ---
 .../wicket/markup/html/form/RadioChoice.java    | 126 +---------------
 .../wicket/markup/html/form/RadioGroup.java     |  94 +-----------
 .../html/form/SelectionChangeBehavior.java      | 142 +++++++++++++++++++
 .../wicket/util/tester/BaseWicketTester.java    |  25 +++-
 .../apache/wicket/util/tester/FormTester.java   |  27 +---
 .../org/apache/wicket/MockPageWithForm.java     |  21 +--
 .../wicket/util/tester/FormTesterTest.java      |  16 +--
 .../extensions/yui/calendar/DatesPage1.java     |  20 +--
 .../yui/calendar/DatesPage1_ExpectedResult.html |   2 +-
 .../wicket/examples/compref/CheckGroupPage.html |   3 -
 .../wicket/examples/compref/CheckGroupPage.java |  14 +-
 .../apache/wicket/examples/dates/DatesPage.java |  14 +-
 .../wicket/examples/forminput/FormInput.java    |  37 ++---
 .../wicket/examples/tree/AdvancedTreePage.java  |  23 +--
 19 files changed, 213 insertions(+), 722 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Check.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Check.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Check.java
index 83fa278..6f7ff26 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Check.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Check.java
@@ -24,7 +24,6 @@ import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.model.IModel;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.util.string.Strings;
 
 
@@ -195,25 +194,6 @@ public class Check<T> extends LabeledWebMarkupContainer implements IGenericCompo
 			tag.put("checked", "checked");
 		}
 
-		if (group.wantOnSelectionChangedNotifications())
-		{
-			// url that points to this components IOnChangeListener method
-			CharSequence url = group.urlForListener(new PageParameters());
-
-			Form<?> form = group.findParent(Form.class);
-			if (form != null)
-			{
-				tag.put("onclick", form.getJsForListenerUrl(url));
-			}
-			else
-			{
-				// NOTE: do not encode the url as that would give invalid JavaScript
-				tag.put("onclick", "window.location.href='" + url +
-					(url.toString().indexOf('?') > -1 ? "&" : "?") + group.getInputName() +
-					"=' + this.value;");
-			}
-		}
-
 		if (!isActionAuthorized(ENABLE) || !isEnabledInHierarchy() || !group.isEnabledInHierarchy())
 		{
 			tag.put(ATTR_DISABLED, ATTR_DISABLED);

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBox.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBox.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBox.java
index da8f049..f318060 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBox.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBox.java
@@ -18,11 +18,8 @@ package org.apache.wicket.markup.html.form;
 
 import java.util.Locale;
 
-import org.apache.wicket.IRequestListener;
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.model.IModel;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.util.convert.IConverter;
 
 /**
@@ -42,10 +39,6 @@ import org.apache.wicket.util.convert.IConverter;
  * 
  * </p>
  * <p>
- * You can can extend this class and override method wantOnSelectionChangedNotifications() to force
- * server roundtrips on each selection change.
- * </p>
- * <p>
  * A CheckBox always has a valid therefore values from methods
  * {@link FormComponent#setRequired(boolean)} and {@link FormComponent#isRequired()} are not taken
  * into account.
@@ -53,7 +46,7 @@ import org.apache.wicket.util.convert.IConverter;
  * 
  * @author Jonathan Locke
  */
-public class CheckBox extends FormComponent<Boolean> implements IRequestListener
+public class CheckBox extends FormComponent<Boolean>
 {
 	private static final long serialVersionUID = 1L;
 
@@ -77,96 +70,6 @@ public class CheckBox extends FormComponent<Boolean> implements IRequestListener
 	}
 
 	/**
-	 * @see org.apache.wicket.markup.html.form.IOnChangeListener#onSelectionChanged()
-	 */
-	@Override
-	public void onRequest()
-	{
-		Form<?> form = getForm();
-		if (form == null) {
-			convertInput();
-			updateModel();
-			onSelectionChanged(getModelObject());
-		} else {
-			form.onFormSubmitted(new IFormSubmitter()
-			{
-				@Override
-				public void onSubmit()
-				{
-					convertInput();
-					updateModel();
-					onSelectionChanged(getModelObject());
-				}
-				
-				@Override
-				public void onError()
-				{
-				}
-				
-				@Override
-				public void onAfterSubmit()
-				{
-				}
-				
-				@Override
-				public Form<?> getForm()
-				{
-					return CheckBox.this.getForm();
-				}
-				
-				@Override
-				public boolean getDefaultFormProcessing()
-				{
-					return false;
-				}
-			});
-		}
-	}
-
-	/**
-	 * Template method that can be overridden to be notified by value changes.
-	 * {@link #wantOnSelectionChangedNotifications()} has to be overriden to return {@value true} for
-	 * this method to being called.
-	 * <p>
-	 * This method does nothing by default.
-	 * 
-	 * @param newSelection
-	 *            The newly selected object of the backing model NOTE this is the same as you would
-	 *            get by calling getModelObject() if the new selection were current
-	 */
-	protected void onSelectionChanged(Boolean newSelection)
-	{
-	}
-
-	/**
-	 * Whether a request should be generated with each selection change, resulting in the
-	 * model being updated (of just this component) and {@link #onSelectionChanged(Object)}
-	 * being called. This method returns false by default.
-	 * <p>
-	 * Use an {@link AjaxFormComponentUpdatingBehavior} with <tt>change</tt> event,
-	 * if you want to use Ajax instead.
-	 * 
-	 * @return returns {@value false} by default, i.e. selection changes do not result in a request
-	 */
-	protected boolean wantOnSelectionChangedNotifications()
-	{
-		return false;
-	}
-
-	/**
-	 * @see org.apache.wicket.MarkupContainer#getStatelessHint()
-	 */
-	@Override
-	protected boolean getStatelessHint()
-	{
-		if (wantOnSelectionChangedNotifications())
-		{
-			return false;
-		}
-		return super.getStatelessHint();
-	}
-
-	/**
 	 * Processes the component tag.
 	 * 
 	 * @param tag
@@ -197,28 +100,6 @@ public class CheckBox extends FormComponent<Boolean> implements IRequestListener
 		// type="checkbox" value=""] will always submit as false
 		tag.remove("value");
 
-		// Should a roundtrip be made (have onSelectionChanged called) when the
-		// checkbox is clicked?
-		if (wantOnSelectionChangedNotifications())
-		{
-			CharSequence url = urlForListener(new PageParameters());
-
-			Form<?> form = findParent(Form.class);
-			if (form != null)
-			{
-				tag.put("onclick", form.getJsForListenerUrl(url));
-			}
-			else
-			{
-				// NOTE: do not encode the url as that would give invalid
-				// JavaScript
-				tag.put("onclick", "window.location.href='" + url +
-					(url.toString().indexOf('?') > -1 ? "&" : "?") + getInputName() +
-					"=' + this.checked;");
-			}
-
-		}
-
 		super.onComponentTag(tag);
 	}
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckGroup.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckGroup.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckGroup.java
index ead1823..e05b0d5 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckGroup.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckGroup.java
@@ -19,9 +19,7 @@ package org.apache.wicket.markup.html.form;
 import java.util.Collection;
 import java.util.List;
 
-import org.apache.wicket.IRequestListener;
 import org.apache.wicket.WicketRuntimeException;
-import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.model.IModel;
@@ -60,7 +58,7 @@ import org.slf4j.LoggerFactory;
  * @param <T>
  *            The model object type
  */
-public class CheckGroup<T> extends FormComponent<Collection<T>> implements IRequestListener
+public class CheckGroup<T> extends FormComponent<Collection<T>>
 {
 	private static final long serialVersionUID = 1L;
 
@@ -201,91 +199,4 @@ public class CheckGroup<T> extends FormComponent<Collection<T>> implements IRequ
 		tag.remove("disabled");
 		tag.remove("name");
 	}
-
-	/**
-	 * Called when a selection changes.
-	 */
-	@Override
-	public final void onRequest()
-	{
-		Form<?> form = getForm();
-		if (form == null) {
-			convertInput();
-			updateModel();
-			onSelectionChanged(getModelObject());
-		} else {
-			form.onFormSubmitted(new IFormSubmitter()
-			{
-				@Override
-				public void onSubmit()
-				{
-					convertInput();
-					updateModel();
-					onSelectionChanged(getModelObject());
-				}
-				
-				@Override
-				public void onError()
-				{
-				}
-				
-				@Override
-				public void onAfterSubmit()
-				{
-				}
-				
-				@Override
-				public Form<?> getForm()
-				{
-					return CheckGroup.this.getForm();
-				}
-				
-				@Override
-				public boolean getDefaultFormProcessing()
-				{
-					return false;
-				}
-			});
-		}
-	}
-
-	/**
-	 * Template method that can be overridden to be notified by value changes.
-	 * {@link #wantOnSelectionChangedNotifications()} has to be overriden to return {@value true} for
-	 * this method to being called.
-	 * <p>
-	 * This method does nothing by default.
-	 * 
-	 * @param newSelection
-	 *            The newly selected object of the backing model NOTE this is the same as you would
-	 *            get by calling getModelObject() if the new selection were current
-	 */
-	protected void onSelectionChanged(final Collection<T> newSelection)
-	{
-	}
-
-	/**
-	 * Whether a request should be generated with each selection change, resulting in the
-	 * model being updated (of just this component) and {@link #onSelectionChanged(Object)}
-	 * being called. This method returns false by default.
-	 * <p>
-	 * Use an {@link AjaxFormChoiceComponentUpdatingBehavior} with <tt>change</tt> event,
-	 * if you want to use Ajax instead.
-	 * 
-	 * @return returns {@value false} by default, i.e. selection changes do not result in a request
-	 */
-	protected boolean wantOnSelectionChangedNotifications()
-	{
-		return false;
-	}
-
-	@Override
-	protected boolean getStatelessHint()
-	{
-		if (wantOnSelectionChangedNotifications())
-		{
-			return false;
-		}
-		return super.getStatelessHint();
-	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/main/java/org/apache/wicket/markup/html/form/DropDownChoice.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/DropDownChoice.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/DropDownChoice.java
index cee8851..a0bd6c4 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/DropDownChoice.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/DropDownChoice.java
@@ -18,11 +18,8 @@ package org.apache.wicket.markup.html.form;
 
 import java.util.List;
 
-import org.apache.wicket.IRequestListener;
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.model.IModel;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 
 /**
@@ -52,11 +49,6 @@ import org.apache.wicket.request.mapper.parameter.PageParameters;
  * 
  * </p>
  * 
- * <p>
- * You can can extend this class and override method wantOnSelectionChangedNotifications() to force
- * server roundtrips on each selection change.
- * </p>
- * 
  * @author Jonathan Locke
  * @author Eelco Hillenius
  * @author Johan Compagner
@@ -64,7 +56,7 @@ import org.apache.wicket.request.mapper.parameter.PageParameters;
  * @param <T>
  *            The model object type
  */
-public class DropDownChoice<T> extends AbstractSingleSelectChoice<T> implements IRequestListener
+public class DropDownChoice<T> extends AbstractSingleSelectChoice<T>
 {
 	private static final long serialVersionUID = 1L;
 
@@ -204,53 +196,6 @@ public class DropDownChoice<T> extends AbstractSingleSelectChoice<T> implements
 	}
 
 	/**
-	 * Called when a selection changes.
-	 */
-	@Override
-	public final void onRequest()
-	{
-		Form<?> form = getForm();
-		if (form == null) {
-			convertInput();
-			updateModel();
-			onSelectionChanged(getModelObject());
-		} else {
-			form.getRootForm().onFormSubmitted(new IFormSubmitter()
-			{
-				@Override
-				public void onSubmit()
-				{
-					convertInput();
-					updateModel();
-					onSelectionChanged(getModelObject());
-				}
-				
-				@Override
-				public void onError()
-				{
-				}
-				
-				@Override
-				public void onAfterSubmit()
-				{
-				}
-				
-				@Override
-				public Form<?> getForm()
-				{
-					return DropDownChoice.this.getForm();
-				}
-				
-				@Override
-				public boolean getDefaultFormProcessing()
-				{
-					return false;
-				}
-			});
-		}
-	}
-
-	/**
 	 * Processes the component tag.
 	 * 
 	 * @param tag
@@ -262,68 +207,6 @@ public class DropDownChoice<T> extends AbstractSingleSelectChoice<T> implements
 	{
 		checkComponentTag(tag, "select");
 
-		// Should a roundtrip be made (have onSelectionChanged called) when the
-		// selection changed?
-		if (wantOnSelectionChangedNotifications())
-		{
-			CharSequence url = urlForListener(new PageParameters());
-
-			Form<?> form = findParent(Form.class);
-			if (form != null)
-			{
-				tag.put("onchange", form.getJsForListenerUrl(url.toString()));
-			}
-			else
-			{
-				tag.put("onchange", "window.location.href='" + url +
-					(url.toString().indexOf('?') > -1 ? "&" : "?") + getInputName() +
-					"=' + this.options[this.selectedIndex].value;");
-			}
-		}
-
 		super.onComponentTag(tag);
 	}
-
-	/**
-	 * Template method that can be overridden to be notified by value changes.
-	 * {@link #wantOnSelectionChangedNotifications()} has to be overriden to return {@value true} for
-	 * this method to being called.
-	 * <p>
-	 * This method does nothing by default.
-	 * 
-	 * @param newSelection
-	 *            The newly selected object of the backing model NOTE this is the same as you would
-	 *            get by calling getModelObject() if the new selection were current
-	 */
-	protected void onSelectionChanged(final T newSelection)
-	{
-	}
-
-	/**
-	 * Whether a request should be generated with each selection change, resulting in the
-	 * model being updated (of just this component) and {@link #onSelectionChanged(Object)}
-	 * being called. This method returns false by default.
-	 * <p>
-	 * Use an {@link AjaxFormComponentUpdatingBehavior} with <tt>change</tt> event,
-	 * if you want to use Ajax instead.
-	 * 
-	 * @return returns {@value false} by default, i.e. selection changes do not result in a request
-	 */
-	protected boolean wantOnSelectionChangedNotifications()
-	{
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	protected boolean getStatelessHint()
-	{
-		if (wantOnSelectionChangedNotifications())
-		{
-			return false;
-		}
-		return super.getStatelessHint();
-	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Radio.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Radio.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Radio.java
index 1c38c11..df26e56 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Radio.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/Radio.java
@@ -22,7 +22,6 @@ import org.apache.wicket.WicketRuntimeException;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.model.IModel;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
 
 /**
  * Component representing a single radio choice in a org.apache.wicket.markup.html.form.RadioGroup.
@@ -180,25 +179,6 @@ public class Radio<T> extends LabeledWebMarkupContainer implements IGenericCompo
 			tag.put("checked", "checked");
 		}
 
-		if (group.wantOnSelectionChangedNotifications())
-		{
-			// url that points to this components IOnChangeListener method
-			CharSequence url = group.urlForListener(new PageParameters());
-
-			Form<?> form = group.findParent(Form.class);
-			if (form != null)
-			{
-				tag.put("onclick", form.getJsForListenerUrl(url));
-			}
-			else
-			{
-				// NOTE: do not encode the url as that would give invalid JavaScript
-				tag.put("onclick", "window.location.href='" + url +
-					(url.toString().indexOf('?') > -1 ? "&" : "?") + group.getInputName() +
-					"=' + this.value;");
-			}
-		}
-
 		if (!isEnabledInHierarchy())
 		{
 			tag.put(ATTR_DISABLED, ATTR_DISABLED);

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java
index 13b8b33..3994204 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioChoice.java
@@ -19,12 +19,9 @@ package org.apache.wicket.markup.html.form;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.wicket.IRequestListener;
-import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.MarkupStream;
 import org.apache.wicket.model.IModel;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.settings.DebugSettings;
 import org.apache.wicket.util.convert.IConverter;
 import org.apache.wicket.util.lang.Args;
@@ -56,18 +53,13 @@ import org.apache.wicket.util.value.IValueMap;
  * 
  * </p>
  * 
- * <p>
- * You can extend this class and override method wantOnSelectionChangedNotifications() to force
- * server roundtrips on each selection change.
- * </p>
- * 
  * @author Jonathan Locke
  * @author Igor Vaynberg (ivaynberg)
  * 
  * @param <T>
  *            The model object type
  */
-public class RadioChoice<T> extends AbstractSingleSelectChoice<T> implements IRequestListener
+public class RadioChoice<T> extends AbstractSingleSelectChoice<T>
 {
 	private static final long serialVersionUID = 1L;
 
@@ -247,96 +239,6 @@ public class RadioChoice<T> extends AbstractSingleSelectChoice<T> implements IRe
 	}
 
 	/**
-	 * @see org.apache.wicket.markup.html.form.IOnChangeListener#onSelectionChanged()
-	 */
-	@Override
-	public void onRequest()
-	{
-		Form<?> form = getForm();
-		if (form == null) {
-			convertInput();
-			updateModel();
-			onSelectionChanged(getModelObject());
-		} else {
-			form.onFormSubmitted(new IFormSubmitter()
-			{
-				@Override
-				public void onSubmit()
-				{
-					convertInput();
-					updateModel();
-					onSelectionChanged(getModelObject());
-				}
-				
-				@Override
-				public void onError()
-				{
-				}
-				
-				@Override
-				public void onAfterSubmit()
-				{
-				}
-				
-				@Override
-				public Form<?> getForm()
-				{
-					return RadioChoice.this.getForm();
-				}
-				
-				@Override
-				public boolean getDefaultFormProcessing()
-				{
-					return false;
-				}
-			});
-		}
-	}
-
-	/**
-	 * Template method that can be overridden to be notified by value changes.
-	 * {@link #wantOnSelectionChangedNotifications()} has to be overriden to return {@value true} for
-	 * this method to being called.
-	 * <p>
-	 * This method does nothing by default.
-	 * 
-	 * @param newSelection
-	 *            The newly selected object of the backing model NOTE this is the same as you would
-	 *            get by calling getModelObject() if the new selection were current
-	 */
-	protected void onSelectionChanged(T newSelection)
-	{
-	}
-
-	/**
-	 * Whether a request should be generated with each selection change, resulting in the
-	 * model being updated (of just this component) and {@link #onSelectionChanged(Object)}
-	 * being called. This method returns false by default.
-	 * <p>
-	 * Use an {@link AjaxFormComponentUpdatingBehavior} with <tt>change</tt> event,
-	 * if you want to use Ajax instead.
-	 * 
-	 * @return returns {@value false} by default, i.e. selection changes do not result in a request
-	 */
-	protected boolean wantOnSelectionChangedNotifications()
-	{
-		return false;
-	}
-
-	/**
-	 * @see org.apache.wicket.MarkupContainer#getStatelessHint()
-	 */
-	@Override
-	protected boolean getStatelessHint()
-	{
-		if (wantOnSelectionChangedNotifications())
-		{
-			return false;
-		}
-		return super.getStatelessHint();
-	}
-
-	/**
 	 * @return Prefix to use before choice
 	 */
 	public String getPrefix()
@@ -561,32 +463,6 @@ public class RadioChoice<T> extends AbstractSingleSelectChoice<T> implements IRe
 				.append(Strings.escapeMarkup(idAttr))
 				.append('"');
 
-			// Should a roundtrip be made (have onSelectionChanged called)
-			// when the option is clicked?
-			if (wantOnSelectionChangedNotifications())
-			{
-				CharSequence url = urlForListener(new PageParameters());
-
-				Form<?> form = findParent(Form.class);
-				if (form != null)
-				{
-					buffer.append(" onclick=\"")
-						.append(form.getJsForListenerUrl(url))
-						.append(";\"");
-				}
-				else
-				{
-					// NOTE: do not encode the url as that would give
-					// invalid JavaScript
-					buffer.append(" onclick=\"window.location.href='")
-						.append(url)
-						.append((url.toString().indexOf('?') > -1 ? '&' : '?') + getInputName())
-						.append('=')
-						.append(Strings.escapeMarkup(id))
-						.append("';\"");
-				}
-			}
-
 			// Allows user to add attributes to the <input..> tag
 			{
 				IValueMap attrs = getAdditionalAttributes(index, choice);

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioGroup.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioGroup.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioGroup.java
index 51778a4..ac5ca4a 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioGroup.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/RadioGroup.java
@@ -16,9 +16,7 @@
  */
 package org.apache.wicket.markup.html.form;
 
-import org.apache.wicket.IRequestListener;
 import org.apache.wicket.WicketRuntimeException;
-import org.apache.wicket.ajax.form.AjaxFormChoiceComponentUpdatingBehavior;
 import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.model.IModel;
@@ -49,7 +47,7 @@ import org.apache.wicket.util.visit.IVisitor;
  * @param <T>
  *            The model object type
  */
-public class RadioGroup<T> extends FormComponent<T> implements IRequestListener
+public class RadioGroup<T> extends FormComponent<T>
 {
 	private static final long serialVersionUID = 1L;
 
@@ -73,34 +71,6 @@ public class RadioGroup<T> extends FormComponent<T> implements IRequestListener
 		setRenderBodyOnly(true);
 	}
 
-	/**
-	 * Whether a request should be generated with each selection change, resulting in the
-	 * model being updated (of just this component) and {@link #onSelectionChanged(Object)}
-	 * being called. This method returns false by default.
-	 * <p>
-	 * Use an {@link AjaxFormChoiceComponentUpdatingBehavior} with <tt>change</tt> event,
-	 * if you want to use Ajax instead.
-	 * 
-	 * @return returns {@value false} by default, i.e. selection changes do not result in a request
-	 */
-	protected boolean wantOnSelectionChangedNotifications()
-	{
-		return false;
-	}
-
-	/**
-	 * @see org.apache.wicket.MarkupContainer#getStatelessHint()
-	 */
-	@Override
-	protected boolean getStatelessHint()
-	{
-		if (wantOnSelectionChangedNotifications())
-		{
-			return false;
-		}
-		return super.getStatelessHint();
-	}
-
 	@Override
 	protected String getModelValue()
 	{
@@ -174,66 +144,4 @@ public class RadioGroup<T> extends FormComponent<T> implements IRequestListener
 		tag.remove("disabled");
 		tag.remove("name");
 	}
-
-	/**
-	 * Called when a selection changes.
-	 */
-	@Override
-	public final void onRequest()
-	{
-		Form<?> form = getForm();
-		if (form == null) {
-			convertInput();
-			updateModel();
-			onSelectionChanged(getModelObject());
-		} else {
-			form.onFormSubmitted(new IFormSubmitter()
-			{
-				@Override
-				public void onSubmit()
-				{
-					convertInput();
-					updateModel();
-					onSelectionChanged(getModelObject());
-				}
-				
-				@Override
-				public void onError()
-				{
-				}
-				
-				@Override
-				public void onAfterSubmit()
-				{
-				}
-				
-				@Override
-				public Form<?> getForm()
-				{
-					return RadioGroup.this.getForm();
-				}
-				
-				@Override
-				public boolean getDefaultFormProcessing()
-				{
-					return false;
-				}
-			});
-		}
-	}
-
-	/**
-	 * Template method that can be overridden to be notified by value changes.
-	 * {@link #wantOnSelectionChangedNotifications()} has to be overriden to return {@value true} for
-	 * this method to being called.
-	 * <p>
-	 * This method does nothing by default.
-	 * 
-	 * @param newSelection
-	 *            The newly selected object of the backing model NOTE this is the same as you would
-	 *            get by calling getModelObject() if the new selection were current
-	 */
-	protected void onSelectionChanged(final T newSelection)
-	{
-	}
 }

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/main/java/org/apache/wicket/markup/html/form/SelectionChangeBehavior.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/SelectionChangeBehavior.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/SelectionChangeBehavior.java
new file mode 100644
index 0000000..8943d12
--- /dev/null
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/SelectionChangeBehavior.java
@@ -0,0 +1,142 @@
+/*
+ * 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.markup.html.form;
+
+import org.apache.wicket.Component;
+import org.apache.wicket.IRequestListener;
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.ComponentTag;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+public class SelectionChangeBehavior extends Behavior implements IRequestListener
+{
+
+	private FormComponent<?> formComponent;
+
+	@Override
+	public boolean getStatelessHint(Component component)
+	{
+		return false;
+	}
+	
+	@Override
+	public void bind(Component component)
+	{
+		this.formComponent = (FormComponent<?>)component;
+		
+		formComponent.setRenderBodyOnly(false);
+	}
+
+	public FormComponent<?> getFormComponent()
+	{
+		return formComponent;
+	}
+	
+	@Override
+	public void onComponentTag(Component component, ComponentTag tag)
+	{
+		CharSequence url = component.urlForListener(this, new PageParameters());
+
+		String event = getJSEvent();
+		
+		String condition = String.format("if (event.target.name !== '%s') return; ", formComponent.getInputName());
+		
+		Form<?> form = component.findParent(Form.class);
+		if (form != null)
+		{
+			tag.put(event, condition + form.getJsForListenerUrl(url.toString()));
+		}
+		else
+		{
+			char separator = url.toString().indexOf('?') > -1 ? '&' : '?';
+				
+			tag.put(event,
+				condition + String.format("window.location.href='%s%s%s=' + %s;", url, separator, formComponent.getInputName(), getJSValue()));
+		}
+	}
+
+	
+	private String getJSEvent()
+	{
+		if (formComponent instanceof DropDownChoice) {
+			return "onchange";
+		} else {
+			return "onclick";
+		}
+	}
+
+	private String getJSValue()
+	{
+		if (formComponent instanceof DropDownChoice) {
+			return "this.options[this.selectedIndex].value";
+		} else if (formComponent instanceof CheckBox) {
+			return "this.checked";
+		} else {
+			return "event.target.value";
+		}
+	}
+
+	private void process() {
+		formComponent.convertInput();
+		formComponent.updateModel();
+		onSelectionChanged();
+	}
+	
+	protected void onSelectionChanged()
+	{
+	}
+
+	@Override
+	public final void onRequest()
+	{
+		Form<?> form = formComponent.findParent(Form.class);
+		if (form == null) {
+			process();
+		} else {
+			form.getRootForm().onFormSubmitted(new IFormSubmitter()
+			{
+				@Override
+				public void onSubmit()
+				{
+					process();
+				}
+				
+				@Override
+				public void onError()
+				{
+				}
+				
+				@Override
+				public void onAfterSubmit()
+				{
+				}
+				
+				@Override
+				public Form<?> getForm()
+				{
+					return formComponent.getForm();
+				}
+				
+				@Override
+				public boolean getDefaultFormProcessing()
+				{
+					return false;
+				}
+			});
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java b/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
index d7cdf4e..ec7f5aa 100644
--- a/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
+++ b/wicket-core/src/main/java/org/apache/wicket/util/tester/BaseWicketTester.java
@@ -60,6 +60,7 @@ import org.apache.wicket.ajax.markup.html.AjaxLink;
 import org.apache.wicket.ajax.markup.html.IAjaxLink;
 import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink;
 import org.apache.wicket.behavior.AbstractAjaxBehavior;
+import org.apache.wicket.behavior.Behavior;
 import org.apache.wicket.core.request.handler.BookmarkableListenerRequestHandler;
 import org.apache.wicket.core.request.handler.BookmarkablePageRequestHandler;
 import org.apache.wicket.core.request.handler.IPageProvider;
@@ -121,7 +122,6 @@ import org.apache.wicket.request.mapper.IRequestMapperDelegate;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
 import org.apache.wicket.request.resource.IResource;
 import org.apache.wicket.request.resource.ResourceReference;
-import org.apache.wicket.session.ISessionStore.UnboundListener;
 import org.apache.wicket.settings.ApplicationSettings;
 import org.apache.wicket.settings.RequestCycleSettings.RenderStrategy;
 import org.apache.wicket.util.lang.Args;
@@ -1138,6 +1138,29 @@ public class BaseWicketTester
 	}
 
 	/**
+	 * Simulates invoking an {@link IRequestListener} on a component. As opposed to the
+	 * {@link #executeListener(Component)} method, current request/response objects will be used
+	 * 
+	 * After the listener is invoked the page containing the component will be rendered
+	 * (with an optional redirect - depending on {@link RenderStrategy}).
+	 * 
+	 * @param component
+	 * @param listener
+	 */
+	public void invokeListener(Component component, final Behavior behavior)
+	{
+		Args.notNull(component, "component");
+		Args.notNull(behavior, "behavior");
+
+		// there are two ways to do this. RequestCycle could be forced to call the handler
+		// directly but constructing and parsing the URL increases the chance of triggering bugs
+		IRequestHandler handler = new ListenerRequestHandler(new PageAndComponentProvider(
+			component.getPage(), component), component.getBehaviorId(behavior));
+
+		processRequest(handler);
+	}
+
+	/**
 	 * Builds and processes a request suitable for executing an <code>AbstractAjaxBehavior</code>.
 	 * 
 	 * @param behavior

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/main/java/org/apache/wicket/util/tester/FormTester.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/util/tester/FormTester.java b/wicket-core/src/main/java/org/apache/wicket/util/tester/FormTester.java
index 8bb2760..31448d9 100644
--- a/wicket-core/src/main/java/org/apache/wicket/util/tester/FormTester.java
+++ b/wicket-core/src/main/java/org/apache/wicket/util/tester/FormTester.java
@@ -38,6 +38,7 @@ import org.apache.wicket.markup.html.form.IFormSubmittingComponent;
 import org.apache.wicket.markup.html.form.ListMultipleChoice;
 import org.apache.wicket.markup.html.form.Radio;
 import org.apache.wicket.markup.html.form.RadioGroup;
+import org.apache.wicket.markup.html.form.SelectionChangeBehavior;
 import org.apache.wicket.markup.html.form.upload.FileUploadField;
 import org.apache.wicket.markup.html.form.upload.MultiFileUploadField;
 import org.apache.wicket.protocol.http.mock.MockHttpServletRequest;
@@ -505,29 +506,9 @@ public class FormTester
 		ChoiceSelector choiceSelector = choiceSelectorFactory.create(component);
 		choiceSelector.doSelect(index);
 
-		try
-		{
-			Method wantOnSelectionChangedNotificationsMethod = component.getClass()
-				.getDeclaredMethod("wantOnSelectionChangedNotifications");
-
-			try
-			{
-				wantOnSelectionChangedNotificationsMethod.setAccessible(true);
-				boolean wantOnSelectionChangedNotifications = (Boolean)wantOnSelectionChangedNotificationsMethod.invoke(component);
-				if (wantOnSelectionChangedNotifications)
-				{
-					tester.invokeListener(component);
-				}
-			}
-			catch (final Exception x)
-			{
-				throw new RuntimeException(x);
-			}
-
-		}
-		catch (final NoSuchMethodException ignored)
-		{
-			// this form component has no auto page reload mechanism
+		List<SelectionChangeBehavior> behaviors = component.getBehaviors(SelectionChangeBehavior.class);
+		if (behaviors.isEmpty() == false) {
+			tester.invokeListener(component, behaviors.get(0));
 		}
 
 		return this;

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/test/java/org/apache/wicket/MockPageWithForm.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/MockPageWithForm.java b/wicket-core/src/test/java/org/apache/wicket/MockPageWithForm.java
index 75cdb92..4b8e706 100644
--- a/wicket-core/src/test/java/org/apache/wicket/MockPageWithForm.java
+++ b/wicket-core/src/test/java/org/apache/wicket/MockPageWithForm.java
@@ -22,6 +22,7 @@ import java.util.List;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.SelectionChangeBehavior;
 import org.apache.wicket.model.Model;
 
 
@@ -60,26 +61,14 @@ public class MockPageWithForm extends WebPage
 		List<String> list = new ArrayList<String>();
 		list.add("Select me");
 		MyForm form = new MyForm("form");
-		DropDownChoice<String> dropDown = new DropDownChoice<String>("dropdown",
-			new Model<String>(), list)
-		{
-			private static final long serialVersionUID = 1L;
-
+		DropDownChoice<String> dropDown = new DropDownChoice<String>("dropdown", new Model<String>(), list);
+		dropDown.add(new SelectionChangeBehavior() {
 			@Override
-			protected void onSelectionChanged(String newSelection)
+			protected void onSelectionChanged()
 			{
 				selected = true;
 			}
-
-			/**
-			 * @see org.apache.wicket.markup.html.form.DropDownChoice#wantOnSelectionChangedNotifications()
-			 */
-			@Override
-			protected boolean wantOnSelectionChangedNotifications()
-			{
-				return true;
-			}
-		};
+		});
 
 
 		form.add(dropDown);

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-core/src/test/java/org/apache/wicket/util/tester/FormTesterTest.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/test/java/org/apache/wicket/util/tester/FormTesterTest.java b/wicket-core/src/test/java/org/apache/wicket/util/tester/FormTesterTest.java
index 7500653..945e46e 100644
--- a/wicket-core/src/test/java/org/apache/wicket/util/tester/FormTesterTest.java
+++ b/wicket-core/src/test/java/org/apache/wicket/util/tester/FormTesterTest.java
@@ -28,6 +28,7 @@ import org.apache.wicket.markup.IMarkupResourceStreamProvider;
 import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.SelectionChangeBehavior;
 import org.apache.wicket.markup.html.form.upload.FileUpload;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.request.mapper.parameter.PageParameters;
@@ -264,20 +265,13 @@ public class FormTesterTest extends WicketTestCase
 				Form<Object> form = new Form<>("form");
 				add(form);
 				List<String> choices = Arrays.asList("opt 1", "opt 2");
-				form.add(new DropDownChoice<String>("selector", Model.of(""), choices)
-				{
+				form.add(new DropDownChoice<String>("selector", Model.of(""), choices).add(new SelectionChangeBehavior() {
 					@Override
-					protected boolean wantOnSelectionChangedNotifications()
+					protected void onSelectionChanged()
 					{
-						return true;
+						selection = (String)getFormComponent().getDefaultModelObject();
 					}
-
-					@Override
-					protected void onSelectionChanged(final String newSelection)
-					{
-						selection = newSelection;
-					}
-				});
+				}));
 			}
 
 			@Override

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-datetime/src/test/java/org/apache/wicket/extensions/yui/calendar/DatesPage1.java
----------------------------------------------------------------------
diff --git a/wicket-datetime/src/test/java/org/apache/wicket/extensions/yui/calendar/DatesPage1.java b/wicket-datetime/src/test/java/org/apache/wicket/extensions/yui/calendar/DatesPage1.java
index da0d26d..43f4067 100644
--- a/wicket-datetime/src/test/java/org/apache/wicket/extensions/yui/calendar/DatesPage1.java
+++ b/wicket-datetime/src/test/java/org/apache/wicket/extensions/yui/calendar/DatesPage1.java
@@ -31,6 +31,7 @@ import org.apache.wicket.markup.html.WebPage;
 import org.apache.wicket.markup.html.form.ChoiceRenderer;
 import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.SelectionChangeBehavior;
 import org.apache.wicket.markup.html.link.Link;
 import org.apache.wicket.markup.html.panel.FeedbackPanel;
 import org.apache.wicket.model.IModel;
@@ -109,6 +110,8 @@ public class DatesPage1 extends WebPage
 			});
 			setChoiceRenderer(new LocaleChoiceRenderer());
 			setDefaultModel(new PropertyModel<>(DatesPage1.this, "selectedLocale"));
+			
+			add(new SelectionChangeBehavior());
 		}
 
 		@Override
@@ -116,23 +119,6 @@ public class DatesPage1 extends WebPage
 		{
 			return super.getModelValue();
 		}
-
-		/**
-		 * @see org.apache.wicket.markup.html.form.DropDownChoice#onSelectionChanged(java.lang.Object)
-		 */
-		@Override
-		public void onSelectionChanged(Locale newSelection)
-		{
-		}
-
-		/**
-		 * @see org.apache.wicket.markup.html.form.DropDownChoice#wantOnSelectionChangedNotifications()
-		 */
-		@Override
-		protected boolean wantOnSelectionChangedNotifications()
-		{
-			return true;
-		}
 	}
 
 	private static final Locale LOCALE_EN = new Locale("en");

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-datetime/src/test/java/org/apache/wicket/extensions/yui/calendar/DatesPage1_ExpectedResult.html
----------------------------------------------------------------------
diff --git a/wicket-datetime/src/test/java/org/apache/wicket/extensions/yui/calendar/DatesPage1_ExpectedResult.html b/wicket-datetime/src/test/java/org/apache/wicket/extensions/yui/calendar/DatesPage1_ExpectedResult.html
index d365128..9bc873a 100644
--- a/wicket-datetime/src/test/java/org/apache/wicket/extensions/yui/calendar/DatesPage1_ExpectedResult.html
+++ b/wicket-datetime/src/test/java/org/apache/wicket/extensions/yui/calendar/DatesPage1_ExpectedResult.html
@@ -106,7 +106,7 @@ Wicket.Event.publish(Wicket.Event.Topic.AJAX_HANDLERS_BOUND);
 </head>
 <body>
 <form wicket:id="localeForm" id="localeForm2" method="post" action="./org.apache.wicket.extensions.yui.calendar.DatesPage1?0-1.-localeForm">
-<p><select wicket:id="localeSelect" onchange="var f = document.getElementById(&#039;localeForm2&#039;); f.action=&#039;./org.apache.wicket.extensions.yui.calendar.DatesPage1?0-1.-localeForm-localeSelect&#039;;f.submit();" name="localeSelect">
+<p><select wicket:id="localeSelect" name="localeSelect" onchange="if (event.target.name !== &#039;localeSelect&#039;) return; var f = document.getElementById(&#039;localeForm2&#039;); f.action=&#039;./org.apache.wicket.extensions.yui.calendar.DatesPage1?0-1.0-localeForm-localeSelect&#039;;f.submit();">
 <option value="0">cinese (Cina) (Chinese (China))</option>
 <option value="1">cinese (Cina) (Chinese (China))</option>
 <option value="2">cinese (Cina) (Chinese (China))</option>

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckGroupPage.html
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckGroupPage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckGroupPage.html
index b10bf3f..260a2c7 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckGroupPage.html
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckGroupPage.html
@@ -14,13 +14,11 @@
 	A CheckBoxGroup and CheckBoxComponnet components let users select multiple values from a group of checkboxes. These components are more flexible then the CheckBoxMultipleChoice component in that individual checkboxes are full components, unlike with CheckBoxMultipleChoice, and thus can be used anywhere in the markup.
 	</p>
 	<p>
-	 <form wicket:id="form">
 		<span wicket:id="group">
 			<table style="border: 2px dotted #fc0; width: 400px; padding: 5px;">
 			 <tr>
 			  <td valign="top">Select persons</td>
 			  <td>
-				  <input type="checkbox" wicket:id="groupselector">check/uncheck all</input><br/>
 				  <table cellspacing="0" cellpadding="2">
 					<tr>
 						<td><b>Select</b></td>
@@ -44,7 +42,6 @@
 			 </tr>
 			</table>
 		</span>
-	 </form>
 	 <span wicket:id="feedback">feedbackmessages will be put here</span>
 	</p>
     <span wicket:id="explainPanel">panel contents come here</span>

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckGroupPage.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckGroupPage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckGroupPage.java
index 738920e..12c99fb 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckGroupPage.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckGroupPage.java
@@ -24,6 +24,7 @@ import org.apache.wicket.markup.html.form.Check;
 import org.apache.wicket.markup.html.form.CheckGroup;
 import org.apache.wicket.markup.html.form.CheckGroupSelector;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.SelectionChangeBehavior;
 import org.apache.wicket.markup.html.list.ListItem;
 import org.apache.wicket.markup.html.list.ListView;
 import org.apache.wicket.markup.html.panel.FeedbackPanel;
@@ -43,18 +44,9 @@ public class CheckGroupPage extends WicketExamplePage
 	public CheckGroupPage()
 	{
 		final CheckGroup<Person> group = new CheckGroup<>("group", new ArrayList<Person>());
-		Form<Void> form = new Form<Void>("form")
-		{
-			@Override
-			protected void onSubmit()
-			{
-				info("selected person(s): " + group.getDefaultModelObjectAsString());
-			}
-		};
+		group.add(new SelectionChangeBehavior());
 
-		add(form);
-		form.add(group);
-		group.add(new CheckGroupSelector("groupselector"));
+		add(group);
 		ListView<Person> persons = new ListView<Person>("persons",
 			ComponentReferenceApplication.getPersons())
 		{

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-examples/src/main/java/org/apache/wicket/examples/dates/DatesPage.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/dates/DatesPage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/dates/DatesPage.java
index 73d9b44..eaaaed2 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/dates/DatesPage.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/dates/DatesPage.java
@@ -34,6 +34,7 @@ import org.apache.wicket.extensions.yui.calendar.TimeField;
 import org.apache.wicket.markup.html.form.ChoiceRenderer;
 import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.SelectionChangeBehavior;
 import org.apache.wicket.markup.html.link.Link;
 import org.apache.wicket.markup.html.panel.FeedbackPanel;
 import org.apache.wicket.model.IModel;
@@ -100,17 +101,8 @@ public class DatesPage extends WicketExamplePage
 			});
 			setChoiceRenderer(new LocaleChoiceRenderer());
 			setDefaultModel(new PropertyModel<>(DatesPage.this, "selectedLocale"));
-		}
-
-		@Override
-		public void onSelectionChanged(Locale newSelection)
-		{
-		}
-
-		@Override
-		protected boolean wantOnSelectionChangedNotifications()
-		{
-			return true;
+			
+			add(new SelectionChangeBehavior());
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-examples/src/main/java/org/apache/wicket/examples/forminput/FormInput.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/forminput/FormInput.java b/wicket-examples/src/main/java/org/apache/wicket/examples/forminput/FormInput.java
index 8e3fb4b..ecc3414 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/forminput/FormInput.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/forminput/FormInput.java
@@ -35,6 +35,7 @@ import org.apache.wicket.markup.html.form.ListMultipleChoice;
 import org.apache.wicket.markup.html.form.Radio;
 import org.apache.wicket.markup.html.form.RadioChoice;
 import org.apache.wicket.markup.html.form.RadioGroup;
+import org.apache.wicket.markup.html.form.SelectionChangeBehavior;
 import org.apache.wicket.markup.html.form.SimpleFormComponentLabel;
 import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.markup.html.link.Link;
@@ -248,29 +249,21 @@ public class FormInput extends WicketExamplePage
 			// set the model that gets the current locale, and that is used for
 			// updating the current locale to property 'locale' of FormInput
 			setModel(new PropertyModel<>(FormInput.this, "locale"));
-		}
-
-		@Override
-		public void onSelectionChanged(Locale newSelection)
-		{
-			// note that we don't have to do anything here, as our property
-			// model already calls FormInput.setLocale when the model is
-			// updated
-
-			// force re-render by setting the page to render to the bookmarkable
-			// instance, so that the page will be rendered from scratch,
-			// re-evaluating the input patterns etc
-			setResponsePage(FormInput.class);
-		}
+			
+			add(new SelectionChangeBehavior() {
+				@Override
+				protected void onSelectionChanged()
+				{
+					// note that we don't have to do anything here, as our property
+					// model already calls FormInput.setLocale when the model is
+					// updated
 
-		/**
-		 * @see org.apache.wicket.markup.html.form.DropDownChoice#wantOnSelectionChangedNotifications()
-		 */
-		@Override
-		protected boolean wantOnSelectionChangedNotifications()
-		{
-			// we want round-trips when a the user selects another item
-			return true;
+					// force re-render by setting the page to render to the bookmarkable
+					// instance, so that the page will be rendered from scratch,
+					// re-evaluating the input patterns etc
+					setResponsePage(FormInput.class);
+				}
+			});
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/wicket/blob/e2af7563/wicket-examples/src/main/java/org/apache/wicket/examples/tree/AdvancedTreePage.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/tree/AdvancedTreePage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/tree/AdvancedTreePage.java
index b33b075..4522885 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/tree/AdvancedTreePage.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/tree/AdvancedTreePage.java
@@ -43,6 +43,7 @@ import org.apache.wicket.markup.html.form.Button;
 import org.apache.wicket.markup.html.form.ChoiceRenderer;
 import org.apache.wicket.markup.html.form.DropDownChoice;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.form.SelectionChangeBehavior;
 import org.apache.wicket.markup.html.link.Link;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.PropertyModel;
@@ -97,28 +98,10 @@ public abstract class AdvancedTreePage extends AbstractTreePage
 		form.add(tree);
 
 		form.add(new DropDownChoice<Content>("content", new PropertyModel<>(this, "content"),
-			initContents(), new ChoiceRenderer<>("class.simpleName"))
-		{
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			protected boolean wantOnSelectionChangedNotifications()
-			{
-				return true;
-			}
-		});
+			initContents(), new ChoiceRenderer<>("class.simpleName")).add(new SelectionChangeBehavior()));
 
 		form.add(new DropDownChoice<Behavior>("theme", new PropertyModel<>(this, "theme"),
-			initThemes(), new ChoiceRenderer<>("class.simpleName"))
-		{
-			private static final long serialVersionUID = 1L;
-
-			@Override
-			protected boolean wantOnSelectionChangedNotifications()
-			{
-				return true;
-			}
-		});
+			initThemes(), new ChoiceRenderer<>("class.simpleName")).add(new SelectionChangeBehavior()));
 
 		form.add(new Link<Void>("expandAll")
 		{