jQuery, come creare un plugin per validare i nostri form?

Nel mio ultimo articolo abbiamo gettato le basi per la creazione di plugins per il noto framework JavaScript “jQuery“. Ora utilizzeremo queste basi per creare un plugin che potrebbe farci risparmiare del prezioso tempo: Un validatore di Form.

Inizieremo dalla progettazione del plugin, questo vuol dire che risponderemo alle domande principali: Che cosa deve fare questo plugin? Quali sono i parametri che l’utente potrà configurare? Che cosa avverrà quando sarà trovato un errore?

Partiamo dal risultato finale di questa guida, infatti nel seguente link potrete vedere il plugin in funzionamento.

Bene, ora che abbiamo visto cosa è in grado di fare il nostro plugin procediamo.

I parametri di configurazione

Nella demo che hai appena visto, il plugin permette la configurazione di vari elementi, eccoli di seguito:

 // valori personalizzabili
var config = {
     'shaker'            : false
   , 'shakers'           : 5
   , 'showMessage'       : false
   , 'errorClass'        : 'error'
   , 'requiredClass'     : 'required'
   , 'requiredMail'      : 'mail'
   , 'requiredNumber'    : 'numeric'
   ,    messages : {
               'blank'        : 'Questo campo non può rimanere vuoto!'
             , 'check'        : 'Questo campo deve essere selezionato!'
             , 'email'        : 'Inserire un indirizzo email valido!'
           	 , 'numbe'        : 'Inserire un numero!'
}
};

Esaminiamo di seguito ogni opzione e vediamo che cosa ci possiamo fare:

shaker

  • Tipo di parametro
    boolean – ciò significa che può assumere solamente due valori: Vero o Falso (in questo caso true o false).
  • Funzionamento
    il parametro shaker serve a riprodurre un effetto di vero e proprio “shaker”, e quindi lo scuotimento dell’input in questione
  • Valore di default
    false – questo significa che, se non diversamente specificato, l’effetto shaker non verrà riprodotto.

shakers

  • Tipo di parametro
    integer – vale a dire numero intero;
  • Funzionamento
    questo parametro indica il numero di volte che il nostro shaker si dovrà ripetere.
  • Valore di default
    5 – se abilitato l’effetto shaker verrà ripetuto 5 volte.

showMessage

  • Tipo di parametro
    boolean – infatti può essere abilitato (true) o disabilitato (false)
  • Funzionamento
    se abilitato questo parametro permette la visualizzazione di un messaggio di errore
  • Valore di default
    false – questa opzione di default è disabilitata

errorClass

  • Tipo di parametro
    string – questo parametro accetta come valore una stringa
  • Funzionamento
    questo parametro serve ad indicare il nome della classe da assegnare ai relativi input, select etc. in caso di errore
  • Valore di default
    ‘error’ – la classe che verrà assegnata sarà: error

requiredClass

  • Tipo di parametro
    string – il parametro accetta come valore una stringa
  • Funzionamento
    questa opzione serve ad indicare il nome della classe che devono avere gli elementi da essere validati
  • Valore di default
    required – tutti gli input, select etc. che verranno validati dovranno avere la classe required

requiredMail

  • Tipo di parametro
    string – il parametro accetta come valore una stringa
  • Funzionamento
    tramite questo parametro possiamo definire la classe che deve avere il campo che verrà validato come email (verrà quindi verificato che sia presente il simbolo ‘@’ ed il punto ‘.’)
  • Valore di default
    mail – tutti i campi nei quali vogliamo fare il controllo della sintassi di un indirizzo email dovranno avere la classe mail (oltre alla classe required)

requiredNumber

  • Tipo di parametro
    string – il parametro accetta come valore una stringa
  • Funzionamento
    questa opzione indica il nome della classe che dovranno avere gli input da validare come numerici (quindi nei quali potranno essere inseriti soltanto numeri)
  • Valore di default
    numeric

messages

Questo parametro contiene, a sua volta, altri parametro che servono a definire i messaggi da visualizzare in caso di errori.
Vediamoli di seguito

blank

  • Tipo di parametro
    string – il parametro accetta come valore una stringa
  • Funzionamento
    indica il messaggio da visualizzare nel caso nel campo non venga inserito alcun valore
  • Valore di default
    ‘Questo campo non può rimanere vuoto!’

