Ellipse Tutorial

Comment utiliser le composant ?

AccueilNotre catalogue de formationsNos partenairesDemande de devisEllipse FrameworkJWT (Javascript Widget Toolkit)License d'exploitation de nos logicielsVos développements sur mesuresTutorial sur le langage CSSTutorial sur le langage XMLTutorial sur le langage JavaTutorial sur le langage Visual Basic 6.0Code SamplesHistorique de la sociétéNous contacterMentions LégalesA propos de ce site
 

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

Définir votre modèle de données

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";
    }
    
}
Une classe de manipulation d'articles

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;
    }
}
Une classe de manipulation de panier d'article

Lier votre composant à vos données

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 );
        }
    }
    
}
Le code de la page web d'affichage du contenu du panier : ViewBasket.java

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>
La mise en page de la page web : ViewBasket.wp

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.

Les différents modes de fonctionnement du composant

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>
La mise en page de la page web : ViewBasket.wp

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
            }
        });
    }
    
}
Le code de la page web d'affichage du contenu du panier : ViewBasket.java

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.