Wicket Ajax Radio

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

  • Point 1
  • Point 2
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

Output

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 :

  1. AjaxRadio : This class is pretty simple it simple adds Wicket Radio and AjaxEventBehaior to each Radio
  2. 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

8 thoughts on “Wicket Ajax Radio

  1. Great work! Could you please allow to use this “AjaxRadio” class in commercial project?
    I am so confused that wicket does not have ajax radio button shipped with framework. Maby your implementation should be included in wicket?

  2. And thank you for posting it to github. But license really needed. The best choise – completele free to use and modify 😉

  3. Super, but I’m new in Wicket and struggle with setting the initial value and reading the results afterwards. Can you add that to this sample? Would be very nice! Thanks

Leave a reply to timaar Cancel reply