Ajouter le support de l’Intellisense de ExtJs sous Visual Studio 2008#

J’ai eu à montrer ExtJs récemment pour les contrôles UI puissants et aboutis qu’il propose, et comme d’habitude j’ai eu droit aux réflexions du genre : c’est bien  mais c’est galère sans l’intellisense!!! à croire qu’on ne peut plus s’en passer ce que je comprends tout à fait, on s’habitue très vite au confort et nous avons du mal à s’en séparer :) c’est souvent vécu comme une régression.

Voici la solution pour bénéficier de l’IntelliSense ExtJs sous Visual Studio :

- Glissez déplacer respectivement vos fichiers ext-base.js et ext-all-debug.js au tout début du fichier Javascript dans le quel vous voulez utiliser ExtJs, vous devriez avoir ces deux lignes

/// <reference path="../Framework/ext-2.2.1/adapter/ext/ext-base.js" />
/// <reference path="../Framework/ext-2.2.1/ext-all-debug.js" />

- Appuyez maintenant sur Ctrl + Shift + J, Visual Studio va mettre à jour l’intellisense

Et voilà, lorsque vous tapez maintenant Ext. dans votre fichier JS vous allez pouvoir parcourir l’intellisense ExtJs sous Visual Studio, dorénavant vous n’aurez plus aucune excuse pour ne pas utiliser ExtJs ;)

Sunday, December 13, 2009 11:09:39 PM (Romance Standard Time, UTC+01:00) #    Comments [2]  | 

 

Pagination dans une grille extjs (Ext.grid.GridPanel) avec des données JSON provenant d’un service WCF#

Dans cet article on va partir de la grille basique qu’on a construit dans l’article précédent et on va lui rajouter la pagination. On peut donc reprendre tout le code et avant de rentrer dans le vif du sujet on va changer la méthode de la requête http au web service de POST en GET dans l’objet HttpProxy, comme ceci :

var myProxy = new Ext.data.HttpProxy({
    url: 'http://localhost/pagedgrid/serveur/Person.svc/Get',
    method: 'GET'
    
});

Bien évidemment et par voie de conséquence on doit aussi changer le service pour accepter les requêtes GET, il suffit alors de changer le tag WebInvoke en WebGet. (Le code du service est joint ci-dessous).

Vous vous demandez certainement : « Mais pourquoi il change le POST en GET ? » Tout simplement parce que la PagingToolbar a quelques problèmes à fonctionner avec la méthode POST et il faut faire un Workaround en introduisant les extensions pour que ça marche. Même si la solution est connue je préfère commencer avec la solution la plus simple pour que vous ne soyez pas confus.

Maintenant que tout ça est fait, on va commencer les choses sérieuses. Il s’agit donc de rajouter en bas du tableau une barre de pagination. Pour ce faire, on va utiliser une classe toute prête qui s’appelle Ext.PagingToolbar qui permet de faire de la pagination. Cette classe prend en paramètre

- la taille de la page (par défaut c’est égal à 20)

- le store lui permettant de ramener les données

Le store va ramener des données avec un total, la paging toolbar va alors :

- Calculer le nombre de pages

- Se positionner à la première page

Et à chaque fois qu’on va cliquer sur le bouton « Page suivante » la paging toolbar va consulter le store pour avoir les données de la page suivante en concaténant aux paramètres de la requête http deux paramètres :

- start : l’index du premier enregistrement de la page suivante (commence à zéro)

- limit : la taille de la page

Pour inclure la Paging toolbar dans le GridPanel, il y a la configOption bbar (Bottom bar) qui permet d’insérer une barre située en bas du tableau en opposition à tbar (toolbar) qui elle est positionée en haut du tableau. Voici le bout de code à ajouter à votre GridPanel pour ajouter la pagination :

bbar: new Ext.PagingToolbar({
    pageSize: 5,
    store: store
}),

L’objet GridPanel devient alors :

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
    bbar: new Ext.PagingToolbar({
        pageSize: 5,
        store: store
    }),
    title: 'Grid Panel Example' //titre de la grille

});

Donc tout ce que fait la paging toolbar c’est nous préparer le terrain pour faire de la pagination. Il nous reste du travail à faire côté serveur pour ramener les bonnes données puisqu’il faut que mon service accepte les deux paramètres start et limit envoyés par la paging toolbar et renvoyer les données en conséquence. (Vous trouverez ci-joint le code du service modifié)

La paging toolbar n’envoie pas les paramètres start et limit à l’initialisation du tableau, donc il faut bien faire attention de les initialiser au load du store de la manière suivante :

store.load({params: {start:0, limit:5}});

