Gestion des listes avec les Repeaters


Pour gérer l'affichage des listes, Wicket propose le mécanisme des repeaters, comme nous l'avons vu dans le billet ZenContact 6.

En plus de la ListView qui permet de répéter facilement un markup pour chaque élément d'une liste, Wicket propose des repeaters plus avancés, que je vais vous présenter en suivant leur hiérarchie de classes. Nous allons aussi voir comment les utiliser pour remplacer la ListView utilisée dans ZenContact.

Lire la suite...

Comment rendre ses fichiers Javascript ou CSS dynamiques avec Wicket


Si vous avez l'habitude de rajouter des fichiers Javascript ou CSS à vos pages depuis vos composants Wicket, vous avez sûrement déjà utilisé la méthode getHeaderContribution :

  1. add(JavascriptPackageResource.getHeaderContribution(MyComponent.class, "js/MyComponent.js"));

Ou encore, sur les anciennes version de Wicket :

  1. add(HeaderContributor.forJavaScript(MyComponent.class, "MyComponent.js");

Cependant, les fichiers Javascript (ou CSS) sont ajoutés tel quels. Nous allons voir ici comment personnaliser ces fichiers, en rajoutant des variables à nos fichiers initialement statiques.

Nous allons pour cela utiliser un TextTemplateHeaderContributor à la place de notre HeaderContributor, en passant un modèle contenant la liste de nos variables.

  1. IModel<Map<String, Object>> variablesModel = new AbstractReadOnlyModel<Map<String, Object>>() {
  2.  
  3. private Map<String, Object> variables;
  4.  
  5. public Map<String, Object> getObject() {
  6. if (variables == null) {
  7. this.variables = new MiniMap<String, Object>(3);
  8. variables.put("markupId", MyComponent.this.getMarkupId() );
  9. variables.put("height", calculateHeight() );
  10. variables.put("width", calculateWidth() );
  11. }
  12. return variables;
  13. }
  14.  
  15.  
  16. };
  17.  
  18. add(TextTemplateHeaderContributor.forJavaScript(MyComponent.class, "js/MyComponent.js", variablesModel));

Ensuite, il est facile de récupérer la valeur de nos variables dans notre fichier Javascript :

  1. $(function() {
  2. $("#${markupId}").dialog({
  3. height: ${height},
  4. width: ${width}
  5. });
  6. });

Nous verrons un cas d'application avec les templates Javascript et JQuery dans un prochain article.

ZenContact 15 : Drag and Drop avec Wicket et Script.aculo.us


Dans ce billet nous allons voir comment ajouter la fonctionnalité "drag and drop" afin de faciliter davantage l'édition de contacts.

Voici ce que nous souhaitons obtenir :

  • avoir la possibilité de déplacer un contact présent dans la liste de contacts vers le formulaire d'édition, afin de pré-remplir les champs de ce dernier avec les infos du contact correspondant.
Lire la suite...

ZenContact 14 : Création d'un Panel de formulaire


Dans ce billet nous allons voir comment créer et utiliser un Panel avec Wicket. Les panels sont des templates réutilisables contenant des composants, ils sont ajoutés à une page par composition.

A titre d'exemple, nous allons intégrer le formulaire d'ajout de contacts dans son propre Panel.

Lire la suite...

ZenContact 13 : Edition des contacts avec un peu d'Ajax


Maintenant que les contacts peuvent être convenablement créés, il faut pouvoir les éditer ! Nous allons voir comment procéder dans ce billet.

Edition simple de contacts

Dans la liste des contacts nous plaçons un lien sur l'image crayon qui symbolise l'édition. Ce lien doit rediriger l'utilisateur vers le formulaire de création/édition des contacts avec les champs correspondant pré-remplis. Pour ce faire, il suffira de passer en paramètre le contact à éditer à notre page EditContactPage.

Dynamiser le markup

Ajoutons un attribut wicket:id dans la balise a déjà présente :

ListContactPage.html

  1. <wicket:extend>
  2. <table cellspacing="5" cellpadding="5">
  3. <tr wicket:id="liste">
  4. <td><div><img src="images/people.png"/></div></td>
  5. <td><span wicket:id="prenom"/>&nbsp;<span wicket:id="nom"/></td>
  6. <td><a href="#" wicket:id="editer"><img src="images/edit.png"/></a></td>
  7. </tr>
  8. </table>
  9. </wicket:extend>

Ajout du lien côté Java

Ajoutons l'élément Link et implémentons sa méthode onClick() afin de renvoyer l'utilisateur vers la page d'édition des contacts.

  1. public class ListContactPage extends TemplatePage {
  2.  
  3. public ListContactPage() {
  4. add(new PropertyListView("liste", ZenContactApplication.get()
  5. .getContactsList()) {
  6. private static final long serialVersionUID = 1L;
  7.  
  8. @Override
  9. protected void populateItem(final ListItem item) {
  10. final Contact contact = (Contact) item.getModelObject();
  11.  
  12. item.add(new Label("prenom"));
  13. item.add(new Label("nom"));
  14.  
  15. item.add(new Link("editer") {
  16. @Override
  17. public void onClick() {
  18. setResponsePage(new EditContactPage(contact));
  19. }
  20. });
  21. }
  22. });
  23. }
  24.  
  25. }

Vous remarquez que nous utilisons un constructeur de la page EditContactPage qui prend en paramètre un objet de type Contact. Créons donc ce constructeur.

  1. public class EditContactPage extends TemplatePage {
  2.  
  3. public EditContactPage() {
  4. this(new Contact());
  5. }
  6.  
  7. public EditContactPage(Contact contact) {
  8. super();
  9. add(new EditContactFrom("editform", contact));
  10. }
  11.  
  12. public class EditContactFrom extends Form {/**/}
  13.  
  14. }

Testons

Lancez Jetty, et cliquez sur un des liens nouvellement créés dans la page listant les contacts.

http://localhost:8080/zencontact

Super ! Nous pouvons désormais éditer un contact facilement. Cependant, nous n'avons pas tout à fait terminé, je vous avez promi un peu d'Ajax !

Edition avec une pointe d'Ajax

Voyons comment l'utilisateur peut éditer très rapidement le nom du contact avec seulement 12 caractères de code ! Il suffit de remplacer le Label du nom par un AjaxEditableLabel qui se trouve dans wicket-extensions.

  1. public class ListContactPage extends TemplatePage {
  2.  
  3. public ListContactPage() {
  4. add(new PropertyListView("liste", ZenContactApplication.get()
  5. .getContactsList()) {
  6. private static final long serialVersionUID = 1L;
  7.  
  8. @Override
  9. protected void populateItem(final ListItem item) {
  10. final Contact contact = (Contact) item.getModelObject();
  11.  
  12. item.add(new Label("prenom"));
  13. item.add(new AjaxEditableLabel("nom"));
  14.  
  15. item.add(new Link("editer") {
  16. @Override
  17. public void onClick() {
  18. setResponsePage(new EditContactPage(contact));
  19. }
  20. });
  21. }
  22. });
  23. }
  24.  
  25. }

Testons

Dès que l'utilisateur clique sur le Label "nom", celui est remplacé dynamiquement par un input de type texte. La modification est soumise avec une requêtre AJAX dès que le focus n'est plus sur l'input.

Dans le prochain épisode nous aborderons la création d'un Panel.

Wicket et JMX


En attendant que les fonctionnalités JMX soient incorporées à wicket, il est possible d'en obtenir le support en rajoutant la dépendance vers wicket-jmx à notre projet.

Cela va nous permettre d'avoir accès à la configuration de notre application Wicket en nous connectant avec une console JMX (la jconsole par exemple).

En utilisant maven, il suffit de rajouter la dépendance suivante :

<dependency>
	<groupId>org.apache.wicket</groupId>
	<artifactId>wicket-jmx</artifactId>
	<version>1.4.4</version>
</dependency>

Il est désormais possible de modifier à chaud toute la configuration d'une application wicket.

Pour aller plus loin, on peut également trouver un projet nommé JMXPanel dans Wicket Stuff, qui permet d'afficher tout simplement l'arbre de nos MBeans Wicket.

Une seule ligne suffit pour rajouter le panel JMX à notre composant wicket:

add(new JmxPanel("tabPanel"));

wicket-jmx-panel

Pour récupérer le panel, il suffit de rajouter le projet wicket-jmx-panel à notre projet. Ce projet dépend lui même de wicket-jmx.

<dependency>
	<groupId>org.wicketstuff</groupId>
	<artifactId>wicketstuff-jmx-panel</artifactId>
	<version>1.4-SNAPSHOT</version>
</dependency>

Il vous faudra également rajouter le repository wicket-stuff dans votre configuration maven ou dans votre pom.xml :

<repositories>
	<repository>
		<id>wicket-stuff-repository</id>
		<name>Wicket-Stuff Repository</name>
		<url>http://www.wicketstuff.org/maven/repository</url>
	</repository>
</repositories>

Vous pouvez lister les versions du panel jmx disponibles sur maven en vous rendant directement sur le repo Maven de wicketstuff :

http://www.wicketstuff.org/maven/repository/org/wicketstuff/wicketstuff-jmx-panel/

A l'heure actuelle, la dernière version est la version 1.4-SNAPSHOT

ZenContact 12 : Validation côté client


Dans le billet précédent nous avons vu comment intégrer un DatePicker à notre formulaire, cette étape finalisait la validation côté serveur. Cependant, nous avons également besoin d'une validation en amont, côté client. Voyons comment l'ajouter.

Ajout du Behavior Yav

Ce que nous voulons côté client, c'est appliquer les mêmes règles de validation que côté serveur. Pour cela, nous faisons appel au plugin Yav, un composant "made in" Zenika intégré dans le projet Wicket Stuff. Wicket Stuff-Yav a pour but d'intégrer Yav un framework de validation purement Javascript à Wicket.

Nous ajoutons tout simplement une instance du Behavior Yav à notre formulaire.

  1. public class EditContactPage extends TemplatePage {
  2.  
  3. public EditContactPage() {
  4. super();
  5. add(new EditContactFrom("editform", new Contact()));
  6.  
  7. }
  8.  
  9. public class EditContactFrom extends Form {
  10.  
  11. public EditContactFrom(String id, Contact contact) {
  12. super(id);
  13.  
  14. setModel(new CompoundPropertyModel(contact));
  15.  
  16. add(new TextField("prenom").setRequired(true));
  17. add(new TextField("nom").setRequired(true).add(
  18. new MaximumLengthValidator(10)));
  19. add(new TextField("dateNaissance", Date.class)
  20. .add(new DatePicker()));
  21. add(new TextField("email").add(EmailAddressValidator.getInstance()));
  22.  
  23. add(new FeedbackPanel("feedback"));
  24.  
  25. add(new YavBehavior());
  26. }
  27.  
  28. @Override
  29. protected void onSubmit() {
  30. Contact contact = (Contact) getModelObject();
  31.  
  32. ZenContactApplication.get().getContacts().add(contact);
  33.  
  34. setResponsePage(ListContactPage.class);
  35. }
  36.  
  37. }
  38. }

Nous pouvons tester la validation côté client : http://localhost:8080/zencontact

C'était la dernière étape de l'implémentation de la création de contacts. Dans un prochain billet nous verrons comment éditer rapidement ces contacts nouvellement créés avec un peu d'AJAX.

Précédent : Zencontact 11 - DatePicker

ZenContact 11 : Ajout du DatePicker


Dans le précédent billet nous avons vu comme persister un nouveau contact créé avec note formulaire. La création de contacts est donc désormais tout à fait opérationnelle, cependant il nous manque encore quelques fonctionnalités. Dans ce billet, nous allons voir comment faciliter l'insertion et le formatage de la date de naissance à l'aide d'un DatePicker YUI.

Ajouter un Behavior de type DatePicker au composant Java

  1. public class EditContactPage extends TemplatePage {
  2.  
  3. public EditContactPage() {
  4. super();
  5. add(new EditContactFrom("editform", new Contact()));
  6.  
  7. }
  8.  
  9. public class EditContactFrom extends Form {
  10.  
  11. public EditContactFrom(String id, Contact contact) {
  12. super(id);
  13.  
  14. setModel(new CompoundPropertyModel(contact));
  15.  
  16. add(new TextField("prenom").setRequired(true));
  17. add(new TextField("nom").setRequired(true).add(
  18. new MaximumLengthValidator(10)));
  19. add(new TextField("dateNaissance", Date.class).add(new DatePicker()));
  20. add(new TextField("email").add(EmailAddressValidator.getInstance()));
  21.  
  22. add(new FeedbackPanel("feedback"));
  23. }
  24.  
  25. @Override
  26. protected void onSubmit() {
  27. Contact contact = (Contact) getModelObject();
  28.  
  29. ZenContactApplication.get().getContacts().add(contact);
  30.  
  31. setResponsePage(ListContactPage.class);
  32. }
  33.  
  34. }
  35. }

Le DatePicker n'a pas pour unique but de faciliter l'insertion d'une date pour l'utilisateur. Il permet également de s'assurer qu'il n'y aura pas de problèmes lors de la conversion de la chaîne de caractères en type Date, puisque le format de date provient du serveur.

Testons : http://localhost:8080/zencontact

DatePicker

La validation côté serveur est maintenant complète. Cependant, pour davantage de fiabilité, il serait utile de valider en amont, côté client. Nous verrons comment procéder dans le prochain billet.

Précédent : Zencontact 10 - Persistance du contact
Suivant : Zencontact 12 - Validation côté client

ZenContact 10 : Persistance du nouveau contact


Après s'être assuré de la validation de notre formulaire, nous pouvons enfin persister ce nouveau contact dans notre liste.

Persister le nouveau contact

Cette étape s'effectue au moment de la soumission du formulaire. Nous allons donc surcharger la méthode onSubmit() de notre composant EditContactForm.

  1. public class EditContactPage extends TemplatePage {
  2.  
  3. public EditContactPage() {
  4. super();
  5. add(new EditContactFrom("editform", new Contact()));
  6.  
  7. }
  8.  
  9. public class EditContactFrom extends Form {
  10.  
  11. public EditContactFrom(String id, Contact contact) {
  12. super(id);
  13.  
  14. setModel(new CompoundPropertyModel(contact));
  15.  
  16. add(new TextField("prenom").setRequired(true));
  17. add(new TextField("nom").setRequired(true).add(new MaximumLengthValidator(10)));
  18. add(new TextField("dateNaissance", Date.class));
  19. add(new TextField("email").add(EmailAddressValidator.getInstance()));
  20.  
  21. add(new FeedbackPanel("feedback"));
  22. }
  23.  
  24. @Override
  25. protected void onSubmit() {
  26. Contact contact = (Contact) getModelObject();
  27.  
  28. ZenContactApplication.get().getContacts().add(contact);
  29. }
  30.  
  31. }
  32. }

Nous récupérons ici l'objet de type Contact modifié à partir du modèle de notre formulaire, puis nous l'ajoutons à notre liste de contacts.

Il est intéressant de remarquer que Wicket fait usage du pattern "Redirect After Post" afin d'empêcher l'utilisateur de soumettre le même formulaire en rafraîchissant sa page après l'envoi d'une première requête POST.

Vous pouvez tester vous même : http://localhost:8080/zencontact

Rappelons que notre Collection de contacts est un Set qui ne peut contenir d'éléments dupliqués !

Rediriger vers la liste de contacts

Une fois le contact correctement persisté, nous pouvons rediriger le client vers la page listant les contacts (ListContactPage), afin d'y voir le contact nouvellement ajouté.

  1. public class EditContactPage extends TemplatePage {
  2.  
  3. public EditContactPage() {
  4. super();
  5. add(new EditContactFrom("editform", new Contact()));
  6.  
  7. }
  8.  
  9. public class EditContactFrom extends Form {
  10.  
  11. public EditContactFrom(String id, Contact contact) {
  12. super(id);
  13.  
  14. setModel(new CompoundPropertyModel(contact));
  15.  
  16. add(new TextField("prenom").setRequired(true));
  17. add(new TextField("nom").setRequired(true).add(new MaximumLengthValidator(10)));
  18. add(new TextField("dateNaissance", Date.class));
  19. add(new TextField("email").add(EmailAddressValidator.getInstance()));
  20.  
  21. add(new FeedbackPanel("feedback"));
  22. }
  23.  
  24. @Override
  25. protected void onSubmit() {
  26. Contact contact = (Contact) getModelObject();
  27.  
  28. ZenContactApplication.get().getContacts().add(contact);
  29. setResponsePage(ListContactPage.class);
  30. }
  31.  
  32. }
  33. }

L'ajout de contact est maintenant opérationnel. Cependant notre formulaire ne possède pas encore toutes les fonctionnalités requises, nous verrons dans un prochain billet comment faciliter l'insertion de la date de naissance de notre contact à l'aide d'un DatePicker.

Précédent : Zencontact 9 -Validation côté serveur
Suivant : Zencontact 11 - DatePicker

ZenContact 9 : Validation du formulaire côté serveur


Dans le billet précédent nous avons vu comment afficher un message d'erreur de validation du formulaire. Dans cette étape nous allons donc en profiter pour ajouter des éléments de validation sur les champs du formulaire afin de s'assurer que les données renseignées par l'utilisateur sont valides.

Un formulaire valide possède la forme suivante :

  • Le nom est obligatoire et possède un maximum de 10 caractères
  • Le prénom est obligatoire
  • L'email est facultatif mais doit posséder un pattern de forme "email"
  • La date de naissance est facultative mais doit être de forme "date"

Ajouter les éléments de validation aux composants Java

Nous avons déjà vu comment valider la forme date en forçant le type du composant TextField associé. Intéressons nous donc aux autres éléments de validation :

  1. public class EditContactPage extends TemplatePage {
  2.  
  3. public EditContactPage() {
  4. super();
  5. add(new EditContactFrom("editform", new Contact()));
  6.  
  7. }
  8.  
  9. public class EditContactFrom extends Form {
  10.  
  11. public EditContactFrom(String id, Contact contact) {
  12. super(id);
  13.  
  14. setModel(new CompoundPropertyModel(contact));
  15.  
  16. add(new TextField("prenom").setRequired(true));
  17. add(new TextField("nom").setRequired(true).add(new MaximumLengthValidator(10)));
  18. add(new TextField("dateNaissance", Date.class));
  19. add(new TextField("email").add(EmailAddressValidator.getInstance()));
  20.  
  21. add(new FeedbackPanel("feedback"));
  22. }
  23.  
  24. }
  25. }

La seule méthode setRequired(boolean) appartenant aux éléments de type FormComponent permet de forcer le remplissage d'un champ.

Pour les autres contraintes, Wicket nous fournit des Validator prêts à l'emploi, qui correspondent aux besoins les plus courants. De plus, il est possible de créer ses propres Validator rapidement et simplement à l'aide du contrat IValidator et de son implémentation de base AbstractValidator.
Chaque champ peut posséder un nombre illimité de Validators, qu'il est possible d'ajouter de manière chaînée.

Vérifions maintenant que la validation du formulaire suit notre contrat de départ : http://localhost:8080/zencontact

FeedbackPanel

Parfait, nous sommes désormais certains que l'utilisateur ne peut ajouter de données erronées, il ne reste plus qu'à persister ce nouveau contact créé. Nous verrons cela dans notre prochain billet.

Précédent : Zencontact 8 - FeedbackPanel
Suivant : Zencontact 10 - Persistance du contact

- page 1 de 3