check

  • Tipo di parametro
    string – il parametro accetta come valore una stringa
  • Funzionamento
    indica il messaggio da visualizzare nel caso che l’input sia di tipo ‘checkbox’ e che non venga selezionato
  • Valore di default
    ‘Questo campo deve essere selezionato!’

email

  • Tipo di parametro
    string – il parametro accetta come valore una stringa
  • Funzionamento
    indica il messaggio da visualizzare nel caso sia stato richiesto un indirizzo email ma il valore inserito non corrisponda
  • Valore di default
    ‘Inserire un indirizzo email valido!’

numbe

  • Tipo di parametro
    string – il parametro accetta come valore una stringa
  • Funzionamento
    indica il messaggio da visualizzare nel caso che il valore richiesto sia di tipo numerico ma quello inserito non corrisponda
  • Valore di default
    ‘Inserire un numero!’

Abbiamo visto quali sono i parametri di configurazione di plugin, e come hai potuto notare possiamo configurare dall’effetto desiderato in caso di errore al messaggio da visualizzare.
Ovviamente i parametri per la configurazione del plugin potrebbero essere molti di più, sta solo a te decidere cosa permettere e che cosa no!

Che cosa deve succedere quando il form viene inviato?

Come abbiamo già detto all’inizio di questo articolo e bene porci tutte le domande possibili affinchè venga decisa ogni singola funzionalità del plugin.

Alcune domande potrebbero sembrare banali e/o scontate, ma sono le domande che stanno alla base del funzionamento.

Puoi vedere nel seguente grafico (molto semplice) che cosa avviene quando viene premuto il bottone di invio del form:

Il nostro form viene validato nel momento in cui l’utente decide di inviare i dati inseriti.
Se i dati inseriti risultano corretti, il form viene inviato, se invece, viene trovato uno o più errori, il form non viene inviato, ed agli elementi dove è stato trovate l’errore, viene aggiunta la classe ‘error’ (la classe error può essere personalizzata).

Come intercettiamo l’invio del form utilizzando jQuery ?

Per intercettare l’invio del form utilizzeremo la funzione submit di jQuery.
Come sempre, ti suggerisco di iniziare dalla documentazione ufficiale, che puoi trovare facendo click qui.

Il metodo submit() si occupa di assegnare una funzione all’evento “Submit di JavaScript“, questo evento si “scatena” quando un utente si appresta ad inviare un form.

Iniziamo a scrivere il nostro plugin

Vediamo ora il codice che utilizzeremo per definire il nostro plugin:

(function($) {
    $.fn.validMe = function(options) {
        // Qua tutto ciò che  il nostro plugin dovrà fare
}
})(jQuery);

Con il codice precedente abbiamo creato una funzione che ci permette di utilizzare l’alias $ all’interno del nostro plugin.
Successivamente abbiamo creato la funzione validMe, che verrà poi richiamata utilizzando la seguente sintassi:

$(selettore).validMe();

Dove ‘selettore‘ sta per qualsiasi tipo di selettore di jQuery, ecco qualche esempio:

  • $('form.myForm').validMe();

    ogni formulario che abbia la classe ‘myForm’

  • $('div.content  > form').validMe();

    ogni formulario all’interno dei div che abbiano come classe ‘content’

  • $('form[name=myForm]').validMe();

    ogni formulario che abbia come attributo name il valore ‘myForm’

Inoltre, il nostro plugin accetta come parametro un’oggetto che conterrà le opzioni, che ci occuperemo di definire a breve.

Per quanto riguarda la sintassi usata per definire il plugin, e/o il perchè abbiamo scelto questo metodo, vi rimando all’articolo sulla base per creare un plugin.

Permettiamo agli utenti di personalizzare il plugin

All’inizio di questo articolo abbiamo visto quali saranno i parametri che gli utenti potranno personalizzare, ora trasformiamo quanto detto in codice:

