Tuesday, October 25, 2011

Wicket and AjaxFormComponentUpdatingBehavior


If you have a form component in wicket with some components and you want to change using ajax some things in that form before submit (when you click or edit on one of the components), then you have to use AjaxFormComponentUpdatingBehavior.

This is  a behavior that updates the hosting FormComponent via ajax when an event it is attached to is triggered.
private AjaxFormComponentUpdatingBehavior createAjax( ) {
     return new AjaxFormComponentUpdatingBehavior("onchange") {
        @Override
        protected void onUpdate(AjaxRequestTarget target) {
          // do your task 
        }
     };
} 

The key is that your component must be a FormComponent, otherwise the event won't be triggered. Simple components like CheckBox, TextField, DropDownChoice are all FormComponents. But if you have a custom component create by yourself from more components  or even one like DateField, DateTextField , you will have to add a behavior to every sub-component to make your form update through ajax.

For example, a DateTimeField must respond if we change something inside its text field or if we change hours or minutes through its internal text fields, or AM/PM through its internal drop down choice. To access internal components from a wicket component we can use a get method with the markup-id as parameter if no methods are offered by that class. Inside DateTimeField we can override a newDateTextField method to add our behavior. But for the other elements we do not have similar methods, so we must look for the name of the markups in the html or java source code:
DateTimeField txtTime = new DateTimeField("txtTime", generalModel) {
     @Override
     protected DateTextField newDateTextField(String id,  PropertyModel dateFieldModel) {
        DateTextField f = super.newDateTextField(id, dateFieldModel);                  
        f.add(createAjax());               
        return f;
     }
}; 
// add ajax update behavior on hours and minutes textfields
txtTime.get("hours").add(createAjax());
txtTime.get("minutes").add(createAjax());


No comments: