ATTENTION : Tutorial en cours d'écriture ! N'hésitez pas à nous signaler toute erreur ou suggestion.
Accès rapide :
Définir votre modèle de données
Lier votre composant à vos données
Les différents modes de fonctionnement du composant
Considérons la classe Java suivante : elle permet de définir des instances d'articles pour un éventuel site web de vente en ligne. Comme vous pouvez le noter, chaque article est constitué de quatre propriétés : un identifiant (idArticle), une description (description), une marque (brand) et un prix unitaire (unitaryPrice). Notez aussi la présence des méthodes de construction et d'affichage de nos articles.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
package com.is.webstore.business; public class Article { private int idArticle; private String description; private String brand; private double price; public Article() {} public Article( int idArticle, String description, String brand, double unitaryPrice ) { super(); this.setIdArticle( idArticle ); this.setDescription( description ); this.setBrand( brand ); this.setUnitaryPrice( unitaryPrice ); } public int getIdArticle() { return idArticle; } public void setIdArticle( int idArticle ) { if ( idArticle < 0 ) throw new RuntimeException( "identifier must be positive" ); this.idArticle = idArticle; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description.toLowerCase(); } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand.toUpperCase(); } public double getUnitaryPrice() { return price; } public void setUnitaryPrice(double price) { if ( price < 0 ) throw new RuntimeException( "Price must be positive" ); this.price = price; } public String toString() { return "[" + this.idArticle + "]: " + this.description + " of brand " + this.brand + " - " + this.price + " euros"; } } |
Notre modèle de données s'appuiera aussi sur une autre classe permettant de représenter la notion de panier marchant. Normalement, dans un vrai panier, chaque article devrait être associé à une quantité, mais dans cet exemple nous simplifierons les choses : si vous souhaitez avoir un article en plusieurs exemplaires dans votre panier, ajoutez le plusieurs fois. Voici un exemple de code pour cette classe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
package com.is.webstore.business; import java.util.ArrayList; import java.util.List; public class Basket { private List<Article> articles = new ArrayList<Article>(); public Basket() { } public void addArticle( Article article ) { if ( article == null ) throw new NullPointerException(); this.articles.add( article ); } public List<Article> getArticles() { return articles; } } |
Il nous faut maintenant coder notre page web qui affichera notre composant <web:DataGrid />.
Afin de coder relativement vite notre page web, elle créera un panier par défaut dans la session, si celui n'existe pas.
Voici le code de la classe utilisée pour notre page web. Cette création de panier est réalisée dans la methode
page_preRepeaterDuplications qui est déclenchée par le framework Ellipse juste avant que les duplications
des lignes de la grille commencent.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
package com.is.webstore.ihm; import com.is.webstore.business.Article; import com.is.webstore.business.Basket; import corelib.services.web.webapplications.WebPage; import corelib.services.web.webapplications.events.WebPageEvent; public class ViewBasket extends WebPage { @Override public void page_preRepeaterDuplications( WebPageEvent webPageEvent ) { super.page_preRepeaterDuplications( webPageEvent ); if ( this.session.getAttribute( "basket") == null ) { Basket basket = new Basket(); basket.addArticle( new Article( 1, "Mouse", "Logitoch", 65 ) ); basket.addArticle( new Article( 2, "Keyboard", "Microhard", 49.5 ) ); basket.addArticle( new Article( 3, "Operating system", "Fenetres Vistouille", 150 ) ); basket.addArticle( new Article( 4, "Mouse pad", "Evolution MM", 5 ) ); basket.addArticle( new Article( 5, "USB key 8 To", "Syno", 8 ) ); basket.addArticle( new Article( 6, "Laptop", "PH", 1199 ) ); basket.addArticle( new Article( 7, "CD x 500", "CETME", 250 ) ); basket.addArticle( new Article( 8, "DVD-R x 100", "CETME", 99 ) ); basket.addArticle( new Article( 9, "DVD+R x 100", "CETME", 105 ) ); basket.addArticle( new Article( 10, "Laptop battery", "PH", 80 ) ); basket.addArticle( new Article( 11, "Headphones", "Syno", 105 ) ); basket.addArticle( new Article( 12, "WebCam", "Logitoch", 755 ) ); this.session.setAttribute( "basket", basket ); } } } |
Voici maintenant la mise en forme de votre page Web.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?xml version="1.0" encoding="ISO-8859-1" ?> <web:Html xmlns:web="corelib.services.web.components" codeBehind="com.is.webstore.ihm.ViewBasket"> <head> <title>View basket content</title> <link rel="stylesheet" type="text/css" href="corelib/services/web/javascript/jwt/Jwt.css" /> </head> <body> <h1 align="center">View basket content</h1> <web:Form> <web:DataGrid values="#{basket.articles}" elementAlias="article" beanPerPage="5" cssStyle="width: 600px; margin: auto"> <web:DataGridColumn caption="Identifier" values="#{article.idArticle}" /> <web:DataGridColumn caption="Description" values="#{article.description}" /> <web:DataGridColumn caption="Brand" values="#{article.brand}" /> <web:DataGridColumn caption="Unitary price" values="#{article.unitaryPrice}" /> </web:DataGrid> </web:Form> </body> </web:Html> |
Comme vous pouvez le remarquer le composant <web:DataGrid /> ainsi que les tags de définition des
colonnes, sont liés au modèle de données via des expressions (facilement repérable avec par la syntaxe #{...}).
Ainsi la grille est liée à un tableau d'articles via l'expression #{basket.articles}. Le moteur de liaison de
données du framework Ellipse à la responsabilité d'évaluer cette expression : après évaluation le tableau équivalent au
code this.getSession().getAttribute("basket").getArticles() (this représentant ici la page web)
qui sera utilisé.
Vous comprenez qu'une boucle sera exécutée pour traiter tous les éléments de la collection d'articles. A chaque tour de
boucles, l'article courant sera accessible via l'alias article (spécifié via l'attribut elementAlias).
Ensuite chaque colonne est liée à une propriété de l'article courant. Ainsi #{article.description} permettra
l'exécution du code suivante : article.getDescription(). Pour de plus amples informations sur le moteur de
liaison aux données, je vous renvoie vers la page correspondante du tutorial.
La capture d'écran ci-dessous vous montre le résultat obtenu. Notez bien que la pagination est une fonctionnalité directement supportée par le composant. Il est néanmoins possible de contrôler le nombre de lignes affichées par page.
Il est fréquent que l'on puisse avoir besoin de tables qui, outre le fait de présenter des données, permettent de lancer
des actions supplémentaires et notamment la consultation détaillée, l'insertion, l'édition, la suppression, ... Il doit être
clair que le composant <web:DataGrid /> ne permet pas directement ces autres possibilités. Par
contre, il permet d'afficher des boutons et de gérer des événements associés à ces possibilités : il sera de votre ressort des coder la
réalisation de ces actions, spécifiquement à votre modèle.
Chaque mode peut être activé indépendamment des modes via une propriété spécifique. Les quatre propriétés du composant sont
allowDisplayEvent, allowInsertEvent, allowEditEvent et allowDeleteEvent.
Par défaut ces propriétés sont initialisées à la valeur false. Il suffit de fixer les propriétés souhaitées
à true pour activer les modes associés. Vous pouvez réaliser ces changement d'état soit par code Java (dans la
classe de page associée) soit dans la mise en page XML de votre page Web via des attributs XML. L'exemple de code suivant
utilise la seconde alternative.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0" encoding="ISO-8859-1" ?> <web:Html xmlns:web="corelib.services.web.components" codeBehind="com.is.webstore.ihm.ViewBasket"> <head> <title>View basket content</title> <link rel="stylesheet" type="text/css" href="corelib/services/web/javascript/jwt/Jwt.css" /> </head> <body> <h1 align="center">View basket content</h1> <web:Form> <web:DataGrid id="theGrid" values="#{basket.articles}" elementAlias="article" beanPerPage="5" cssStyle="width: 600px; margin: auto" allowDisplayEvent="true" allowInsertEvent="true" allowEditEvent="true" allowDeleteEvent="true"> <web:DataGridColumn caption="Identifier" values="#{article.idArticle}" /> <web:DataGridColumn caption="Description" values="#{article.description}" /> <web:DataGridColumn caption="Brand" values="#{article.brand}" /> <web:DataGridColumn caption="Unitary price" values="#{article.unitaryPrice}" /> </web:DataGrid> </web:Form> </body> </web:Html> |
Ensuite, vous pouvez enregistrer votre page web comme écouteur (listener) de votre composant <web:DataGrid />.
La technique utilisée est la technique classique des listeners : il vous suffit juste de connaître l'interface d'écoute
adaptée : il s'agit de corelib.services.web.components.events.DataGridListener. L'exemple de code suivant
vous montre ce que pourrait donner une telle classe : notez bien que certaines autres pages web proposées dans l'exemple
serait à coder.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
package com.is.webstore.ihm; import com.is.webstore.business.Article; import com.is.webstore.business.Basket; import corelib.services.web.components.DataGrid; import corelib.services.web.components.events.DataGridEvent; import corelib.services.web.components.events.DataGridListener; import corelib.services.web.webapplications.WebPage; import corelib.services.web.webapplications.events.WebPageEvent; public class ViewBasket extends WebPage { private DataGrid theGrid; @Override public void page_preRepeaterDuplications( WebPageEvent webPageEvent ) { super.page_preRepeaterDuplications( webPageEvent ); if ( this.session.getAttribute( "basket") == null ) { Basket basket = new Basket(); basket.addArticle( new Article( 1, "Mouse", "Logitoch", 65 ) ); basket.addArticle( new Article( 2, "Keyboard", "Microhard", 49.5 ) ); basket.addArticle( new Article( 3, "Operating system", "Fenetres Vistouille", 150 ) ); basket.addArticle( new Article( 4, "Mouse pad", "Evolution MM", 5 ) ); basket.addArticle( new Article( 5, "USB key 8 To", "Syno", 8 ) ); basket.addArticle( new Article( 6, "Laptop", "PH", 1199 ) ); basket.addArticle( new Article( 7, "CD x 500", "CETME", 250 ) ); basket.addArticle( new Article( 8, "DVD-R x 100", "CETME", 99 ) ); basket.addArticle( new Article( 9, "DVD+R x 100", "CETME", 105 ) ); basket.addArticle( new Article( 10, "Laptop battery", "PH", 80 ) ); basket.addArticle( new Article( 11, "Headphones", "Syno", 105 ) ); basket.addArticle( new Article( 12, "WebCam", "Logitoch", 755 ) ); this.session.setAttribute( "basket", basket ); } } @Override public void page_load(WebPageEvent webPageEvent) { super.page_load(webPageEvent); this.theGrid.addDataGridListener( new DataGridListener() { @Override public void insertSelectedBean( DataGridEvent event ) { // You must define the InsertArticle.wp web page ViewBasket.this.redirect( "InsertArticle.wp" ); } @Override public void editSelectedBean( DataGridEvent event ) { Article article = (Article) event.getSelectedBean(); ViewBasket.this.session.setAttribute( "article", article ); // You must define the EditArticle.wp web page ViewBasket.this.redirect( "EditArticle.wp" ); } @Override public void displaySelectedBean( DataGridEvent event ) { Article article = (Article) event.getSelectedBean(); ViewBasket.this.session.setAttribute( "article", article ); // You must define the ViewArticle.wp web page ViewBasket.this.redirect( "ViewArticle.wp" ); } @Override public void deleteSelectedBean( DataGridEvent event ) { Article article = (Article) event.getSelectedBean(); // Do the article deletion } }); } } |
A titre d'exemple, voici à quoi ressemble une grille pour laquelle tout les modes supplémentaires ont été activés (attention, il s'agit d'une capture d'écran : ne cliquez donc pas dessus).
Remarque importante : pour correctement se présenter à vous, ce composant à besoin d'une feuille de styles CSS
et de quelques images complémentaires. Vous n'avez pas à copier ces éléments dans le WAR. En fait, ils font partie
du fichier EllipseFramework.jar : au démarrage de votre application Web, un certain nombre de ressources
sont automatiquement désarchiver dans le WAR du serveur HTTP. Il est clair que ce point simplifie considérable les choses.
|
|
|||||||