

In addition to specific components, Wicket offers also a set of built in AJAX behaviors that can be used to easily add AJAX functionalities to existing components. As we will see in this paragraph AJAX behaviors can be used also to ajaxify components that weren't initially designed to work with this technology. All the following behaviors are inside package @org.apache.wicket.ajax@. 

h3. AjaxEventBehavior

AjaxEventBehavior allows to handle a JavaScript event (like click, change, etc...) on server side via AJAX. Its constructor takes in input the name of the event that must be handled. Every time this event is fired for a given component on client side, the callback method @onEvent(AjaxRequestTarget target)@ is executed. onEvent is abstract, hence we must implement it to tell @AjaxEventBehavior@ what to do when the specified event occurs.

In project @AjaxEventBehaviorExample@ we used this behavior to build a “clickable” Label component that counts the number of clicks. Here is the code from the home page of the project:

*HTML:*
{code:html}
<body>
  <div wicket:id="clickCounterLabel"></div>
  User has clicked <span wicket:id="clickCounter"></span> time/s on the label above.
</body>
{code}

*Java Code:*
{code}
public class HomePage extends WebPage {
   public HomePage(final PageParameters parameters) {
      super(parameters);
   
      final ClickCounterLabel clickCounterLabel = 
         new ClickCounterLabel("clickCounterLabel", "Click on me!");
      final Label clickCounter =
         new Label("clickCounter", new PropertyModel(clickCounterLabel, "clickCounter"));
      
      
      clickCounterLabel.setOutputMarkupId(true);
      clickCounterLabel.add(new AjaxEventBehavior("click"){

         @Override
         protected void onEvent(AjaxRequestTarget target) {
            clickCounterLabel.clickCounter++;
            target.add(clickCounter);
         }         
      });
      
      add(clickCounterLabel);
      add(clickCounter.setOutputMarkupId(true));      
    }
}

class ClickCounterLabel extends Label{
   public int clickCounter;   

   public ClickCounterLabel(String id) {
      super(id);
   }

   public ClickCounterLabel(String id, IModel<?> model) {
      super(id, model);
   }

   public ClickCounterLabel(String id, String label) {
      super(id, label);      
   }
}
{code}

In the code above we have declared a custom label class named @ClickCounterLabel@ that exposes a public integer field called clickCounter. Then, in the home page we have attached a @AjaxEventBehavior@ to our custom label to increment clickCounter every time it receives a click event.

The number of clicks is displayed with another standard label named @clickCounter@.

h3. AjaxFormSubmitBehavior

This behavior allows to send a form via AJAX when the component it is attached to receives the specified event. The component doesn't need to be inside the form if we use the constructor version that, in addition to the name of the event, takes in input also the target form:

{code}
Form form = new Form("form");		
Button submitButton = new Button("submitButton");
//submit form when button is clicked		
submitButton.add(new AjaxFormSubmitBehavior(form, "click"){});
add(form);
add(submitButton);
{code}

{note}
@AjaxFormSubmitBehavior@ does not prevent JavaScript default event handling. For @<input type="submit">@ you'll have to call @AjaxRequestAttributes#setPreventDefault(true)@ to prevent the form from being submitted twice.
{note}

h3. AjaxFormComponentUpdatingBehavior

This behavior updates the model of the form component it is attached to when a given event occurs. The standard form submitting process is skipped and the behavior validates only its form component. 

The behavior doesn't work with radio buttons and checkboxes. For these kinds of components we must use @AjaxFormChoiceComponentUpdatingBehavior@:

{code}
Form form = new Form("form");		
TextField textField = new TextField("textField", Model.of(""));
//update the model of the text field each time event "change" occurs
textField.add(new AjaxFormComponentUpdatingBehavior("change"){
	@Override
	protected void onUpdate(AjaxRequestTarget target) {
		//...				
	}
});
add(form.add(textField));
{code}

h3. AbstractAjaxTimerBehavior

@AbstractAjaxTimerBehavior@ executes callback method @onTimer(AjaxRequestTarget target)@ at a specified interval. The behavior can be stopped and restarted at a later time with methods @stop(AjaxRequestTarget target)@ and @restart(AjaxRequestTarget target)@:

{code}
Label dynamicLabel = new Label("dynamicLabel");
//trigger an AJAX request every three seconds		
dynamicLabel.add(new AbstractAjaxTimerBehavior(Duration.seconds(3)) {			
	@Override
	protected void onTimer(AjaxRequestTarget target) {
		//...				
	}
});
add(dynamicLabel);
{code}

{note}
As side effect AJAX components and behaviors make their hosting page stateful. As a consequence they are unfit for those pages that must stay stateless. Project WicketStuff provides a module with a stateless version of the most common AJAX components and behaviors. You can find more informations on this module in Appendix B. 
{note}
