jQuery: semplice validazione di un form

A differenza di qualche tempo fa, in cui ero piuttosto interessato a librerie esterne per validare i miei form, oggi preferisco scrivere e ottimizzare la validazione di volta in volta a seconda del sito in questione.

Troppe librerie, come jQueryTools o jQuery Validator, sono strettamente dipendenti dalla versione di jQuery utilizzata e vanno spesso in conflitto con altri elementi nel DOM.

Come procedere, allora, se siamo alle prime armi?
Un passaggio per volta, vediamo di arrivare ad una validazione completa.

Partiamo con il creare una pagina HTML ed inserirvi il riferimento ad un foglio di stile ed alla libreria jQuery:

<html>
<head>
<meta charset="utf-8">
<title>Form Validation</title>
<link href="stile.css" rel="stylesheet" type="text/css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
</head>
...

stile.css

body{
	font-size:12px;
	font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
}
/* selezioniamo tutti gli input con type=text e le textarea */
input[type=text], #form1 textarea{
	background:#F9F8F6;
	border:1px solid #706f6f;
	width:90%;
	padding:3px;
	font-size:12px;
	font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
	border-radius:3px;
}
/* diamo uno stile diverso alle select ed ai campi file */
select, #form1 input[type=file]{
	background:#CCCCCC;
	border:1px solid #706f6f;
	width:90%;
	padding:3px;
	font-size:12px;
	font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
	border-radius:3px;
}
button{
	background-color:#CCCCCC;
	border:1px solid #999999;
	width:90%;
	padding:3px;
	font-size:12px;
	font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;
	border-radius:3px;
}
button:hover{
	cursor:pointer;
	background-color:#b1b1b1;
}
/* stile che assegno ai campi errati */
.redborder{
	border:1px solid #C00 !important;
	box-shadow:0 0 3px #990000;
}
/* stile che assegno ai campi corretti */
.greenborder{
	border:1px solid #0C0 !important;
	box-shadow:0 0 3px #009933;
}

.errormsg{
	display:none;
}
.errormsg h2{
	color:#C00;
	margin:0px;
	padding:0px;
}
.errormsg ul{
	margin-top:0px;
	font-size:11px;
	color:#C00;
	font-weight:bold;

}
.waitmsg{
	display:none;
}

Form:

</pre>
<form id="form1" action="#" method="post" name="form1">
<label for="nome">Inserisci il tuo nome: </label>
<input id="nome" type="text" name="nome" data-description="Nome" />

<label for="cognome">Inserisci il tuo cognome: </label>
<input id="cognome" type="text" name="cognome" data-description="Cognome" />

<label for="email">Inserisci la tua E-Mail: </label>
<input id="email" type="text" name="email" data-description="E-Mail" />

<label for="marca">Seleziona la marca della tua auto: </label>
<select name="marca" data-description="Marca"> <option selected="selected" value="0">Seleziona una voce...</option></select>
<select name="marca" data-description="Marca"> <option value="1">BMW</option></select>
<select name="marca" data-description="Marca"> <option value="2">OPEL</option></select>
<select name="marca" data-description="Marca"> <option value="3">MERCEDES</option></select>
<select name="marca" data-description="Marca"> <option value="4">PORSCHE</option></select>

<input id="privacy" type="radio" name="privacy" value="1" data-description="Privacy" />
<label for="privacy">*<strong>si</strong>, ho letto e accetto il trattamento dei miei dati personali</label>

<button id="submitform1" type="button">Invia la richiesta</button>
<input id="errorState" type="hidden" name="errorState" value="0" />
<div class="errormsg">
<h2>Attenzione</h2>
</div>
<div class="waitmsg">
<h2><img src="img/ajax-loader3.gif" alt="" width="24" height="24" align="absmiddle" /> Attendere prego</h2>
</div>
</form>
<pre>

Alcuni tag sono custom, come ad esempio data-description.
Ho preferito gestire in maniera facoltativa il tag data-description, così da poter descrivere in maniera diversa, dal nome standard del campo, la label del campo stesso.
Nel caso in cui il campo sia
(input id=”email” type=”text”) e volessi scrivere “Il campo E-Mail non è corretto”, allora inserirò il valore “E-Mail” nel tag data-description.
Un sistema veloce, facile da customizzare, non obbligatorio e compatibile anche su IE.

Alla fine del form invece ho un campo con id=errorState e default value=0.
Durante il processo di validazione, mi appoggio al value di id=errorState, modificandolo in value=1 nel caso di errore in qualsiasi campo.
I messaggi di errore, invece, sono listati in un
(ul) dentro il div con class=errormsg.
Non ho inserito alcun input type=submit, ma un semplice button e ne intercetto il click con un semplicissimo bind(), sostituibile ( consigliato ) con un on(), visto che le nuove release di jQuery saranno poco gentili nei confronti di metodi deprecati.

Inserisco prima alcune funzioni:

// per pura velocità di scrittura del codice, mi creo una funzione tolog() ne commento il console.log() quando testo su IE.
function tolog(me){
  console.log(me);
}