Ces deux paramètres seront écrasés dans la requête http par ceux envoyés par la paging toolbar à chaque changement de page.

Voici le résultat en utilisant les mêmes données que l’article précédent:

image

En ce qui concerne l’utilisation de la paging toolbar avec la méthode POST, je publierais bientôt un article qui explique le problème qui se pose et la solution proposée.

Code côté client (Javascript) 

Extjs | Javascript | WCF
Friday, March 20, 2009 10:23:34 PM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

Remplir une grille extjs (Ext.grid.GridPanel) avec des données JSON provenant d’un service WCF#

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 :

image

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.

Partie Serveur (Services WCF) : serveur.zip

Partie Serveur (Services WCF) : serveur.zip

Partie Serveur (Services WCF) : serveur.zip

Extjs | Javascript | WCF
Monday, March 16, 2009 10:46:17 AM (Romance Standard Time, UTC+01:00) #    Comments [1]  | 

 

TreePanel : Construire un arbre Extjs avec des données statiques#

Comme promis dans l’article Hello World, on va commencer à aborder les choses sérieuses. Dans cet article on va dessiner un arbre avec des données statiques en format JSON. On va tout d’abord, initialiser une page “extjs enabled” en ajoutant les références vers les fichiers js qu’il faut bien (voir cet article)

L’arbre contiendra les données hiérarchisées des modes de transports comme ceci :

La racine sera « Modes de transport » qui contiendra 2 nœuds enfants : « Transport en commun » et « Transport privatif ». le Transport en commun contiendra les nœuds enfants suivants : « Train », « Métro »,et « Bus »… Et ainsi de suite. Voici les données en format JSON :

var moyensDeTransport = [{ "text": "Transport en commun", "id": "11", "leaf": false, "cls": "folder", "children": [ { id: "111", text: "Train", "leaf": false, "cls": "file", "children": [ { id: "1111", text: "TGV", "leaf": true, "cls": "file", "children": [] }, { id: "1112", text: "Corail", "leaf": true, "cls": "file", "children": [] }, { id: "1113", text: "TER", "leaf": true, "cls": "file", "children": [] } ] }, { id: "112", text: "M&eacute;tro", "leaf": true, "cls": "file", "children": [] }, { id: "113", text: "Bus", "leaf": true, "cls": "file", "children": [] } ]},

{ "text": "Transport privatif", "id": "12", "leaf": false, "cls": "folder", "children": [ { id: "11", text: "Voiture", "leaf": true, "cls": "file", "children": [] }, { id: "21", text: "Taxi", "leaf": true, "cls": "file", "children": [] } ]} ];

 

L’objet arbre du framework extjs est le Ext.Tree.TreePanel. On peut l’instancier d’une manière très simple : var arbre = new Ext.Tree.TreePanel() ; Sauf que de cette façon on a juste instancier un objet en mémoire de type TreePanel mais nous ce qu’on veut c’est l’afficher dans notre page, il faut donc configurer l’objet, pour cela on a deux manières de faire :

- En utilisant les Config Options du constructeur (la méthode la plus couramment utilisée)

- En utilisant les méthodes publiques de l’objet après l’avoir instancié

Dans cet article on va utiliser les Configs Options. Pour ce faire, il faut tout simplement passer en paramètre au constructeur un objet JSON contenant toutes les configs options qu’on veut remplir comme ceci :

var arbreMoyensDeTransport = new Ext.tree.TreePanel({
    el: 'container', //l’id de l’élément html qui va contenir l’arbre (div)
    animate: true, //animer l’arbre lors des expand / collapse
    enableDD: false, //Désactiver le Drag and drop
    loader: treeloader, //Le composant qui va charger l’arbre// Note: no dataurl, register a TreeLoader to make use of createNode()
    autoHeight: true, //la hauteur du conteneur de l'arbre s’adapte à la hauteur de l’arbre
    selModel: new Ext.tree.DefaultSelectionModel(), //Par défaut c’est le singleSelectionModel, définit la politique de sélection dans l’arbre  
    rootVisible: true //La racine est visible
});

 

Pour l’instant on a créé une instance de l’arbre mais on ne l’a pas encore lié avec les données qu’il doit contenir. Pour cela on va tout d’abord instancier le type Ext.tree.AsyncTreeNode en passant à la config option ‘children’ l’objet JSON déclaré ci-dessus de la manière suivante :

// set the root node
var root = new Ext.tree.AsyncTreeNode({
    text: 'Moyens de transport', //texte du noeud
    draggable: false, // Désactiver le Drag and drop sur ce noeud
    id: '1', // identifiant du noeud
    children: moyensDeTransport //Objet JSON contenant la structure de l’arbre

});

