Logo ExtJS

ExtJS

Un framework JavaScript complet de Sencha pour créer des applications web d'entreprise riches et complexes avec une expérience utilisateur de type bureau.

Pour les non-initiés

Qu'est-ce qu'ExtJS ?

Imaginez que vous devez créer une application complexe pour gérer toutes les opérations d'une entreprise : gestion des clients, inventaire, facturation, tableaux de bord analytiques, etc. Traditionnellement, ces applications étaient développées comme des logiciels à installer sur chaque ordinateur, mais aujourd'hui, on préfère souvent des solutions accessibles via un navigateur web.

Icône ExtJSExtJS est un framework JavaScript développé par Sencha qui permet de créer ces applications web complexes avec une expérience utilisateur proche de celle d'un logiciel de bureau. C'est comme avoir Microsoft Excel ou un logiciel de comptabilité directement dans votre navigateur, avec la même richesse fonctionnelle et la même efficacité.

Pourquoi ExtJS est si puissant ?

Composants riches et prêts à l'emploi

ExtJS propose plus de 140 composants prêts à l'emploi : grilles de données, graphiques, formulaires, arbres, onglets, et bien d'autres.

Gestion avancée des données

Système complet de gestion des données avec chargement, filtrage, tri, validation et synchronisation automatique avec le serveur.

En résumé, ExtJS permet aux entreprises de développer des applications web sophistiquées qui offrent une expérience utilisateur riche et efficace, particulièrement adaptée aux environnements d'entreprise où la productivité et la gestion de données complexes sont essentielles.

Pour les développeurs

Fonctionnement technique

Icône ExtJSExtJS est un framework Icône JavaScriptJavaScript orienté objet qui utilise des concepts avancés comme l'héritage de classe, les espaces de noms et les patterns de conception pour créer des applications web complexes.

Architecture et concepts clés

Composants UI

ExtJS est construit autour d'un système de composants extensibles. Chaque élément visuel, du simple bouton au tableau de bord complexe, est un composant qui peut être configuré, composé et étendu.

Exemple de définition d'un panel ExtJS
// Définition d'un panel ExtJS Ext.define('MyApp.view.example.Panel', { extend: 'Ext.panel.Panel', xtype: 'example-panel', requires: [ 'Ext.button.Button', 'Ext.form.field.Text' ], title: 'Mon Premier Panel', width: 500, height: 300, layout: 'vbox', bodyPadding: 10, items: [{ xtype: 'textfield', fieldLabel: 'Nom', name: 'name', allowBlank: false, width: '100%' }, { xtype: 'textfield', fieldLabel: 'Email', name: 'email', vtype: 'email', allowBlank: false, width: '100%' }, { xtype: 'textarea', fieldLabel: 'Message', name: 'message', grow: true, width: '100%' }], buttons: [{ text: 'Annuler', handler: 'onCancelClick' }, { text: 'Envoyer', formBind: true, handler: 'onSubmitClick' }] });

Modèles et Stores

La gestion des données dans ExtJS s'articule autour des modèles (qui définissent la structure des données) et des stores (qui gèrent la collection de données, le chargement et la synchronisation avec le serveur).

Exemple de modèle et store ExtJS
// Définition d'un modèle et store ExtJS Ext.define('MyApp.model.User', { extend: 'Ext.data.Model', fields: [ { name: 'id', type: 'int' }, { name: 'firstName', type: 'string' }, { name: 'lastName', type: 'string' }, { name: 'email', type: 'string' }, { name: 'role', type: 'string' }, { name: 'lastLogin', type: 'date' } ], validators: { email: [ { type: 'email', message: 'Format d'email invalide' } ] }, idProperty: 'id' }); Ext.define('MyApp.store.Users', { extend: 'Ext.data.Store', alias: 'store.users', model: 'MyApp.model.User', proxy: { type: 'ajax', url: '/api/users', reader: { type: 'json', rootProperty: 'data', totalProperty: 'total' } }, autoLoad: true, pageSize: 25, remoteSort: true, remoteFilter: true });

Architecture MVC/MVVM

