jQuery plugin

Oggi ho realizzato un piccolo plugin in jQuery che ben si presta a fare da breve introduzione allo sviluppo di plugin per il famoso framework javascript.

Quello di cui avevo bisogno era un plugin per simulare il comportamento della pseudo-classe “focus” in modo da renderla compatibile con tutti i browser. Nella fattispecie quando ci si posiziona su un campo di input, a questo viene aggiunta una classe in modo da cambiarne lo stile. In questo modo si evidenzia all’utente il campo in cui sta operando favorendo l’accessibilità e l’usabilità.

Ma veniamo al sodo. Il comando base che useremo per estendere jQuery è il metodo $.fn.nomePlugin = function() {}. Possiamo passare alla funzione i parametri per la configurazione, nel caso il nostro plugin ne abbia bisogno. La prassi è di utilizzare come parametro un singolo oggetto contenente i vari parametri, in modo da rendere il codice più leggibile ed espandibile. Nel nostro caso è sufficiente un unico parametro che sarà il nome della classe che verrà aggiunta agli elementi durante il focus. Cominciamo quindi a scrivere:

$.fn.pseudoFocus = function(params) {
    defaults = {classe: 'hasFocus'};
    options = $.extend(defaults, params);
}

Come vedete utilizzo il parametro params per i valori passati dall’utente e defaults per le impostazioni di default appunto. Tramite il comando $.extend(defaults, params) jQuery “estende” i valori di default con i nuovi valori passati al plugin. In pratica vengono modificati solo i parametri diversi da quelli di default, lasciando gli altri inalterati.

Ora che abbiamo tutte le informazioni passiamo alla funzionalità vera e propria del plugin:

$.fn.pseudoFocus = function(params) {
	//valori di default
    defaults = {classe: 'hasFocus'};
    options = $.extend(defaults, params);

    return this.each(function() {
    	var element = $(this); //opero sull'elemento che qui è individuato da "this"
    	//qui va il nostro codice...
    });

}

Come evidenziato da return this.each(function() {...}) il corpo del plugin deve ritornare un ciclo. Questo perché jQuery opera su tutti gli elementi individuati dal selettore usato, quindi nel caso in cui ce ne siano più d’uno dovremo eseguire il plugin su ciascuno di essi. All’interno del nostro ciclo quindi il singolo elemento sarà individuato da $(this). Per comodità assegnamo l’elemento ad una variabile che ho chiamato element.

Il nostro plugin, come accennato prima, deve aggiungere agli elementi la classe desiderata durante l’evento focus e rimuoverla durante l’evento blur. Aggiungiamo quindi questi metodi:

$.fn.pseudoFocus = function(params) {
	//valori di default
    defaults = {classe: 'hasFocus'};
    options = $.extend(defaults, params);

    return this.each(function() {
    	var element = $(this); //opero sull'elemento che qui è individuato da "this"
    	//qui va il nostro codice...
    	element.focus(function() {
    		element.addClass(options.classe);
    	});
    	element.blur(function() {
    		element.removeClass(options.classe);
    	});
    });
}

Come vedete all’interno dei due metodi appena citati viene aggiunta o tolta la classe grazie a element.addClass(options.classe) e element.removeClass(options.classe), i metodi di jQuery per manipolare le classi. Come vedete ho utilizzato il nostro oggetto options che contiene la classe desiderata (sia essa quella di default o quella fornita in fase di inizializzazione del plugin).

Ci rimane però un ultimo step. Come vedete abbiamo sempre utilizzato l’abbreviazione $ al posto di jQuery. Questo potrebbe generare conflitti con altre librerie che utilizzano lo stesso metodo (prototype e motools, tanto per citarne due…). Per fortuna possiamo sfruttare la sintassi di javascript per aggiungere una “schermatura” (in inglese “closure”) in modo da poter utilizzare liberamente il dollaro all’interno del plugin senza però interferire con ciò che viene usato all’esterno. Per farlo basta utilizzare la forma (function($) {…})(jQuery). Questa non fa altro che definire la funzione anonima function($) {...} ed utilizzarla subito passando come parametro jQuery. In questo modo $ diventa una variabile interna alla funzione e quindi il nostro plugin può utilizzarla liberamente.

Il plugin finito è quindi:

(function($) {
    $.fn.pseudoFocus = function(params) {
	    //valori di default
        defaults = {classe: 'hasFocus'};
        options = $.extend(defaults, params);

        return this.each(function() {
    	    var element = $(this); //opero sull'elemento che qui è individuato da "this"
            //qui va il nostro codice...
            element.focus(function() {
                element.addClass(options.classe);
            });
            element.blur(function() {
                element.removeClass(options.classe);
            });
        });
    }
})(jQuery)

Salviamo il file come jquery.pseudoFocus.js nella stessa cartella di jQuery. Per utilizzarlo dobbiamo richiamarlo nella pagina subito dopo il tag “script” che richiama jQuery. Dovremo poi eseguirlo dopo il caricamento del DOM tramite la sintassi $(document).ready(...):

<script type="text/javascript" src="jquery.js">
<script type="text/javascript" src="jquery.pseudoFocus.js">

$(document).ready(function() {
    $('input[type=text], input[type=password], textarea').pseudoFocus({classe: 'miaClasse'});
});

Come vedete vengono prelevati gli input di tipo text, password e le textarea (ma avrei potuto utilizzare un qualsiasi elemento) e viene loro assegnato l’effetto focus tramite la classe “miaClasse”. Basterà realizzare un css adeguato e il gioco sarà fatto.

Come considerazione finale c’è da dire che la pseudo-classe focus è supportata da molti browser moderni e quindi l’esecuzione del plugin non è sempre necessaria. Ci basterebbe infatti utilizzare “:focus” nel css al posto di .miaClasse ed avremmo il medesimo effetto.

Non ho voluto dilungarmi su questo ma focalizzarmi su come stendere un semplice plugin. Nell’utilizzo reale avremmo potuto controllare la versione del browser tramite $.browser e decidere di conseguenza se applicare o meno la classe.

2 Comments so far

  1. gpasci on settembre 26th, 2008

    ottima guida alla stesura di un plugin,
    finalmente capisco a cosa serve la closure (function(){…})(jquery).
    blog molto interessante, sto seguendo il tuo approccio a code igniter, a quando il prossimo step?

    buon lavoro ;)

  2. cescopag on settembre 26th, 2008

    Grazie gpasci! Sono contento di essere utile!
    Per quanto riguarda CodeIgniter purtroppo non ho avuto molto tempo per sviluppare l’applicazione e quindi mi manca il materiale d’esempio!
    Comunque ho l’intenzione di stendere il terzo step a breve!

Leave a reply