(function($) {
$.fn.validMe = function(options) {

    // valori personalizzabili
    var config = {
          'shaker'                  : false
        , 'shakers'                 : 5
        , 'showMessage'             : false
        , 'errorClass'              : 'error'
        , 'requiredClass'           : 'required'
        , 'requiredMail'            : 'mail'
        , 'requiredNumber'          : 'numeric'
        ,  messages : {
                  'blank'   : 'Questo campo non può rimanere vuoto!'
                , 'check'   : 'Questo campo deve essere selezionato!'
                , 'email'   : 'Inserire un indirizzo email valido!'
                , 'numbe'   : 'Inserire un numero!'
           }
    };

    // estendiamo i valori di default con quelli specificati dall'utente
    if (options) $.extend(config, options);

}
})(jQuery);

Nel precedente codice possiamo notare la creazione dell’oggetto config, il quale possiede vari parametri, come ad esempio la classe che dovranno avere gli elementi da validare, oppure la classe che verrà assegnata in caso di errore.

Notiamo come l’oggetto config possiede a sua volta un ulteriore oggetto: messages.
Così facendo possiamo organizzare al meglio tutte le opzioni che vogliamo permettere, agli utenti che utilizzeranno il nostro plugin, di personalizzare.

Tutti i parametri che si trovano all’interno dell’oggetto config, sono le opzioni di default del nostro plugin.
Questo significa che, dove non diversamente specificato, il nostro plugin farà riferimento a quei parametri.

Subito dopo la creazione dell’oggetto config, utilizziamo la funzione extend() di jQuery per “estendere” le opzioni di default con quelle specificate dall’utente.
Questo passaggio viene eseguito soltanto se l’utente ha specificato qualche parametro, in caso contrario il passaggio verrà “saltato”.

Come deve fare l’utente per estendere le opzioni di default ?

Le opzioni di default del nostro plugin possono essere ampliate dall’utente al momento di “chiamare” la funzione.
Se infatti, l’utente decidesse di attivare (ad esempio) l’opzione ‘shaker’, il codice che si dovrebbe utilizzare è il seguente:

$('form.myForm').validMe({ shaker: true });

In questo modo stiamo passando un “valore” alla funzione del nostro plugin, e le parentesi graffe stanno ad indicare che si tratta di un oggetto che può contenere più “parametri”.

Vediamo quale sarebbe il codice da utilizzare se si decidesse di attivare il parametro shaker ed il parametro showMessage:

$('form.myForm').validMe({ shaker: true, showMessage: true });

Utilizzare il ciclo for per analizzare gli elementi

Il selettore di jQuery, che come abbiamo visto, ci permette di associare la funzione del nostro plugin ad un elemento.
C’è però da prendere in considerazione l’eventualità che gli elementi trovati dal selettore che abbiamo specificato siano più di uno.
In quel caso la soluzione è quella di effettuare un ciclo for per analizzare gli elementi trovati dal nostro formulario.
Prendiamo in considerazione il seguente codice:

$('form.myForm').validMe();

Nel codice appena visto verranno validati tutti i form che hanno la classe ‘myForm’, questo significa che i form con questa classe possono essere più di uno, ed è quindi necessario utilizzare la funzione each() di jQuery per esaminarli uno ad uno.

Esaminiamo ora il seguente codice:

(function($) {
     $.fn.validMe = function(options) {

     [...]

     // cicliamo tutti gli elementi trovati
     return this.each(
          function (){

               // creiamo la funzione che controllerà i campi richiesti al momento dell'invio del form
               $(this).submit(
                    function(){
                         // parametri per il funzionamento del plugin
                         var validMe = {
                              'errors' : false
                          }
                         // codice da eseguire quando verrà inviato il form
                    }
               );

          }
     );

}
})(jQuery);

Come puoi vedere abbiamo inserito la funzione each() di jQuery tramite la quale possiamo fare il ciclo di ogni elemento ‘trovato’ dal selettore, specificato al momento della ‘chiamata’ al plugin.
Inoltre è stata aggiunta la keyword return subito prima di utilizzare la funzione each(), questo fa si che ogni elemento ciclato venga reso disponibile anche dopo che il plugin ha svolto il suo compito, per permettere all’utente di accodare al plugin altre funzioni, ad esempio:

$('form.daValidare').validMe().delay(500).hide();

