BaseWicketTester's simulated AJAX form submissions don't include Radio values
-----------------------------------------------------------------------------
Key: WICKET-1451
URL: https://issues.apache.org/jira/browse/WICKET-1451
Project: Wicket
Issue Type: Bug
Reporter: David Shepherdson
When submitting a form by AJAX, the BaseWicketTester goes through all the form
components to make sure their values are stored in the request. However,
because Radios are not instances of FormComponent, and because the code skips
RadioGroups, the values for radio buttons are not stored in the request. This
is particularly a problem if the form contains radio buttons marked as
required, because in that case validation will fail and the onSubmit() method
will not be called.
The problem lies in BaseWicketTester.submitAjaxFormSubmitBehavior(). If the
visitor in this method were changed so that, instead of skipping RadioGroups,
it instead did something like the constructor of FormTester does (see
WICKET-1411) to extract the actual value for the group and set that in the
request, the problem would be prevented.
For anyone else affected by this issue, we're working around it by overriding
the clickLink(String, boolean) method (since submitAjaxFormSubmitBehavior() is
private) in a subclass of WicketTester like this:
@Override
public void clickLink(String path, boolean isAjax) {
// Workaround for bug in BaseWicketTester: doexn't cope with
RadioGroups properly.
Component linkComponent =
getComponentFromLastRenderedPage(path);
if (linkComponent instanceof AjaxSubmitLink) {
// Code borrowed from BaseWicketTester.
AjaxSubmitLink link = (AjaxSubmitLink)linkComponent;
// We cycle through the attached behaviors and select
the
// LAST matching behavior as the one we handle.
List behaviors = link.getBehaviors();
AjaxFormSubmitBehavior behaviour = null;
for (Iterator iter = behaviors.iterator();
iter.hasNext();)
{
Object behavior = iter.next();
if (behavior instanceof AjaxFormSubmitBehavior)
{
AjaxFormSubmitBehavior submitBehavior =
(AjaxFormSubmitBehavior)behavior;
behaviour = submitBehavior;
}
}
if (behaviour != null) {
// More code borrowed from BaseWicketTester.
Form form = null;
try {
Field formField =
AjaxFormSubmitBehavior.class.getDeclaredField("form");
formField.setAccessible(true);
form = (Form)formField.get(behaviour);
} catch (Exception e) {
s_log.error("Caught exception in
workaround for BaseWicketTester bug.", e);
}
if (form != null) {
form.visitFormComponents(new
FormComponent.AbstractVisitor()
{
public void
onFormComponent(FormComponent formComponent)
{
if (formComponent
instanceof RadioGroup) {
final String
name = formComponent.getInputName();
final String value =
formComponent.getValue();
Object choiceValue =
formComponent.visitChildren(Radio.class, new IVisitor()
{
public Object
component(Component component)
{
// O-P Preserve
old escaping value, then turn escaping off
// so that
values aren't escaped unnecessarily.
@SuppressWarnings("hiding")
boolean
oldEscaping = component.getEscapeModelStrings();
component.setEscapeModelStrings(false);
Radio radio =
(Radio)component;
String
radioValue = radio.getValue();
// O-P Restore
the previous escaping setting.
component.setEscapeModelStrings(oldEscaping);
if
(radio.getModelObject().toString().equals(value))
{
return
radioValue;
}
return
CONTINUE_TRAVERSAL;
}
});
if (choiceValue !=
null) {
Map
requestParams = getParametersForNextRequest();
if
(requestParams.get(name) == null) {
requestParams.put(name, (String) choiceValue);
}
}
}
}
});
}
}
}
super.clickLink(path, isAjax);
}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.