L’objet de cet article est de démystifier l’objet grid, et montrer comment travailler sur un ensemble de données présentées dans un tableau.
L’exemple sur lequel je m’appuierais, sera un tableau utilisant l’objet grid, contenant une liste d’utilisateurs, une colonne du tableau sera dédiée à une case pour marquer l’utilisateur « à supprimer ».
Un bouton permettra de traiter tous les utilisateurs du tableau et de supprimer tous ceux pour lesquels la case sera cochée.
1- Méthodologie
Nous allons récupérer la liste des utilisateurs grâce à une fonction AJAX, puis intégrer cette liste dans un dataset, je ne détaillerais pas cette procédure, un article lui est consacré dans ce blog.
Puis nous allons afficher ce dataset dans un objet grid.
Ensuite nous créerons un bouton « supprimer » pour traiter toutes les lignes du tableau et créer une requête qui sera envoyée au serveur en POST pour lui indiquer la liste des utilisateurs à supprimer dans la base. Les utilisateurs seront supprimés du dataset pour disparaître du tableau.
Cet article va nous permettre de voir une autre possibilité du langage, la possibilité d’envoyer une requête POST et récupérer un message de retour du serveur par l’intermédiaire d’un dataset.
2- Récupération et intégration des données
La liste des utilisateurs sera stockée dans une base SQL et récupérée par un scripte PHP. Le script et les informations sur les utilisateurs ne diffèrent que peu par rapport au tutoriel sur l’intégration de dataset avec AJAX donc je ne détaillerais que les points essentiels.
Requête SQL – Création de la table utilisateur -
- CREATE TABLE `users` (
- `id` int(10) unsigned NOT NULL auto_increment,
- `nick` varchar(30) NOT NULL default '',
- `name` varchar(30) default NULL,
- `surname` varchar(30) default NULL,
- `password` varchar(100) NOT NULL default '',
- PRIMARY KEY (`id`)
- )
Le document XML voulut est le suivant, il est identique à celui du tutoriel sur AJAX et les dataset mais comporte un attribut en plus par utilisateurs, l’attribut supp= »false », cette attribut est rajouté par le script PHP pour permettre à l’application client de contrôler quel utilisateur doit être supprimé.
Document XML – Format des données -
- <utilisateurs>
- <user id="1" nick="xxxx" prenom="xxxx" nom="xxxx" supp="false"/>
- <user id="2" nick="yyyy" prenom="yyyy" nom="yyyy" supp="false"/>
- .......
- <user id="3" nick="zzzz" prenom="zzzz" nom="zzzz" supp="false"/>
- </utilisateurs>
voilà le script PHP qui permet la génération de la liste des utilisateurs au format XML
Script PHP – Création du document XML –
- <?php
- header("Content-type: text/xml; charset=UTF-8");
- include"includes/config.inc";
- include"includes/connect.inc";
- echo"<utilisateurs>\n";
- // liste des utilisateurs
- $query = 'SELECT `id`, `nick`, `name`, `surname` FROM `users`';
- $result = mysql_query($query) or die("impossible de récupérer la liste des utilisateurs");
- while ($line = mysql_fetch_assoc($result)) {
- $id = $line["id"];
- $nick = $line["nick"];
- $prenom = $line['name'];
- $nom = $line['surname'];
- echo"<user id=\"$id\" nick=\"$nick\" prenom=\"$prenom\" nom=\"$nom\" supp=\"false\"/>\n";
- }
- mysql_free_result($result);
- include"includes/disconnect.inc";
- echo"</utilisateurs>\n";
- ?>
La structure est identique à celle du script vu dans le tutoriel « AJAX et les dataset », le seul ajout est l’attribut supp=\ »false\ ».
La vérification du résultat est toujours possible en entrant l’URL du script dans un navigateur pour vérifier le bon formatage du document.