All’interno della funzione each() (nella quale abbiamo a disposizione, uno alla volta, tutti gli elementi trovati) abbiamo inserito la funzione submit() di jQuery, preceduta dal selettore $(this).
Questo significa che all’attuale elemento del ciclo for viene associata la funzione submit() che entrerà in funzione al momento dell’invio del form.

Per comodità ho creato un’ulteriore oggetto, con il nome di validMe, all’interno della funzione submit().
L’oggetto validMe serve a contenere parametri per il funzionamento del plugin, infatti questi parametri non possono essere modificati in nessun modo dall’utente finale.
In questo caso l’oggetto validMe possiede semplicemente il parametro errors con il valore false.
Il parametro errors è di tipo boolean, e funziona come un interruttore:
Se viene trovato almeno un errore tra gli elementi da validare si posiziona su “acceso” (true) se non viene trovato nessun errore rimane “spento” (false).

Questo parametro verrà poi controllato prima di inviare il formulario, e sarà lui che permetterà l’invio (se è spento) oppure di interrompere l’operazione (se è acceso).

Vediamo di seguito il codice rimanente del nostro plugin, in modo da avere una panoramica generale del suo funzionamento, dopo di che procederemo con l’esaminare ogni parte per vederne insieme il significato.

/*
* @package validMe - jQuery plugin
* @author  Nicolas Gutierrez <nicmanzana@gmail.com> per Yourinspirationweb.com
* @license MIT License
*/

(function($) {
	$.fn.validMe = function(options) {

		// valori personalizzabili
		var config = {
				'shaker'					: false
			 , 'shakers'				: 5
			 , 'showMessage'			: false
			 , 'errorClass'			: 'error'
			 , 'requiredClass'		: 'required'
			 , 'requiredMail'			: 'mail'
			 , 'requiredNumber'		: 'numeric'
			 ,	messages : {
			 			'blank'		: 'Questo campo non pu&ograve; rimanere vuoto!'
			 		 , 'check'		: 'Questo campo deve essere selezionato!'
			 		 , 'email'		: 'Inserire un indirizzo email valido!'
			 		 , 'numbe'		: 'Inserire un numero!'
			 	}
		};

		// estendiamo i valori di default con quelli specificati dall'utente
		if (options) $.extend(config, options);

		return this.each(
			function (){
				// creiamo la funzione che controllerà i campi richiesti al momento dell'invio del form
				$(this).submit(
					function(){

						// parametri per il funzionamento del plugin
					   var validMe = {
					   			'errors'			: false
					   }

						// cicliamo tutti gli input trovati
			   		$(this).find('.'+config.requiredClass+'').each(
			   			function() {
			   				var $input 		= $(this);
			   				var type			= $input.attr('type');
			   				var groupName 	= $input.attr('name');

			   				// controlliamo che il contenuto dell'input non sia vuoto
			   				if( !$input.val() ){
			   					error						= true;
			   					errorType				= 'blank';
			   					validMe.errors 		= true;
			   				// se si tratta di una checkbox che non è stata selezionata
			   				}else if( (type == 'checkbox') && ( !$input.is(':checked') ) ){
			   					error						= true;
			   					errorType				= 'check';
			   					validMe.errors			= true;
			   				// se si tratta di una email controlliamo che ci sia il simbolo "@" e "."
			   				}else if( $input.hasClass(config.requiredMail) && ( ($input.val().indexOf('@') == -1) || ($input.val().indexOf('.') == -1) ) ){
			   					error						= true;
			   					errorType				= 'email';
			   					validMe.errors			= true;
			   				// se si tratta di un input numerico controlliamo che il valore inserito sia di questo tipo
			   				}else if( ($input.hasClass(config.requiredNumber)) && isNaN($input.val()) ){
			   					error						= true;
			   					errorType				= 'numbe';
			   					validMe.errors			= true;
			   				// se non è nessuno di questi casi resettiamo l'errore
			   				}else{
			   					error 					= false;
			   					errorType				= null;
			   				}

			   				// notifichiamo l'utente dell'errore di validazione
			   				if(error){
			   					// assegnamo la classe di errore all'input
			   					$input.addClass(config.errorClass);

			   					// se è abilitata l'opzione shaker, shakeriamo un po' l'input !!!!
			   					if(config.shaker){
			   						for (i=0; i<config.shakers; i++) {
			   							$input.animate({ marginLeft: "2px"}, 100 );
			   							$input.animate({ marginLeft: "-2px"}, 100 );
			   						}
			   						$input.animate({ marginLeft: "0"}, 100 );
			   					}

			   					// se è abilitata l'opzione showMessage mostriamo anche un messaggio
			   					if(config.showMessage){
			   						// il messaggio viene mostrato solo se non è già stato mostrato
			   						if($input.next('label').length == 0){
			   							$input.after('<label class="'+config.errorClass+'">'+config.messages[errorType]+'</label>');
			   						}else{
			   							$input.next('label').html(config.messages[errorType]);
			   						}
			   					}

			   				}

			   				// se è abilitata l'opzione showMessage e non ci sono errori togliamo il messaggio
			   				if(!error && $input.next('label').length != 0){
			   					$input.next('label').remove();
			   				}

			   				// se l'input che stiamo controllando non contiene errori ed ha la classe error, la togliamo
			   				if(!error && $input.hasClass(config.errorClass)){
			   					$input.removeClass(config.errorClass);
			   					if(config.removeCustom){
			   						config.removeCustom($input);
			   					}
			   				}

			   			}
						);

						// se non ci sono errori procedo con il submit del formulario
						if(validMe.errors){
							return false;
						}else{
							return true;
						}
					}
				);

			}
		);
	}
})(jQuery);