// funzione che inserisce nella lista degli errori il singolo errore di validazione
function addToErroMsg(msg){
var msg_final = '</pre>
<ul>
	<li>' + msg + '</li>
</ul>
<pre>
';
  $('.errormsg ul').append(msg_final);
}

Ora intercetto il click del bottone di invio:

$('#submitform1').click(function(){

        // a tutti i campi del form che hanno la class=redborder rimuovo sia la classe redborder che greenborder
	$('#form1 input.redborder, #form1 select.redborder').removeClass('redborder').removeClass('greenborder');
        // svuoto la lista degli errori
	$('.errormsg ul').empty();
        // rimetto il valore di default di errorState
	$('#errorState').val('0');

        // valido i campi sottostanti. il tipo text può essere omesso, gli altri tipi devono essere citati
        // attualmente ho creato una validazione solamente per email, select e radio
	validField('nome');
	validField('cognome');
	validField('email','email');
	validField('marca','select');
	validField('privacy','radio');

        // se errorState==1 allora c'è stato un errore
	if($('#errorState').val()==1){
		$('.errormsg h2').html('Attenzione:');
		$('.errormsg').fadeIn();
	}else{
                // non c'è stato errore di validazione

		$('#submitform1').attr('disabled','disabled');   // disabilito il pulsante di invio
		$('.errormsg').hide();  // nascondo l'eventuale messaggio di errore validazione
		$('.waitmsg').fadeIn(); // mostro il messaggio di attesa
		$('#form1').submit();   // submit del form
	}

})

Ho commentato riga per riga il codice, così vi sarà molto semplice comprendere e personalizzare quando scritto.
Ora non resta che instanziare la funzione validField():

function validField(fieldName,tipo){

	// l'ID è fieldName: ora valuto se ho messo una descrizione diversa
	var fieldDesc = $('#' + fieldName).attr('data-description');
	if(fieldDesc==undefined){
		// il campo ha una descrizione diversa
		fieldDesc = fieldName;
	}

	// validazione per campo TEXT
	if(tipo==undefined || tipo=='text'){
		fieldValue = $('#' + fieldName).val();
		if(fieldValue.length==0){
			// validazione fallita, assegno la classe=redborder
			$('#' + fieldName).addClass('redborder').removeClass('greenborder');
			// errorState=1
			$('#errorState').val('1');
			// messaggio di errore, qui potete personalizzarlo
			addToErroMsg('Campo ' + fieldDesc + ' obbligatorio');
		}else{
			// la validazione è corretta, assegno la classe=greenborder
			$('#' + fieldName).addClass('greenborder').removeClass('redborder');
		}
	} // end type text

	if(tipo=='email'){

		fieldValue = $('#' + fieldName).val();
		if(fieldValue.length==0){
			$('#' + fieldName).addClass('redborder').removeClass('greenborder');
			addToErroMsg('Campo ' + fieldDesc + ' obbligatorio');
			$('#errorState').val('1');
		}else{
			if(fieldValue.indexOf('.')==-1 || fieldValue.indexOf('@')==-1){
				$('#' + fieldName).addClass('redborder').removeClass('greenborder');
				addToErroMsg('E-Mail non valida');
				$('#errorState').val('1');
			}else{
				$('#' + fieldName).addClass('greenborder').removeClass('redborder');
			}
		}
	} // end type email

	if(tipo=='select'){
		fieldValue = $('#' + fieldName + ' option:selected').val();
		if(fieldValue==0){
			$('#' + fieldName).addClass('redborder').removeClass('greenborder');
			addToErroMsg('Campo ' + fieldDesc + ' obbligatorio');
			$('#errorState').val('1');
		}else{
			$('#' + fieldName).addClass('greenborder').removeClass('redborder');
		}
	} // end type select

	if(tipo=='radio'){

		fieldValue = $('#' + fieldName).attr('checked');
		if(fieldValue==undefined){
			$('label[for="privacy"]').css('color','red');
			addToErroMsg('Campo ' + fieldDesc + ' obbligatorio');
			$('#errorState').val('1');
		}else{
			$('label[for="privacy"]').css('color','#999');
		}
	} // end type radio

} //end validField function

Abbiamo lavorato sullo stato di undefined di alcune variabili: su questa azione c’è sempre un aperto dibattito se non sia meglio operare diversamente.
Probabilmente si potrebbe procedere in maniera più “pulita”, ma in questo caso il tempo era poco e il risultato … accettabile.

Se volete vedere la demo di questo form, cliccate qui, mentre da qui scaricate lo zip con il codice.

Validare un file JSON

jsonlint screenshotMolti di voi avranno a che fare, quotidianamente, con la questione JSON e la sua struttura.
Spesso e volentieri il codice è generato lato server, quindi avrete la necessità, in pochi click, di sapere se il file esportato è valido oppure no.

Per questa problematica ci viene incontro un sito, jsonlint.com, che, molto semplicemente, ci permette di incollare il codice e verificarne la correttezza.

Un esempio di JSON lo potete trovare nel nostro script per la creazione di un News Slider in jQuery, dove forniamo allo script la base dati in un file json, appunto.