Ce post à pour but de vous montrer à quel point il est simple de faire de l’Ajax avec Wicket…
Nous allons aussi voir comment accéder à nos pages de façon un petit peu plus élégante.
Dans votre projet “cleanhtml”, créez une nouvelle classe héritant de [WebPage] nommée [AjaxHomePage] dans le même package que la classe [HomePage] (c'est à dire [com.noocodecommit.wicket.cleanhtml.wicket.pages]).
Voici le code source:
package com.noocodecommit.wicket.cleanhtml.wicket.pages; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.TextArea; import org.apache.wicket.model.PropertyModel; public class AjaxHomePage extends WebPage { public AjaxHomePage() { add(new CleanHtmlForm("formCleanHtml")); } class CleanHtmlForm extends Form { private String htmlCode = ""; private WebMarkupContainer panelCodeHtml; public CleanHtmlForm(String id) { super(id); panelCodeHtml = new WebMarkupContainer("panelCodeHtml"); IModel model = new PropertyModel(this, "htmlCode"); panelCodeHtml.add(new TextArea("txtCleanHtml", model)); panelCodeHtml.add(new Label("lblCleanHtml", model).setEscapeModelStrings(false)); add(panelCodeHtml); add(new AjaxButton("btnCompute") { @Override protected void onSubmit(AjaxRequestTarget target, Form form) { setHtmlCode(htmlCode.replaceAll("&", "&")); setHtmlCode(htmlCode.replaceAll("<", "<")); setHtmlCode(htmlCode.replaceAll(">", ">")); target.addComponent(panelCodeHtml); } }); } public String getHtmlCode() { return htmlCode; } public void setHtmlCode(String htmlCode) { this.htmlCode = htmlCode; } } }
Créez aussi la page HTML qui lui est associé:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>Clean Html</title> </head> <body> <form wicket:id="formCleanHtml"> <div wicket:id="panelCodeHtml"> <textarea rows="20" cols="50" wicket:id="txtCleanHtml"></textarea> <pre><code class="html" wicket:id="lblCleanHtml">[lblCleanHtml]</code></pre> </div> <button wicket:id="btnCompute">ComputeAjax</button> </form> </body> </html>
« Euh, c’est moi ou je ne vois pas trop ce qui change… »
Ben non, ce n’est pas vous!
Wicket propose un support très avancé d’Ajax, et c’est tant mieux pour nous.
Dans notre cas, la méthode [onSubmit()] du formulaire à été remplacée par l'ajout d'un bouton [AjaxButton()], qui en tant que classe abstraite, nécessite, comme de par hasard, l'écriture de la méthode [onSubmit(AjaxRequestTarget target, Form form)].
Ensuite, il nous faut rafraichir l'affichage du [TextArea] et du [Label] avec les données à jour, et cela sans recharger complètement la page.
Pour faire cela nous avons rajouté un [WebMarkupContainer] dans l'arborescence qui du coup devient :
- page
- formCleanHtml
- panelCodeHtml
- txtCleanHtml
- lblCleanHtml
- panelCodeHtml
- formCleanHtml
En fait c’est ce “Container” que nous mettrons à jour via Ajax. C’est exactement ce que fait l’appel :
target.addComponent(panelCodeHtml);
dans la méthode [onSubmit(AjaxRequestTarget target, Form form)]. On notifie à Wicket qu'il doit recharger le composant [panelCodeHtml] dans son ensemble (ses fils inclus).
Bon donc nous avons créé notre nouvelle page, mais comment diable allons nous y accéder!
Vous allez modifier légèrement la classe [CleanHtmlApplication] en lui surchargeant la méthode [init()]:
package com.noocodecommit.wicket.cleanhtml.wicket; import org.apache.wicket.protocol.http.WebApplication; import com.noocodecommit.wicket.cleanhtml.wicket.pages.AjaxHomePage; import com.noocodecommit.wicket.cleanhtml.wicket.pages.HomePage; public class CleanHtmlApplication extends WebApplication { @Override protected void init() { super.init(); mountBookmarkablePage("home", HomePage.class); mountBookmarkablePage("ajaxhome", AjaxHomePage.class); } @Override public Class getHomePage() { return HomePage.class; } }
Nous allons dire à Wicket d’associer nos [WebPage] avec un chemin particulier. La classe [HomePage] sera accessible à l'URL http://serveur/cleanhtml/home et la classe [AjaxHomePage] le sera à l'URL http://serveur/cleanhtml/ajaxhome. Pratique non?
Allez, il est temps de lancer tout ça. Ouvrez un firefox à l'adresse http://localhost:8080/cleanhtml/ajaxhome.
Bon jusque là tout va bien. Maintenant saisissez un bout d’HTML dans le champ texte et cliquez sur le bouton [ComputeAjax].
Et la c'est le drame! Une page d'erreur apparait (en fait c'est juste pour avoir l'occasion d'en voir une ensemble). La gestion des erreurs dans Wicket est une des plus aboutie de tous les frameworks que j'ai essayés.
Alors que nous dit cette erreur :
java.lang.IllegalArgumentException: cannot update component
that does not have setOutputMarkupId property set to true.
Et bien Wicket nous dit qu’il a besoin que le composant qui est la cible d’un rafraichissement via Ajax, à besoin d’avoir sa propriété [outputMarkupId] positionnée à [true]. Qu'il en soit ainsi, ce que Wicket veut...
Donc nous allons modifier la classe [AjaxHomePage], en remplaçant :
panelCodeHtml = new WebMarkupContainer("panelCodeHtml");
par:
panelCodeHtml = new WebMarkupContainer("panelCodeHtml"); panelCodeHtml.setOutputMarkupId(true);
On relance Tomcat, on retourne à l’adresse http://localhost:8080/cleanhtml/ajaxhome, on resaisi un bout de code HTML dans le champ texte, on clic sur le bouton [ComputeAjax], et la la page sans faire de rafraichissement général, est modifiée avec le résultat escompté.
Et tout ça sans faire une seule ligne de Javascript...
Bravo, vous êtes désormais un développeur "Web 2.0"
Les sources du projet se trouvent ici.











January 31st, 2008 at 15:04
Trés intérressant!!

January 31st, 2008 at 15:04
Et mon drag n’drop? :privatejoke:
August 16th, 2008 at 04:53
Your blog is interesting!
Keep up the good work!