Puoi vedere il codice sorgente del plugin in maniera più comprensibile all’indirizzo:
https://www.yourinspirationweb.com/example/jquery/creazione_plugin/validMe/js/jquery.validMe.js

Esaminiamo ora il seguente codice:

[...]
// cicliamo tutti gli input trovati
	$(this).find('.'+config.requiredClass+'').each(
		function() {
			[....]
		}
	);
[...]

Vediamo di capire insieme di che cosa si occupa questo codice poichè è una parte fondamentale del plugin.
Utilizziamo la keyword this come selettore ( $(this) ), che in questo caso si riferisce al form, e applichiamo due funzioni:
find() e each() .

Abbiamo già visto il funzionamento di each(), quindi adesso vedremo di che cosa si occupa la funzione find().

Il funzionamento di find() è quello di applicare un ‘filtro’ all’attuale oggetto (in questo caso this) e di restituirci lo stesso oggetto, ma privato di tutto ciò che non rientra nel filtro.
Nel nostro codice il parametro che stiamo passando alla funzione find() è una opzione del nostro plugin (requiredClass), e quindi stiamo dicendo di filtrare tutti gli elementi del form e di ridarci soltanto quelli che hanno la classe requiredClass.

Ora che sappiamo che il risultato di find() + each() sono tutti gli elementi ai quali abbiamo applicato la classe (di default) required, possiamo procedere con analizzare, uno per uno, gli input per controllarne il contenuto.

Il controllo degli input

Possiamo vedere all’interno della funzione each() il seguente codice:

[...]
var $input 		= $(this);
var type			= $input.attr('type');
var groupName 	= $input.attr('name');
[...]

Queste tre variabili sono delle “abbreviazioni” che ci faranno risparmiare un po’ di tempo, vediamo cosa significano:

  • var $input = $(this);

    questo associa alla variabile che io ho chiamato $input il valore di $(this), cioè l’elemento corrente all’interno del ciclo.

  • var type =  $input.attr('type');

    in questo caso utilizzo la funzione attr() di jQuery per ricavare il valore dell’attributo ‘type’ dell’input ed assegnarlo alla variabile type

  • var groupName =  $input.attr('name');

    questa variabile contiene il valore dell’attributo name dell’input.

Quello che dobbiamo fare ora è controllare se l’input è di tipo checkbox piuttosto che radio, se il formato della email inserita è corretto oppure se sia stato inserito un valore numerico dove richiesto; per farlo utilizzeremo, molto semplicemente, degli if else.

Procediamo quindi con l’esaminare ogni singolo blocco e capirne il funzionamento.

