Développer un plugin jQuery UI : options et méthodes

Bookmark and Share
Jeudi 4 août 2011
Posté par Gilles Felix

Développer un plugin jQuery UI : options et méthodes
Après une pause vacances, reprenons notre tutoriel sur comment développer un plugin jQuery UI. Aujourd'hui, allons un peu plus loin dans les options et les méthodes.

Sommaire du tutoriel
Développer un plugin jQuery UI

  1. Introduction
  2. Mise en forme
  3. Options et méthodes
  4. Événements
  5. Fonctionnalités avancées
  6. Héritage

Faisons maintenant évoluer notre exemple fil rouge. Pour l'instant, on transforme un DIV en un bloc avec titre, dont le look dépend du thème jQuery UI choisi. Le but de l'étape du jour va être de pouvoir ouvrir et fermer notre bloc en cliquant sur son titre.

 


Ajoutons une méthode toggle

Commençons par écrire une méthode toggle qui aura comme but de cacher le contenu du bloc quand il est visible et lycée de Versailles.

Ajoutons une variable opened à nos options.

    options: {
        title: 'Titre',
        opened : true // Variable indiquant si le bloc est ouvert 
    },

Et voici maintenant notre méthode toggle (et ses sous-méthodes _open et _close).

    toggle : function() {
        var self = this;
        if (self.options.opened) {
            self._close();
        } else {
            self._open();
        }
        // On inverse la valeur de l'option opened
        self.options.opened = !self.options.opened;

        // On retourne l'instance du plugin pour préserver le chaînage des fonctions
        return self;
    }

    _close: function() {
        // On doit cacher tous les enfants du container sauf le titre
        this.uiBlocContainer.children().not(this.uiBlocTitle).hide();
    },

    _open: function() {
        // On doit afficher tous les enfants du container
        this.uiBlocContainer.children().show();
    },

Modifions également notre méthode _create pour tenir compte du paramètre opened.

    _create: function() {
        this.uiBlocContainer = $('<div></div>')
            .addClass('ui-bloc ui-widget ui-widget-content ui-corner-all')
            .insertAfter(this.element);

        this.element.addClass('ui-bloc-content').appendTo(this.uiBlocContainer);
        this._title();

        if (!this.options.opened) {
            // Si le bloc est initialisé avec le paramètre opened à false, on ferme le bloc
            this._close();
        }
    },

En l'état, notre plugin permet déjà d'ouvrir et fermer le bloc via un appel extérieur (la fonction toggle ne commençant pas par un underscore) et d'afficher un bloc fermé par défaut.

<div>
  <button id="action1">Changer le titre</button>
  <button id="action2">Alert : le titre</button>
  <button id="action3">Toggle</button>
</div>
<script type="text/javascript">
(function($) {
    $(function() {
        $('#monbloc').bloc({
            title : 'Hello world',
            opened : false // Ce bloc est fermé par défaut
        });

        // Le clic sur le bouton Toggle ouvre et ferme alternativement le bloc
        $('#action3').click(function() {
            // On rappelle la fonction bloc sur l'élément
            // avec en paramètre le nom de la fonction interne (toggle)
            $('#monbloc').bloc('toggle');
        }) ;
    });
})(jQuery);
</script>

 

Appellons toggle quand le titre est cliqué

Faisons maintenant en sorte qu'un clic sur la barre de titre déclenche ce fameux toggle. Pour cela, modifions notre méthode interne de génération du titre : _title.

    _title: function() {
        var self = this;

        this.uiBlocTitle = $('<h5></h5>').addClass('ui-bloc-title ui-widget-header ui-corner-top')
            .text(this.options.title)
            // On ajoute l'événement clic à notre titre
            .click(function(event) {
                self.toggle(event);
                return false;
            })
            .prependTo(this.uiBlocContainer);
    },

 

Pensons à l'utilisateur

