Dopo aver analizzato 3 dei principali plugin per JQuery inseriti nel repository ufficiale, nell'articolo precedente, possiamo iniziare a realizzarne uno tutto nostro.
Il plugin che scriveremo introdurrà come al solito il maggior numero di aspetti di JQuery, comprendendo l'argomento in maniera quasi totale. Realizzeremo uno script che permetterà di creare una mini interfaccia per sondaggi a partire da una semplice lista HTML. Oltre alla manipolazione dell'HTML vedremo alcuni aspetti basati sulla gestione degli eventi "interni" al plugin, alla scrittura/lettura di cookie e all'invio dei dati sul server in maniera asincrona tramite AJAX.
Per aggiungere funzionalità al framework basterà aggiungere una funzione all'oggetto jQuery.fn
tramite un costrutto di questo tipo:
jQuery.fn.myPlugin = function() {
return this.each(function(){
//logica implementativa del plugin
});
};
Ovviamente il nome myPlugin rispecchierà il nome scelto per il plugin e l'iterazione this.each
ci permette di implementare la logica non solo su un singolo elemento ma su un vettore
di elementi HTML. Sarà possibile invocare il plugin in questo modo:
// in questo caso eseguiremo la logica
// applicativa su tutti i div della pagina
$("div").myPlugin();
// in questo caso eseguiremo la logica applicativa
// solo su un div particolare
$("div#id-del-div").myPlugin();
Abbiamo quindi le basi per iniziare a realizzare il nostro plugin! Ecco la versione finale
Per la realizzazione ho utilizzato un ulteriore plugin di terze parti per l'accesso (sia in lettura che in scrittura) ai cookie. Il suo utilizzo è banale e ricalca la funzione setcookie utilizzata nel PHP.
Rispetto al solito adotteremo un approccio opposto: introdurremo subito tutto il codice completo del plugin e lo analizzeremo passo passo successivamente. Questo perchè il codice è relativamente breve e non presenta ostacoli di comprensione:
jQuery.fn.poll = function(o) {
o = jQuery.extend({
buttonText: "Invia",
buttonDisabledText: "Già votato",
optionalParams: {},
radioName: Math.random(),
errorMessage: "Si è verificato un errore",
confirmMessage: "Grazie per aver votato",
cookieName: "JQueryPoll",
url: "#",
cssClassName: "ul_poll"
}, o);
var buttonClickCallback = function() {
var ul = $(this).prev();
var els = ul.find("li input[@type=radio][@checked]");
if (els.length == 1) sendData(els.val())
else alert(o.errorMessage);
};
var sendData = function(answerIndex) {
var data = o.optionalParams;
data.answerIndex = answerIndex;
$.post(o.url, data, sendDataCallback);
};
var sendDataCallback = function(response,success) {
if(success != "success") alert(o.errorMessage);
else {
alert(o.confirmMessage);
$.cookie(o.cookieName, true);
button.text(o.buttonDisabledText);
button.attr("disabled", "true");
}
};
var buttonText = !$.cookie(o.cookieName) ? o.buttonText : o.buttonDisabledText;
var button = $("<button>"+buttonText+"</button>");
if($.cookie(o.cookieName)) button.attr("disabled", "true");
button.click(buttonClickCallback);
return this.each(function() {
var el = $(this);
el.addClass(o.cssClassName);
var els = el.children("li");
$.each(els, function(i,n) {
$(n).prepend("<input type='radio' value='"+i+"' name='poll_"+o.radioName+"'/>");
});
el.after(button);
});
}
Il codice del plugin è suddiviso in tre parti:
poll
Variabile | Descrizione |
---|---|
buttonText
|
il testo da mostrare sul pulsante di submit |
buttonDisabledText
|
il testo da mostrare sul pulsante di submit in caso di sondaggio già votato |
optionalParams
|
eventuali parametri secondari da inviare allo script server-side oltre alla risposta selezionata (per esempio un eventuale id) [il valore di default è un oggetto vuoto] |
radioName
|
il nome da assegnare agli elementi radio button (necessario per rendere il form vincolato ad un'unica scelta) [di default si utilizza un numero casuale] |
errorMessage
confirmMessage
|
messaggi da mostrare all'utente in caso di insuccesso e successo |
cookieName
|
nome del cookie dove verrà salvato lo stato |
url
|
url verso il quale effettuare la richiesta asincrona [di default è la pagina stessa] |
cssClassName
|
classe CSS assegnata all'ul per migliorare l'aspetto estetico [di default è ul_poll
|
Per l'assegnazione di queste variabili utilizziamo la comoda funzione di utilità esposta dal framework: estend
La seconda parte del codice include le varie funzioni invocate dal plugin:
- buttonClickCallback
- sendData
- sendDataCallback
La terza ed ultima parte si occupa invece della creazione della parte HTML necessaria. Viene creato prima di tutto un bottone con uno stato che dipende dalla presenza o meno del cookie che segnala un preventivo invio dei dati. La definizione del bottone avviene al di fuori del return per il fatto che esso rappresenta un membro globale del plugin in quanto deve essere accessibile anche da altri metodi (sendDataCallback
in primis).
Nel return invece viene modificata la struttura della pagina in quanto vengono inseriti dei radio button all'interno della lista e viene appeso alla fine di essa il bottone definito in precedenza.
Una volta definito il plugin basterà realizzare una pagina HTML di questo tipo:
<body>
<ul>
<li>Elemento 1.1</li>
<li>Elemento 1.2</li>
<li>Elemento 1.3</li>
<li>Elemento 1.4</li>
</ul>
</body>
ed invocare il plugin in questo modo:
$(document).ready(function() {
$("ul").poll({
optionalParams : {id:10}
});
});