[...]
// controlliamo che il contenuto dell'input non sia vuoto
if( !$input.val() ){
	error				= true;
	errorType			= 'blank';
	validMe.errors 		= true;

[...]

Che cosa vuol dire il codice appena visto?

Se è falso che l’input ha un valore (e quindi se è vero che non ce l’ha) settiamo il valore di error su true, quello di errorType su blank e settiamo il parametro errors dell’oggetto validMe su true;

Il parametro error ed il parametro errorType fanno parte tutt’e due del ciclo corrente, e stanno ad indicare rispettivamente, che è stato trovato un errore e che l’errore è di tipo blank.

Sapere che è stato trovato un errore nella validazione dell’input ci servirà, poco più avanti, per aggiungerci la classe di errore, mostrare (se abilitato) un messaggio di errore ed eseguire lo shaker sull’input (se abilitato).
Sapere invece che l’errore è di tipo blank, ci serve per mostrare il tipo di messaggio più adatto a far capire all’utente come correggere l’errore.

Proseguiamo con il seguente codice:

[...]
// se si tratta di una checkbox che non è stata  selezionata
}else if( (type == 'checkbox') && (  !$input.is(':checked') ) ){
	error				= true;</span>
	errorType			= 'check';</span>
	validMe.errors  		= true;</span>
[...]

Questo codice vuol dire che:
se l’input è di tipo checkbox, ed è falso che è selezionato (quindi è vero che non lo è) settiamo il valore di error su true, assegnamo alla variabile errorType il valore ‘check’ ed impostiamo il valore di validMe.errors su true.

Se nessuna delle due condizioni che abbiamo visto fino adesso si verifica, si procede con la terza:

[...]
// se si  tratta di una email controlliamo che ci sia il simbolo "@" e "."
}else if( $input.hasClass(config.requiredMail) &amp;&amp; (  ($input.val().indexOf('@') == -1) || ($input.val().indexOf('.') == -1) )  ){
	error                  	      = true;
	errorType           	      = 'email';
	validMe.errors       	      = true;
[...]

Ora è arrivato il momento di controllare, se nell’input è stato richiesto l’inserimento di un indirizzo email e che quest’ultimo sia corretto, e quindi che possieda il simbolo ‘@’ e ‘.’

In questo caso utilizzamo altre 2 funzioni che non abbiamo ancora visto:
hasClass() (di jQuery) ed indexOf (nativa di JavaScript).

La prima restituisce un valore di tipo boolean, se è vero che possiede la classe passata come parametro, restituisce true, altrimenti false.
indexOf invece si occupa di controllare che il valore passato come parametro sia presente all’interno di una stringa, e restituisce la sua posizione nella stringa, se presente; altrimenti il valore restituito è ‘-1’ (per una spiegazione più chiara e dettagliata vi rimando a questa pagina).

Quindi la nostra condizione significa:
se l’input possiede la classe richiesta per le email ma non possiede il simbolo ‘@’ oppure non possiede il simbolo ‘.’, allora impostiamo correttamente gli errori.

Il metodo utilizzato precedentemente per validare la mail è molto basilare in quanto controlliamo solo che siano presenti i simboli ‘@’ e ‘.’, ma come sappiamo il simbolo ‘.’ può essere inserito anche all’interno del nome.

Con il metodo che ho mostrato un indirizzo come nicolas.g@gmail risulta valido.

Per una validazione più sicura ti consiglio di utilizzare le espressioni regolari.

Ora dobbiamo eseguire l’ultimo controllo, per verificare (dove richiesto) che il valore inserito sia di tipo numerico:

[...]
// se si tratta di un  input numerico controlliamo che il valore inserito sia di questo tipo
}else if( ($input.hasClass(config.requiredNumber)) &&  isNaN($input.val()) ){
	error                    		= true;
	errorType                		= 'numbe';
	validMe.errors           	=  true;
[...]

In questa condizione si vede l’utilizzo della funzione nativa JavaScript isNaN (is not a number), la quale restituisce un valore di tipo boolean: se è vero che il valore passato alla funzione non è un numero restituisce true, altrimenti false.

Il significato è questo:
se l’input possiede la classe richiesta per validare un input come numerico ma il valore dell’input non lo è, impostiamo gli errori di conseguenza.

Se nessuna delle condizioni che abbiamo visto fino adesso si verifica, vuol dire che non sono presenti errori, quindi possiamo chiudere il blocco delle condizioni con il seguente codice:

[...]
//  se non è nessuno di questi casi resettiamo l'errore
}else{
	error       = false;
	errorType  = null;
}
[...]

