Cas d'utilisation d'un évènement avec Ajax


Dans cet article, nous allons reprendre l'exemple fait avec ZenContact dans l'article précédent en ajoutant cette fois ci un peu d'Ajax dans notre application.

Dans l'exemple, nous avions une page composée d'un SearchPanel, et d'un ListContactsPanel :

SearchPanel

Le SearchPanel contient un formulaire qui, à la soumission, envoie un évènement capturé par le ListContactsPanel.

Nous allons ici modifier le SearchPanel pour que la soumission du formulaire se fasse en Ajax. Ensuite, nous allons permettre au ListContactsPanel d'être modifié sur la page au retour de l'appel Ajax. Pour cela, il va falloir passer l'objet AjaxRequestTarget au ListContactsPanel.

1. Tout d'abord, modifions le formulaire du SearchPanel pour que la soumission se fasse en Ajax :

private class SearchForm extends Form<String> {
 
	private TextField<String> searchString;
 
	public SearchForm(String id) {
		super(id);
		searchString = new TextField<String>("searchString", new Model<String>(""));
		add(searchString);
		add(new AjaxButton("formSubmit") {
 
			@Override
			protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
				send(getPage(), Broadcast.BREADTH, new SearchEvent(searchString.getValue(), target));
			}
 
		});
	}
}

2. Notre SearchEvent encapsule maintenant un objet de type AjaxRequestTarget.

L'objectif est de permettre au composant qui récupère l'event d'utiliser cet objet AjaxRequestTarget. Vous pouvez vous référer à l'article concernant l'Ajax avec Wicket pour plus d'informations.

public class SearchEvent {
 
	private final AjaxRequestTarget target;
	private final String value;
 
	public SearchEvent(String value, AjaxRequestTarget target) {
		this.value = value;
		this.target = target;
	}
 
	public String getValue() {
		return value;
	}
 
	public AjaxRequestTarget getTarget() {
		return target;
	}
 
}

3. onEvent

Finalement, à la réception de l'événement, dans le ListContactsPanel, nous ajoutons dans la target, notre composant. Ceci va pousser wicket à remplacer le panel précédent directement dans le DOM, par le nouveau panel.

@Override
public void onEvent(IEvent<?> event) {
	if (event.getPayload() instanceof SearchEvent) {
		SearchEvent searchEvent = (SearchEvent) event.getPayload();
		searchString = searchEvent.getValue();
		searchEvent.getTarget().add(this);
	}
}

N'hésitez pas à comparer l'implémentation avec celle du précédent article.

Remarque

Nous n'étions pas obligés de passer l'objet AjaxRequestTarget dans le SearchEvent. En effet, depuis la version 1.5 de Wicket, à chaque fois qu'une Réponse Ajax est créée, un événement custom est émis. Il est alors possible de le capturer de la même façon dans la méthode onEvent :

@Override
	public void onEvent(IEvent<?> event) {
		if (event.getPayload() instanceof SearchEvent) {
			//Dans un premier temps on modifier le composant pour prendre le contexte de l'événement
			SearchEvent searchEvent = (SearchEvent) event.getPayload();
			searchString = searchEvent.getValue();
		}
		if (event.getPayload() instanceof AjaxRequestTarget) {
			//Dans un second temps, nous ajoutons le Panel à la target
			((AjaxRequestTarget)event.getPayload()).add(this);
		}
	}

L'avantage de cette méthode est qu'on est plus obligés de passer L'AjaxRequestTarget. Le SearchEvent se contente donc de porter le contexte de l'événement. Par contre, ça impose au ListContactsPanel de deviner que l’événement émis est de type Ajax. C'est pourquoi dans beaucoup de cas, on passera la target directement dans l'event.