Ce n'est déjà pas mal, mais, si on se place dans la peau de l'utilisateur, rien ne nous indique que le titre est cliquable. On va donc modifier le curseur au survol du titre et ajouter aussi une icône à droite de la barre de titre indiquant l'état d'ouverture / fermeture du bloc.

    _title: function() {
        var self = this;

        self.uiBlocTitle = $('<h5></h5>').addClass('ui-bloc-title ui-widget-header ui-corner-top')
            .text(self.options.title)
            .click(function(event) {
                self.toggle(event);
                return false;
            })
            .css('cursor', 'pointer') // On modifie le curseur au survol du titre
            .prependTo(this.uiBlocContainer);

        // On ajoute un SPAN à notre titre
        // la classe ui-bloc-title-toggle va nous servir à placer le SPAN à droite dans la barre de titre
        // la classe ui-icon associée à la classe ui-icon-pin-s
        // va transformer notre SPAN en une icône de tête d'épingle orientée sud (vers le bas)
        self.uiBlocTitleToggle = $('<span></span>')
            .addClass('ui-bloc-title-toggle ui-icon ui-icon-pin-s')
            .appendTo(self.uiBlocTitle);
    },

Ajoutons la classe ui-bloc-title-toggle à notre CSS.

.ui-bloc .ui-bloc-title {
    /* Le titre est en position relative pour permettre au picto toggle (classe ui-bloc-title-toggle)
    d'être positionné en absolu par rapport à lui */
    position: relative;
    margin: 0 0 10px;
    padding: 5px;
}
.ui-bloc .ui-bloc-title-toggle {
    position: absolute;
    right: 0.3em;
    top: 50%;
    width: 16px;
    margin: -8px 0 0 0;
    padding: 1px;
    height: 16px;
    display:block;
}

Et pour être au top, modifions l'icône en fonction de l'état d'ouverture / fermeture.

    _close: function() {
        this.uiBlocContainer.children().not(this.uiBlocTitle).hide();
        // L'icône de la barre de titre devient une tête d'épingle orientée vers l'ouest (west, donc vers la gauche)
        this.uiBlocTitleToggle.removeClass('ui-icon-pin-s').addClass('ui-icon-pin-w');
    },

    _open: function() {
        this.uiBlocContainer.children().show();
        // L'icône de la barre de titre devient une tête d'épingle orientée vers le sud (vers le bas)
        this.uiBlocTitleToggle.removeClass('ui-icon-pin-w').addClass('ui-icon-pin-s');
    },

 

Rendons la fonctionnalité toggle optionnelle

Pour finir ce chapitre du tutoriel, nous allons rendre la fonctionnalité toggle optionnelle. Pour cela, ajoutons une nouvelle variable à nos options.

    options: {
        title: 'Titre',
        togglable: true, // Variable indiquant si le bloc est ouvrable / fermable
        opened : true
    },

Il faut maintenant conditionner tout le code portant sur la fonctionnalité.

    _title: function() {
        var self = this;

        self.uiBlocTitle = $('<h5></h5>').addClass('ui-bloc-title ui-widget-header ui-corner-top')
            .css('cursor', 'pointer') 
            .prependTo(this.uiBlocContainer);

        $('<span></span>').text(self.options.title)
            .appendTo(self.uiBlocTitle);

        if (self.options.togglable) {
            // On ajoute l'événement clic à notre titre si le bloc est ouvrable / fermable
            self.uiBlocTitle.click(function(event) {
                self.toggle(event);
                return false;
            })

            self.uiBlocTitleToggle = $('<span></span>')
                .addClass('ui-bloc-title-toggle ui-icon ui-icon-pin-s')
                .appendTo(self.uiBlocTitle);
        }
    },

    toggle : function() {
        var self = this;

        //Si le bloc n'est pas ouvrable / fermable, on sort tout de suite
        if (!self.options.togglable) {
            return self;
        }

        if (self.options.opened) {
            self._close();
        } else {
            self._open();
        }
        self.options.opened = !self.options.opened;

        return self;
    }

 

La démo de notre plugin en l'état 

La démo porte maintenant sur deux blocs, un togglable, l'autre non .

 

La suite : les événements

Passons à la quatrième étape, les événements
Aucun commentaire
Laissez votre commentaire :