Impostiamo le variabili error ed errorType su false, in modo da sapere che l’input è stato validato correttamente.

Notifichiamo l’utente dell’errore trovato durante la validazione

[...]
// notifichiamo l'utente dell'errore di validazione
if(error){

	// assegnamo la classe di errore all'input
	$input.addClass(config.errorClass);

	// se è abilitata  l'opzione shaker, shakeriamo un po' l'input !!!!
	if(config.shaker){
		for (i=0; i<config.shakers; i++) {
			$input.animate({ marginLeft: "2px"}, 100 );
			$input.animate({ marginLeft: "-2px"}, 100 );
		}
			$input.animate({ marginLeft: "0"}, 100 );
	}

	// se è  abilitata l'opzione showMessage mostriamo anche un messaggio
	if(config.showMessage){
		// il messaggio viene mostrato solo  se non è già stato mostrato
		if($input.next('label').length ==  0){
			$input.after('<label class="'+config.errorClass+'>'+config.messages[errorType]+'</label>');
		}else{
			$input.next('label').html(config.messages[errorType]);
		}
	}

}
[...]

La condizione che abbiamo appena visto si verifica soltanto quando è stato trovato un errore di validazione dell’input, in quel caso bisogna procedere in questo modo:

  1. Aggiungiamo all’input la classe d’errore
  2. Controlliamo se è abilitata l’opzione shaker ed in quel caso “shakeriamo” l’input
  3. Controlliamo se è abilitata l’opzione showMessage ed in quel caso mostriamo un messaggio di errore a seconda del tipo di errore

1. Per aggiungere all’input la classe di errore utilizzamo la funzione addClass di jQuery, ecco il codice:

[...]
$input.addClass(config.errorClass);
[...]

2. La seguente condizione si verifica soltanto se il valore del parametro shaker (config.shaker) è impostato su true:

[...]
// se è abilitata  l'opzione shaker, shakeriamo un po' l'input !!!!   if(config.shaker){
	for (i=0; i<config.shakers; i++) {
		$input.animate({  marginLeft: "2px"}, 100 );
		$input.animate({ marginLeft:  "-2px"}, 100 );
	}

	$input.animate({ marginLeft: "0"},  100 );
}
[...]

Nel codice appena visto utilizziamo il ciclo for per ripetere un’operazione tot. volte, il numero di volte che verrà eseguita è specificato nel parametro config.shakers (di default 5).

All’interno del ciclo for usiamo la funzione animate() di jQuery.
La funzione animate() ci permette di applicare, all’elemento selezionato, un tipo di animazione utilizzando un set predefinitio di proprietà css.
Puoi trovare una spiegazione più dettagliata sulla funzione animate() e vari esempi in questo articolo di JustB.

Nel nostro caso utilizzeremo la proprietà MarginLeft, infatti applichiamo prima una animazione di soli 2px che verrà eseguita in 100 millisecondi (quindi l’elemento si muoverà verso destra di 2px), subito dopo un’animazione di -2px sul margin left (in questo caso l’elemento tornerà al punto 0 e si sposterà di -2px).

Appena viene chiuso il ciclo for, reimpostiamo il margine dell’input utilizzando sempre la funzione animate(), questa volta però diamo come valore di marginLeft 0.

Il prossimo step è quello di mostrare un messaggio di errore, ma soltanto se l’utente ha abilitato la funzione.
In questo plugin ho deciso di creare un <label> subito dopo l’input nel caso ci sia un errore, in modo da inserirci all’interno il messaggio di errore.
Vediamo il codice utilizzato:

// se è abilitata  l'opzione showMessage mostriamo anche un messaggio
if(config.showMessage){
	// il  messaggio viene mostrato solo se non è già stato mostrato
	if($input.next('label').length == 0){
		$input.after('<label  class="'+config.errorClass+'">'+config.messages[errorType]+'</label>');
	}else{
		$input.next('label').html(config.messages[errorType]);
	}
}