L’intégration du fichier XML dans le dataset est décrit dans le tutoriel « AJAX et les dataset », je ne décrirais donc pas les fonctions AJAX.
Script LZX partie 1 – initialisation et récupération de la liste d’utilisateurs –
- <?xml version="1.0" encoding="UTF-8" ?>
- <canvas width="900" height="550" oninit="loadXMLListUsers()">
- <!-- AJAX -->
- <include href="rpc/ajax.lzx" />
- <dataset name="listuser"/>
- <script>
- <![CDATA[
- var req = null;
- function processReqChange() {
- // only if req shows "loaded"
- if (req.readyState == 4) {
- // only if "OK"
- if (req.status == 200) {
- Debug.write("OK");
- // enregistrement des données du XML dans le dataset
- canvas.listuser.setChildNodes(req.responseXML.childNodes )
- } else {
- Debug.write("Problème lors de la récupération des données:\n" + req.statusText);
- }
- }
- }
- function loadXMLListUsers() {
- // requete XMLHttpRequest
- req = new XMLHttpRequest();
- req.onreadystatechange = processReqChange;
- req.open("GET", "http://localhost/listusers/listusers.php", true);
- req.send(null);
- }
- ]]>
- </script>
Ici, rien de particulier, lors de l’initialisation de l’application cliente, on exécute la fonction loadXMLListUsers() qui récupère la liste des utilisateurs avec XMLhttprequest().
3- La suppression des utilisateurs dans la base
La suppression d’un ou plusieurs utilisateurs dans la base est effectuée par le script delusers.php,
ce script prend en paramètre un tableau nommé « supp », passé par la méthode POST, contenant la liste des id des utilisateurs à supprimer de la base.
Le script effectue la suppression pour chaque « id » et revoit un message en cas de réussite ou échec de la suppression. Ce message peut être des formes suivantes :
En cas de réussite:
- <reponse>
- <validation name='envoie'>OK</validation>
- </reponse>
En cas d’échec:
- <reponse>
- <validation name='envoie'>ERR</validation>
- </reponse>
Script PHP – suppression de l’utilisateur dans la base de donnée -
- <?php
- header("Content-type: text/xml; charset=UTF-8");
- include"includes/config.inc";
- include"includes/connect.inc";
- //récupération des infos
- $id_Array = $_POST["supp"];
- foreach($id_Array as $id){
- $query = "DELETE FROM `users` WHERE `id` = $id;";
- $result = mysql_query($query);
- if ($result != 1) {
- echo"<reponse>";
- echo"<validation>ERR</validation>";
- echo"</reponse>";
- die();
- }
- }
- echo"<reponse>";
- echo"<validation>OK</validation>";
- echo"</reponse>";
- include"includes/disconnect.inc";
- ?>
Voilà le code LZX pour gérer l’envoi et la gestion des réponses du côté du client.
Script LZX partie 2 – gestion des envois et réceptions de données –
- <!-- DATASET pour la suppression des utilisateurs -->
- <dataset name="query" type="http" src="http://localhost/listusers/delusers.php" request="false" ondata="canvas.checksupp()" querytype="POST"/>
- <!-- Contrôle du retour du serveur -->
- <method name="checksupp">
- // création d'un pointeur sur le message de retour du serveur
- var retours = canvas.query.getPointer();
- // positionnement du pointeur
- retours.setXPath("query:/reponse/validation");
- // on récupère le texte de la balise validation
- var result = retours.getNodeText();
- // si c'est OK on affiche la boîte de dialogue "suppression réussit"
- if (result == "OK"){canvas.good.open();}
- // si c'est ERR, on affiche une boîte d'erreur
- if (result == "ERR") {canvas.erreurdialog.open();}
- </method>
- <!-- Fenêtre en cas de suppression correctement effectuée -->
- <modaldialog name="good" title="OK" width="250" height="110">
- <text align="center">tous les éléments ont été supprimés</text>
- <view align="center" layout="axis:x; spacing:20">
- <button onclick="parent.parent.close()" isdefault="true">OK</button>
- </view>
- <simplelayout spacing="5"/>
- </modaldialog>
- <!-- Fenêtre en cas d'erreur -->
- <modaldialog name="erreurdialog" title="erreure" width="250" height="110">
- <text align="center">Erreure lors de l'émission du message</text>
- <view align="center" layout="axis:x; spacing:20">
- <button onclick="parent.parent.close()" isdefault="true">OK</button>
- </view>
- <simplelayout spacing="5"/>
- </modaldialog>
Pour commencer on crée un dataset pour gérer l’envoi et la réception de données vers le script delusers.php en mode POST. Lorsque le dataset reçoit une réponse du serveur, il appel la méthode « canvas.checksupp() ».
La méthode « checksupp » commence par initialiser un pointeur sur le message de retour du serveur, puis récupère le text de ce message, OK ou ERR, en fonction de ce message, on ouvre la fenêtre good ou la fenêtre erreurdialog, pour informer l’utilisateur sur le déroulement des opérations.
Pour créer les fenêtres de message, j’utilise les composants «
4- Affichage des données avec le composant grid
Script LZX partie 3 – affichage des données –
- <view>
- <grid name="gridlivre" datapath="listuser:/utilisateurs/">
- <gridtext datapath="@id" editable="false" width="50" resizable="false"> Id </gridtext>
- <gridtext datapath="@nick"> Nickname </gridtext>
- <gridtext datapath="@prenom"> Prénom </gridtext>
- <gridtext datapath="@nom"> Nom </gridtext>
- <gridcolumn resizable="false" sortable="false" width="40"> Supp
- <checkbox datapath="@supp" xoffset="${10-parent.width/2}">
- <!-- En cas de changement de valeur, on appel la méthode updateData pour modifier le datapath -->
- <method event="onvalue">
- parent.parent.datapath.updateData();
- </method>
- <!-- On retourne la valeur du checkbox -->
- <method name="updateData">
- return this.value;
- </method>
- </checkbox>
- </gridcolumn>
- </grid>
Pour afficher la liste des utilisateurs, on utilisera le composant
Ici, on attache au composant
En cas de modification de l’état de la checkbox, la méthode updateData() modifiera directement, dans le dataset, la valeur de l’ attribut @supp, pour l’utilisateur concerné.
5- Création du bouton pour la suppression des utilisateurs sélectionnés
Script LZX partie 4 – Suppression des utilisateurs sélectionnés –
- <button x="20" y="300" text="Delete selected">
- <method event="onclick">
- <![CDATA[
- // initialisation de la requête de suppression
- var Query;
- // initialisation des pointeurs sur les utilisateurs
- var liste = canvas.listuser.getPointer();
- // positionnement du pointeur
- liste.setXPath("listuser:/utilisateurs");
- //récupération du nombre d'utilisateurs
- var count = liste.getNodeCount();
- // positionnement sur le premier noeud (premier utilisateur)
- liste.selectChild();
- // initialisation du compteur pour le tableau de suppression
- var cpt = 0;
- // pour chaque ligne...
- for (var c = 0; c < count; ++c){
- // si l'attribut supp est vrais...
- if ( liste.getNodeAttribute("supp") == true){
- // on rajoute la ligne dans la liste de suppression
- // sous la forme supp[0]=1&supp[1]
- if (cpt == 0){var Query = "supp["+cpt+"]="+liste.getNodeAttribute("id");}
- else{Query = Query+"&supp["+cpt+"]="+liste.getNodeAttribute("id");}
- // on supprime le noeud
- liste.deleteNode();
- // on incrémente le compteur du tableau de suppression
- cpt = cpt + 1;
- }
- // si pas de suppression on passe à la ligne suivante
- else {liste.selectNext();}
- }
- // initialisation du Dataset query avec le contenu de la requête puis émission
- var DsQuery = canvas.query;
- DsQuery.setQueryString(Query);
- DsQuery.doRequest();
- ]]>
- </method>
- </button>
- <simplelayout axis="y" spacing="5"/>
- </view>
- </canvas>

Lors de la pression sur le bouton, on reprend le dataset, et pour chaque utilisateur dont l’attribut @supp est différent de faux (donc coché comme « à supprimé »), on ajout un paramètre à la requête POST. Ensuite, nous supprimons la ligne directement dans le dataset, ce qui à un effet immédiat sur l’affichage dans le
Cet exemple illustre bien les communications entre le client et le serveur et présente une partie des possibilités du composant








BlogoSquare