Widgets d'extension de l'interface utilisateur jQuery


Widget Factory de jQuery UI facilite la création de widgets qui étendent les fonctionnalités des widgets existants. De cette façon, vous pouvez créer des widgets puissants basés sur ceux existants, et vous pouvez également apporter des ajustements subtils aux fonctions des widgets existants.

Remarque : Avant d'étudier ce chapitre, vous devez comprendre ce qu'est une fabrique de widgets et comment elle fonctionne. Si vous n'êtes pas familier avec ces connaissances, veuillez d'abord consulter le chapitre Comment utiliser Widget Factory.

Création d'une extension de widget

La création d'un widget via Widget Factory se fait en transmettant le nom du widget et un objet prototype à $.widget(). L'exemple suivant crée un widget « superDialog » dans l'espace de noms « personnalisé ».

$.widget( "custom.superDialog", {} );

Pour prendre en charge les extensions, $.widget() accepte éventuellement le constructeur d'un widget pour l'utiliser comme widget parent. Lorsque vous spécifiez un widget parent, transmettez-le comme deuxième argument, après le nom du widget et avant l'objet prototype du widget.

Tout comme l'exemple ci-dessus, nous allons également créer un widget "superDialog" dans l'espace de noms "custom". Mais cette fois, ce qui est transmis est le constructeur ($.ui.dialog) du widget de dialogue de jQuery UI, indiquant que le widget superDialog doit utiliser le widget de dialogue de jQuery UI comme widget parent.

$.widget( "custom.superDialog", $.ui.dialog, {} );

Ici, les deux widgets superDialog et dialog sont essentiellement équivalents, sauf que leurs noms et espaces de noms sont différents. Pour rendre notre nouveau widget plus distinctif, nous pouvons ajouter quelques méthodes à son objet prototype.

L'objet prototype du widget est le dernier paramètre passé à $.widget(). Jusqu'à présent, nos exemples ont utilisé un objet vide. Ajoutons maintenant une méthode à cet objet :

$.widget( "custom.superDialog", $.ui.dialog, {
    red: function() {
        this.element.css( "color", "red" );
    }
});
 
// Create a new <div>, convert it into a superDialog, and call the red() method.
$( "<div>I am red</div>" )
    .superDialog()
    .superDialog( "red" );

Maintenant superDialog a une méthode red(), qui changera la couleur de son texte en rouge. Notez comment Widget Factory définit automatiquement this sur une instance du widget. Pour obtenir la liste de toutes les méthodes et propriétés disponibles sur une instance, visitez la documentation de l'API Widget Factory.

Extension des méthodes existantes

Parfois, vous devez ajuster ou ajouter un comportement aux méthodes de widgets existantes. Vous pouvez spécifier le nom de la méthode comme nom de méthode qui doit être remplacé sur l'objet prototype. L'exemple suivant surcharge la méthode open() de dialogue. Puisque la boîte de dialogue est ouverte par défaut, "open" sera enregistré lorsque ce code sera exécuté.

$.widget( "custom.superDialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
    }
});
 
// Create a new <div>, and convert it into a superDialog.
$( "<div>" ).superDialog();

Lors de l'exécution de ce code, il y a un problème. Depuis que nous avons remplacé le comportement par défaut de open(), la boîte de dialogue ne s'affiche plus à l'écran.

Lorsque nous utilisons une méthode sur un objet prototype, nous surchargeons en fait la méthode d'origine et utilisons une nouvelle méthode dans la chaîne de prototypes.

Pour rendre les méthodes de widget parent disponibles, la fabrique de widgets propose deux méthodes : _super() et _superApply().

Utilisez _super() et _superApply() pour accéder au widget parent

_super() et _superApply() appelez la même méthode dans le widget parent. Voir l'exemple ci-dessous. Tout comme l'exemple précédent, cet exemple surcharge également la méthode open() pour enregistrer "open". Cependant, cette fois, l'exécution de _super() appelle open() de la boîte de dialogue et ouvre la boîte de dialogue.

$.widget( "custom.superDialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
 
        // Invoke the parent widget's open().
        return this._super();
    }
});
 
$( "<div>" ).superDialog();

_super() et _superApply() sont effectivement équivalents aux méthodes Function.prototype.call() et Function.prototype.apply() originales. Ainsi, _super() accepte une liste d'arguments et _superApply() accepte un tableau comme argument. L'exemple suivant montre la différence entre les deux.

$.widget( "custom.superDialog", $.ui.dialog, {
    _setOption: function( key, value ) {
 
        // Both invoke dialog's setOption() method. _super() requires the arguments
        // be passed as an argument list, _superApply() as a single array.
        this._super( key, value );
        this._superApply( arguments );
    }
});

Redéfinir les widgets

jQuery UI 1.9 a ajouté la possibilité de redéfinir les widgets. Par conséquent, au lieu de créer un nouveau widget, il nous suffit de transmettre $.widget() un nom et un constructeur de widget existants. L'exemple ci-dessous ajoute le même enregistrement dans open(), mais pas en créant un nouveau widget.

$.widget( "ui.dialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
        return this._super();
    }
});
 
$( "<div>" ).dialog();

Avec cette méthode, nous pouvons étendre une méthode de widget existante, mais toujours utiliser _super() pour accéder à la méthode d'origine - rien de tout cela n'est fait en créant un nouveau widget, mais redéfinissez simplement le widget directement.

Widgets et polymorphisme

Lors de l'interaction entre les extensions de widget et leurs plug-ins, il est important de noter que les plug-ins du widget parent ne peuvent pas être utilisés pour appeler des méthodes sur les éléments du widget enfant . L’exemple suivant le démontre.

$.widget( "custom.superDialog", $.ui.dialog, {} );
 
var dialog = $( "<div>" ).superDialog();
 
// This works.
dialog.superDialog( "close" );
 
// This doesn't.
dialog.dialog( "close" );

Dans l'exemple ci-dessus, le plug-in du widget parent, dialog(), ne peut pas appeler la méthode close() sur l'élément superDialog. Pour en savoir plus sur l’appel de méthodes de widget, consultez Appel de méthode de widget.

Exemples de personnalisation personnalisée

Les exemples que nous avons vus jusqu'à présent ont tous des méthodes qui s'étendent sur le prototype du widget. Les méthodes surchargées sur le prototype affectent toutes les instances du widget.

Pour démontrer cela, regardez l'exemple ci-dessous. Les deux côtés du dialogue utilisent la même méthode open().

$.widget( "ui.dialog", $.ui.dialog, {
    open: function() {
        console.log( "open" );
        return this._super();
    }
});
 
// Create two dialogs, both use the same open(), therefore "open" is logged twice.
$( "<div>" ).dialog();
$( "<div>" ).dialog();

Parfois, il vous suffit de modifier le comportement d'une certaine instance d'un widget. Pour ce faire, vous devez utiliser l'affectation de propriété JavaScript normale, obtenir une référence à l'instance et remplacer la méthode. Les détails sont présentés dans les exemples suivants.

var dialogInstance = $( "<div>" )
    .dialog()
    // Retrieve the dialog's instance and store it.
    .data( "ui-dialog" );
 
// Override the close() method for this dialog
dialogInstance.close = function() {
    console.log( "close" );
};
 
// Create a second dialog
$( "<div>" ).dialog();
 
// Select both dialogs and call close() on each of them.
// "close" will only be logged once.
$( ":data(ui-dialog)" ).dialog( "close" );

La technique de méthode surchargée pour les instances personnalisées est parfaite pour une personnalisation ponctuelle.