La prima cosa da fare è controllare che il parametro config.showMessage sia impostato su true, se lo è eseguiamo una nuova condizione: verificare che il <label> non sia già stato creato in precedenza, in modo da non crearne più di uno.
Adesso dobbiamo verificare che subito dopo il nostro input non ci sia un <label>, per selezionare l’elemento che si trova subito dopo utilizziamo la funzione next() di jQuery , la quale funziona come filtro; essa ci restituisce il primo elemento trovato subito dopo l’elemento scelto, ed in modo opzionale possiamo passare un parametro in modo da filtrare il risultato, in questo caso il filtro che applichiamo è il tag label.
Ora non ci resta che accodare la proprietà di JavaScript length, questa proprietà restituisce il numero di caratteri presenti in una stringa, quindi se il nostro selettore non avrà trovato nessun tag <label> dopo l’input, il valore restituito da length sarà uguale a zero.

Se abbiamo verificato che l’elemento non è stato ancora creato dobbiamo crearlo noi.
Per farlo utilizziamo questa volta la funzione after() di jQuery, che ci permette di inserire del contenuto subito dopo l’elemento selezionato.
Il contenuto che inseriamo non è altro che un tag label, che ha come classe , la classe scelta per gli errori, e come contenuto il messaggio di errore preso dalle opzioni del plugin.

[...]
config.messages[errorType]
[...]

In pratica utilizziamo la variabile errorType come indice dell’oggetto messages, per visualizzare il messaggio di errore più idoneo.

Ora che abbiamo visto cosa succede all’input in caso di errore, vediamo cosa succede nel caso che non sia stato trovato nessun errrore.

[...]
// se è  abilitata l'opzione showMessage e non ci sono errori togliamo il  messaggio
if(!error && $input.next('label').length !=  0){
     $input.next('label').remove();
}

//  se l'input che stiamo controllando non contiene errori ed ha la classe  error, la togliamo
if(!error &&  $input.hasClass(config.errorClass)){
     $input.removeClass(config.errorClass);
}
[...]

Nella prima condizione controlliamo che sia falso che error è impostato su true (quindi che error sia falso) e che l’elemento <label> subito dopo il nostro input esista, in quel caso utilizziamo la funzione remove di jQuery per eliminare il tag con il suo contenuto.
La funzione remove() si occupa di rimuovere completamente dal DOM l’elemento selezionato.

Nella seconda condizione invece, controlliamo che non ci siano errori e che il nostro input abbia la classe d’errore, in quel caso utilizziamo la funzione removeClass di jQuery per rimuovere una classe dall’elemento selezionato.

Ora che abbiamo fatto tutto ciò che era necessario per validare gli input, l’ultima cosa da fare è interrompere l’operazione nel caso ci siano stati degli errori, altrimenti possiamo continuare con l’invio del form.

[...]
// se  non ci sono errori procedo con il submit del formulario
if(validMe.errors){
return false;
}else{
return true;
}
[...]

Se il parametro validMe.errors è impostato su true, allora interrompiamo l’invio del form tramite le keyword return false;, in caso contrario il formulario viene inviato correttamente, grazie alle keyword return true;.

Conclusioni

In questo articolo abbiamo visto come creare un semplice plugin di validazione per forms, e come permettere all’utente di personalizzare le opzioni.
Ovviamente quello che abbiamo visto può essere migliorato notevolmente, inserendo ad esempio il controllo su select oppure su input di tipo radio.

Ora che hai visto quanto è facile creare un validatore di forms con jQuery, pensi che ne creerai uno tuo?

Tag: , ,

L'autore

Nicolas è un programmatore web con la passione per il web design e per javascript. Passa la maggior parte del suo tempo libero alla ricerca di nuove idee e nuovi progetti da sviluppare. É fanatico di Wordress e jQuery e si diverte nella creazione di plugins per quest'ultimo.

Altri articoli scritti da

Articoli correlati

Potresti essere interessato anche ai seguenti articoli:

17 commenti

  1. claudio rebonato
    • Nicolas Gutierrez
  2. stefano
  3. stefano
  4. Daniele

Trackback e pingback

  1. uberVU - social comments
    Social comments and analytics for this post... This post was mentioned on Twitter by jubstuff: RT @YIW jQuery, come…

Lascia un Commento