Ensuite on va appeler la méthode publique ‘setRootNode’ de TreePanel permettant de définir le nœud racine de l’arbre :

arbreMoyensDeTransport.setRootNode(root);

Il ne reste plus qu’à afficher le résultat :

arbreMoyensDeTransport.render();

 

Voici le résultat :

image

On vient donc d’utiliser un objet de type Ext.tree.TreePanel qu’on a lié à des données statique au format JSON pour construire et afficher un arbre dans un page.

Conclusion :

Quelques remarques à noter après ce premier article :

- Extjs est un framework javascript objet (Comme dit au départ)

- Tous les constructeurs de n’importe quel type d’objet du framwork Extjs prennent en paramètre un objet JSON.

- Les contrôles Extjs sont bindabable à des données sous le format JSON

Friday, February 20, 2009 2:30:12 PM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

Débuter avec Extjs : Hello World#

La première chose à faire pour commencer à programmer avec Extjs c'est de télécharger le framework ici (http://extjs.com/products/extjs/download.php)

Pour utiliser le framework Extjs au sein de votre page web il suffit d'ajouter ces deux balises de script dans la balise head comme ceci (ext-2.2.1 est le répertoire contenant le framework):

<head>

... <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>

...

</head>

En incluant ces deux fichiers dans notre page on peut déjà utiliser toutes les fonctionnalités et les composants qu'offre le framework extjs. Mais il est recommandé d'inclure aussi le fichier css pour avoir un rendu un peu plus joli.

<head>

...

<link rel="stylesheet" type="text/css" href="./ext-2.2.1/resources/css/ext-all.css"/>

... </head>

Il ne reste plus qu'à écrire notre code pour faire une alerte de Hello World. Créer un fichier .js vide et y inclure les quelques lignes suivantes :

var Startup = {

    init : function(){
            Ext.Msg.alert('Hello', 'My hello world with Extjs'); 
    }
}

Ext.onReady(Startup.init, Startup);
 

Startup est un objet contenant la fonction init qui va s'exécuter au démarrage de l'application. Ext.onReady() est une fonction qui est déclenchée lorsque le document est prêt, elle prend en paramètre la fonction à exécuter et le contexte (scope).

Enfin inclure le fichier javascript que vous venez de créer dans votre page html.

Voici le résultat :

image

Vous venez d’utiliser Extjs pour la première fois, je sais ce n'est pas transcendant :) mais il faut bien commencer par le début. Dans les prochains articles on essayera d'aller plus en détail et de faire des choses un peu plus poussées pour voir la puissance de ce framework.

 

 

Sunday, February 15, 2009 2:23:00 PM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

Extjs : Tout ce dont vous avez besoin en javascript#

Au sein des applications SOA, la couche de présentation est de plus en plus souvent développée en full AJAX. Le langage Javascript est un langage très puissant mais au niveau interface utilisateur, il ne met pas à la disposition des développeurs autre chose que les contrôles HTML. Donc pour faire des contrôles évolués comme une belle grille qu’on pourrait binder à une collection de données par exemple, il faut tout écrire à la main ce qui fait généralement fuir les développeurs et décourage les architectes parce qu’il y a tout à faire et c’est une porte ouverte à du code mal écrit,… Pour dé complexifier le code javascript, on a à notre disposition plusieurs frameworks qui proposent des composants tout prêt, mais malheureusement certains d’entre eux (même ceux qui sont payants) sont mal codés et sacrifient les performances ce qui est crucial pour du code qui s’exécute côté client.

Extjs est l’un des framaworks objet javascript les plus complets dédié à l’interface utilisateur. Il est très puissant et offre des composants UI légers, stylés et bindable à des collections de données (données statique ou via un web service). Il permet aussi de faire beaucoup d’autres choses comme de la manipulation de données, de la manipulation de chaînes de caractères, des requêtes AJAX, …


La communauté Ext est très active sur les forums, le seul point faible avec ce Framework c’est la documentation qui, même si elle est bien faite (facilité de recherche), elle n’est pas toujours à jour et manque considérablement d’exemples. C’est spécifiquement sur ce point qu’on va essayer de travailler. Utilisateur d’Extjs depuis quelques semaines, j’ai pris goût à l’utilisation de ce framework qui s’est avéré très intuitif à l’utilisation. Je vais donc essayer de poster des articles sur ce framework pour palier au manque d’exemples sur le net.

Je vous recommande donc vivement l’utilisation du framework Extjs pour votre couche de présentation et vous encourage à faire de même.

Saturday, February 14, 2009 8:52:51 PM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

All content © 2012, Zied Nemili