ExtJS prend en charge les patterns MVC (Modèle-Vue-Contrôleur) et MVVM (Modèle-Vue-ViewModel) pour structurer l'application. Le binding de données permet de connecter les vues aux modèles de manière déclarative.

Exemple de grille ExtJS avec ViewModel et Contrôleur
// Définition d'une grille ExtJS avec ViewModel et Controller Ext.define('MyApp.view.user.Grid', { extend: 'Ext.grid.Panel', xtype: 'user-grid', requires: [ 'MyApp.view.user.GridController', 'MyApp.view.user.GridModel', 'MyApp.store.Users' ], controller: 'user-grid', viewModel: { type: 'user-grid' }, bind: { store: '{users}', selection: '{selectedUser}', title: 'Utilisateurs ({total})' }, columns: [{ text: 'ID', dataIndex: 'id', width: 70 }, { text: 'Prénom', dataIndex: 'firstName', flex: 1 }, { text: 'Nom', dataIndex: 'lastName', flex: 1 }, { text: 'Email', dataIndex: 'email', flex: 2 }, { text: 'Rôle', dataIndex: 'role', flex: 1 }, { text: 'Dernière Connexion', dataIndex: 'lastLogin', xtype: 'datecolumn', format: 'd/m/Y H:i:s', flex: 1.5 }, { xtype: 'actioncolumn', width: 120, items: [{ iconCls: 'x-fa fa-edit', tooltip: 'Modifier', handler: 'onEditClick' }, { iconCls: 'x-fa fa-trash-alt', tooltip: 'Supprimer', handler: 'onDeleteClick' }] }], tbar: [{ text: 'Ajouter', iconCls: 'x-fa fa-plus', handler: 'onAddClick' }, { text: 'Actualiser', iconCls: 'x-fa fa-sync', handler: 'onRefreshClick' }, '->', { xtype: 'textfield', emptyText: 'Rechercher...', reference: 'searchField', enableKeyEvents: true, listeners: { keyup: 'onSearchKeyUp', buffer: 300 } }], bbar: { xtype: 'pagingtoolbar', bind: { store: '{users}' }, displayInfo: true }, listeners: { itemdblclick: 'onItemDoubleClick' } }); // Modèle de la grille (ViewModel) Ext.define('MyApp.view.user.GridModel', { extend: 'Ext.app.ViewModel', alias: 'viewmodel.user-grid', stores: { users: { type: 'users' } }, data: { selectedUser: null }, formulas: { total: function(get) { var store = get('users'); return store ? store.getTotalCount() : 0; } } }); // Controlleur de la grille Ext.define('MyApp.view.user.GridController', { extend: 'Ext.app.ViewController', alias: 'controller.user-grid', onAddClick: function() { this.showUserForm(); }, onEditClick: function(grid, rowIndex) { var record = grid.getStore().getAt(rowIndex); this.showUserForm(record); }, onDeleteClick: function(grid, rowIndex) { var me = this, record = grid.getStore().getAt(rowIndex); Ext.Msg.confirm( 'Confirmation', 'Voulez-vous vraiment supprimer cet utilisateur ?', function(btn) { if (btn === 'yes') { me.deleteUser(record); } } ); }, onRefreshClick: function() { this.getViewModel().getStore('users').reload(); }, onSearchKeyUp: function(field) { var value = field.getValue(), store = this.getViewModel().getStore('users'); if (value) { store.filter({ property: 'query', value: value }); } else { store.clearFilter(); } }, onItemDoubleClick: function(grid, record) { this.showUserForm(record); }, showUserForm: function(record) { var win = Ext.create({ xtype: 'user-form-window', viewModel: { data: { user: record || null } } }); win.show(); }, deleteUser: function(record) { var store = this.getViewModel().getStore('users'); store.remove(record); store.sync({ success: function() { Ext.toast({ html: 'Utilisateur supprimé avec succès', align: 't', iconCls: 'x-fa fa-check' }); }, failure: function() { store.rejectChanges(); Ext.Msg.alert('Erreur', 'Une erreur est survenue lors de la suppression'); } }); } });

Application ExtJS

Une application ExtJS complète est organisée autour d'une classe principale d'application qui gère le cycle de vie, les routes et l'état global.

