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.
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.
ExtJS 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.
Fonctionnement technique
ExtJS est un framework
JavaScript 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.
// 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).
// 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.
// 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.
// 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
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 :