Il existe plusieurs façons de remplir une grille, dans cet article on va attaquer un service WCF pour récupérer les données à l’aide de la classe Ext.data.Store et les lier à un GridPanel.
Mon service WCF me renvoie une liste de personnes contenant leurs noms et prénoms en format JSON. Il me renvoie aussi avec cette liste le nombre total de personnes contenues dans la réponse. Cette information est optionnelle et inutile pour notre cas mais elle peut s’avérer très utile dans d’autres cas comme pour la pagination par exemple.
Voici un exemple de réponse du service :
{"list":
[
{"nom":"Plat","prenom":"Jérémie"},
{"nom":"Nemili","prenom":"Mohamed Zied"},
{"nom":"Nemili","prenom":"Walid"},
{"nom":"Marbre","prenom":"Jean-Pierre"},
{"nom":"Mini","prenom":"Christophe"},
{"nom":"Nemili","prenom":"Anas"},
{"nom":"Dupont","prenom":"Jérôme"},
{"nom":"Delalettre","prenom":"Emilie"},
{"nom":"Dubois","prenom":"Francine"},
{"nom":"Charde","prenom":"François"},
{"nom":"Picq","prenom":"Laurent"},
{"nom":"Azafrar","prenom":"Abdelkarim"},
{"nom":"Nemili","prenom":"Hajer"},
{"nom":"Carvalho","prenom":"Rui"},
{"nom":"Foutard","prenom":"Jean-Marie"},
{"nom":"Othmani","prenom":"Idriss"}
],
"total":16
}
On remarque que les données sont encapsulées dans un objet racine appelé « list » , il existe plusieurs raisons à cela :
- Le composant Ext.data.Store qu’on va utiliser plus tard a besoin qu’on lui spécifie la racine des données.
- Si on met les données en vrac, c'est-à-dire sans racine, on ne pourrait pas mettre toutes les autres propriétés comme la propriété « total » ou eventuellement la propriété « id » qui indique le champ qui représente l’id dans la collection de données.
On se rend compte donc que la librairie Extjs impose un certain formatage des données ce qui doit être pris en compte très tôt dans la conception de l’architecture de votre application.
Du côté client, on va commencer par initialiser une page html « Extjs enabled » en ajoutant les rééfrences vers les fichiers js qu’il faut bien (voir cet article)
Ensuite, dans le body de la page on ajouter un div avec l’id « grid » et un lien vers une page Javascript vide dans le haeder (ici testfile.js). Voici la page html complète :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>test page</title>
<script type="text/javascript" src="../../ext-2.2.1/adapter/ext/ext-base.js"></script>
<!--script type="text/javascript" src="../../ext-2.2.1/ext-all.js"></script-->
<script src="../../ext-2.2.1/ext-all-debug.js" type="text/javascript"></script>
<script type="text/javascript" src="./testfile.js"></script>
<link rel="stylesheet" type="text/css" href="../../ext-2.2.1/resources/css/ext-all.css"/>
<link rel="stylesheet" type="text/css" href="../../css/Main.css"/>
</head>
<body>
<div id="grid"></div>
</body>
</html>
Pour peupler une grille on a besoin de :
- Une instance de la classe Ext.data.Record qui nous permet de définir la structure des lignes de données qu’on va afficher dans la grille et provenant du service web. Pour notre exemple, on a deux champs : nom et prenom. Pour instancier un objet de type Ext.data.Record il est conseillé d’utiliser la méthode « create » qui permet de renvoyer une nouvelle instance au lieu du constructeur.
var personne = Ext.data.Record.create([
{ name: 'nom' },
{name: 'prenom'}
]);
- Un reader permettant de créer un tableau d’objets de type « Ext.data.Record » à partir des données provenant du service web. Pour cela, il faut définir le nœud racine des données avec la propriété « root ». La structure d’un enregistrement en passant un objet de type « Ext.data.Record ». On peut aussi définir de manière optionnelle la propriété de l’objet récupéré du web service qui correspond au nombre total d’enregistrements qu’on va afficher dans la grille à l’aide de la propriété « totalProperty » ou encore la propriété de l’enregistrement qui correspond à l’id.
var myReader = new Ext.data.JsonReader({
totalProperty: "total",
root: "list"
}, personne
);
- Une instance de HttpProxy qui permet de lire des données à partir d’une URL.
var myProxy = new Ext.data.HttpProxy({
url: 'http://localhost/simplegrid/serveur/Person.svc/Get',
method: 'POST'
//params: {}
});
- Enfin une instance de Ext.data.Store est l’équivalent de l’objet DataSource en ASP.NET, le store fournit les données pour les composants UI comme le ComboBox, GridPanel, … Pour instancier un Store
var store = new Ext.data.Store(
{
proxy: myProxy,
reader: myReader
}
);
Une fois on a une instance de Store, on instancie le GridPanel de la manière suivante :
var gr = new Ext.grid.GridPanel({
el: 'grid', //div dans la quelle le GridPanel sera dessiné
viewConfig: { //Fait en sorte que la somme des largeurs de colonnes soit égale à la taille de la grille
forceFit: true
},
ds: store, // la source de données
cm: new Ext.grid.ColumnModel([ //Définit les colonnes du tableau et le mapping avec les champ du Record
{header: "Nom", width: 120, sortable: true, dataIndex: 'nom' },
{header: "Prenom", width: 100, sortable: true, dataIndex: 'prenom' }
]),
sm: new Ext.grid.RowSelectionModel({ singleSelect: true }),// Politique de séléction de ligne (Sélection simple)
width: 600, //largeur de la grille
height: 300, //hauteur de la grille
frame: true, //dessine la grille avec un contour arrondit
title: 'Grid Panel Example' //titre de la grille
});
Le ColumnModel permet de définir les colonnes du tableau, pour chaque colonne on doit définir au minimum :
- Header : le texte d’en-tête de colonne
- dataIndex : permet de mapper la colonne avec les données provenant du store, ce champ correspond à l’attribut « name » de l’objet Record.
L’attribut sortable est optionnel et permet de mettre en place le tri pour la colonne en question.
Il ne reste plus maintenant qu’à afficher la grille et charger les données à partir du store :
//Afficher la grille
gr.render();
//Charger les données
store.load({});
Voici le résultat :
Conclusion :
Ce qu’on a fait ici c’est le tableau le plus basique qu’on peut faire avec le framework extjs, on peut bien évidemment l’enrichir avec la sélection multiple, la pagination en utilisant la bbar ou encore rajouter des fonctions de groupage par champ implémentées par le framework extjs.
Mais au delà de la grille qu’on a dessinée, on remarque encore et toujours le côté simple et intuitif de ce framework.