Wicket provides couple of built-in ajax enabled components for example AjaxButton, AjaxLink, and most importantly AjaxCheckBox and astonishingly there is no AjaxRadio,
Potential Reasons for no built-in ajax enabled Radio Component
Never mind, the beauty of Wicket is you can do anything in Wicket which can be done in JAVA
So lets create that missing component, Here is how that component would work
I would be using the following built-in components from Wicket core libraray:
- Radio (To render HTML Radio)
- RadioGroup (Radios don’t exist alone, every Radio is bound to a group, RadioGroup will hold the current selection)
- AjaxEventBehavior (onClick behavior is bound to each individual Radio )
- Form (To post the current status of Radio, i.e, which one is currently selected)
- Listview (repeatedly display all the Radio, this is going to be dynamaic )
I am going to create two classes for this component :
- AjaxRadio : This class is pretty simple it simple adds Wicket Radio and AjaxEventBehaior to each Radio
- AjaxRadioPanel : This is the main component.
AjaxRadio
AjaxRadio is extending Radio (Wicket core component) and adding onclick ajax behavior, this event will submit the current status of the Radio component to Server whenever the even occurs (onClick in this case)
public abstract class AjaxRadio extends Radio {
private static final long serialVersionUID = 1L;
public abstract void onAjaxEvent(AjaxRequestTarget target);
public AjaxRadio(String id, IModel model) {
super(id, model);
addAjaxBehavior();
setOutputMarkupId(true);
}
private void addAjaxBehavior() {
add(new AjaxEventBehavior("onclick") {
private static final long serialVersionUID = 1L;
protected void onEvent(final AjaxRequestTarget target) {
RadioGroup radioGroup = getEnclosingRadioGroup();
radioGroup.processInput();
onAjaxEvent(target);
}
protected final CharSequence getEventHandler() {
return generateCallbackScript(new AppendingStringBuffer("wicketAjaxPost('")
.append(getCallbackUrl())
.append("', wicketSerialize(Wicket.$('")
.append(AjaxRadio.this.getMarkupId())
.append("'))"));
}
});
}
private RadioGroup getEnclosingRadioGroup() {
RadioGroup group = (RadioGroup) findParent(RadioGroup.class);
if (group == null) {
throw new WicketRuntimeException("Radio component ["
+ getPath()
+ "] cannot find its parent RadioGroup. All Radio components must be a child of or below in the hierarchy of a RadioGroup component.");
}
return group;
}
}
AjaxRadioPanel
The main job of this class is to repeatedly add the AjaxRadio component, and provide a callback if the Radio is update, so that client can do some operation
public abstract class AjaxRadioPanel extends Panel {
private static final long serialVersionUID = 1L;
protected abstract void onRadioSelect(AjaxRequestTarget target, T newSelection);
public AjaxRadioPanel(String id, List items, String propertyExpression) {
this(id, items, null, propertyExpression);
}
public AjaxRadioPanel(String id, List items, T currentSelection, String labelPropertyExpression) {
super(id);
add(buildForm(items, currentSelection, labelPropertyExpression));
}
private Form buildForm(List items, T currentSelection, String labelPropertyExpression) {
Form form = new Form("form");
RadioGroup group = new RadioGroup("radioGroup", new Model(currentSelection));
group.add(newRadios(group, items, labelPropertyExpression));
form.add(group);
return form;
}
private Component newRadios(final RadioGroup group, List items, final String labelPropertyExpression) {
return new ListView("radioButtons", items) {
private static final long serialVersionUID = 1L;
protected void populateItem(ListItem item) {
item.add(newAjaxRadioCell(group, item));
item.add(new Label("label", new PropertyModel(item.getModel(), labelPropertyExpression)));
}
};
}
private AjaxRadio newAjaxRadioCell(final RadioGroup group, ListItem item) {
return new AjaxRadio("radio", item.getModel()) {
private static final long serialVersionUID = 1L;
@Override
public void onAjaxEvent(AjaxRequestTarget target) {
onRadioSelect(target, group.getModelObject());
}
};
}
}
How to Use this component
Simply add AjaxRadioPanel to your container
add(new AjaxRadioPanel(RADIO_PANEL_ID, getPersons(), "name") {
private static final long serialVersionUID = 1L;
@Override
protected void onRadioSelect(AjaxRequestTarget target, ValueMap newSelection) {
info("You have selected " + newSelection.getString("name"));
target.addComponent(feedbackPanel);
}
});
TODO : Update more…
Get the source code from Git Hub