Exemple d'application ExtJS
// Application ExtJS Ext.application({ name: 'MyApp', extend: 'MyApp.Application', requires: [ 'MyApp.*', 'Ext.container.Viewport' ], mainView: 'MyApp.view.main.Main', launch: function() { // Logique de démarrage de l'application console.log('Application lancée avec succès'); // Vérification de l'authentification var token = localStorage.getItem('auth_token'); if (!token) { // Rediriger vers la page de connexion this.getMainView().getController().showLoginForm(); } else { // Valider le token côté serveur Ext.Ajax.request({ url: '/api/auth/verify', headers: { 'Authorization': 'Bearer ' + token }, success: function(response) { var result = Ext.decode(response.responseText); if (result.valid) { // Token valide, continuer Ext.GlobalEvents.fireEvent('userAuthenticated', result.user); } else { // Token invalide, afficher le formulaire de connexion localStorage.removeItem('auth_token'); this.getMainView().getController().showLoginForm(); } }, failure: function() { // Erreur de connexion, afficher le formulaire de connexion localStorage.removeItem('auth_token'); this.getMainView().getController().showLoginForm(); }, scope: this }); } } }); // Classe d'application étendue Ext.define('MyApp.Application', { extend: 'Ext.app.Application', mixins: ['Ext.mixin.Observable'], stores: [ 'Navigation', 'Users' ], defaultToken: 'dashboard', listen: { global: { userAuthenticated: 'onUserAuthenticated', userLogout: 'onUserLogout' } }, onUserAuthenticated: function(user) { // Stocker les informations utilisateur dans le localStorage localStorage.setItem('user_data', Ext.encode(user)); // Mise à jour des magasins de données Ext.getStore('Navigation').reload(); // Rediriger vers le tableau de bord this.redirectTo('dashboard'); }, onUserLogout: function() { // Nettoyer les données d'authentification localStorage.removeItem('auth_token'); localStorage.removeItem('user_data'); // Rediriger vers la page de connexion this.getMainView().getController().showLoginForm(); } });

Fonctionnalités principales

  • Composants UI riches - Plus de 140 composants prêts à l'emploi : grilles, arbres, graphiques, formulaires, etc.
  • Layouts - Système de mise en page avancé (border, fit, card, hbox, vbox, table, etc.)
  • Data Package - Gestion complète du cycle de vie des données avec validation
  • Data Binding - Liaison des données entre les vues et les modèles, dans les deux sens
  • Class System - Système de classes orienté objet avec héritage, mixins et plugins
  • Thèmes - Support de thèmes multiples et personnalisables
  • Accessibilité - Support ARIA pour l'accessibilité
  • Internationalisation - Support complet pour les applications multilingues

Outils et écosystème

  • Sencha Cmd - Outil en ligne de commande pour la compilation, le packaging et le déploiement
  • Sencha Architect - Environnement de développement visuel pour ExtJS
  • Sencha Test - Framework de test pour applications ExtJS
  • Sencha Themer - Outil pour créer et personnaliser des thèmes
  • ExtGen - Générateur de code pour accélérer le développement
  • Sencha Fiddle - Environnement en ligne pour tester rapidement des exemples de code
Applications concrètes

Cas d'usage

Tableaux de bord analytiques

Les tableaux de bord d'analyse de données complexes bénéficient des composants de visualisation riches d'ExtJS, comme les graphiques interactifs et les grilles pivotantes.

Applications de gestion d'entreprise

Systèmes de gestion complets : ERP, CRM, gestion des ressources humaines, gestion financière, et autres applications d'entreprise avec des interfaces riches.

Outils de planification

Applications de planification et de gestion de calendrier, avec glisser-déposer, gestion des ressources et vues multiples (jour, semaine, mois).

Systèmes de reporting

Applications de reporting avec manipulation avancée des données, filtrage dynamique, exportation et impression de rapports personnalisés.

Entreprises qui utilisent ExtJS

De nombreuses grandes entreprises utilisent ExtJS pour leurs applications critiques :

Cisco
Samsung
Boeing
Adobe
IBM
Siemens
Canon
Garmin