AJAX è particolarmente adatto alla gestione dei form. La sua capacità di evitare il refresh di una pagina può ad esempio essere applicata ad un form di login. jQuery dispone di svariati metodi per la gestione di questo tipo di situazioni. In questo articolo vedremo come gestire un form di login con AJAX e jQuery.

Marcatura e stili

Partiamo dalla seguente struttura HTML:


<form action="process.php" method="post" id="login">
	<ul>
        <li>
			<label for="email">E-mail</label>
			<input type="text" name="email" id="email" />
		</li>
		<li>
			<label for="pwd">Password</label>
			<input type="password" name="pwd" id="pwd" />
		</li>
	</ul>
	<p><input type="image" src="img/button.png" alt="Log in" id="submit" /></p>
</form>

A cui applicheremo i seguenti stili:


body {
	font: 100% Arial, sans-serif;
}

form {
	margin: 2em auto;
	width: 40%;
}

ul {
	margin: 0;
	padding: 0;
	list-style: none;
}

li {
	margin-bottom: 0.5em;
}

li label {
	font-weight: bold;
	display: block;
	padding-bottom: 4px;
}

li input {
	font: 1.2em Arial, sans-serif;
	width: 160px;
	display: block;
	border: 1px solid #bbb;
}

.success {
	background: url(img/success.png) no-repeat 0 50%;
	padding: 0.5em 0.5em 0.5em 40px;
	color: #393;
}

.error {
	background: url(img/error.png) no-repeat 0 50%;
	padding: 0.5em 0.5em 0.5em 40px;
	color: #c30;
}

.message {
	background-color: #eee;
	border: 1px solid #ccc;
	border-radius: 4px;
	margin-bottom: 1em;
	width: 200px;
}

Ecco come si presenta ora il nostro form:

Il form con gli stili applicati

Le classi CSS success, error e message verranno usate da jQuery quando mostrerà i risultati dell'elaborazione lato server dei due campi del form.

Il codice lato server

Ho cercato di scrivere un codice PHP per l'elaborazione dei dati nel modo più semplice possibile per permettervi di capire cosa accade dietro le scene di una richiesta AJAX. Si tratta di un codice essenziale che manca di alcune parti, come una migliore validazione dei dati.

Questo codice genera marcatura HTML cercando una corrispondenza nel database per l'email e la password inserite nel form. Se una corrispondenza manca, viene generato un elemento con classe error. Se entrambi i dati coincidono, la classe dell'elemento sarà success. Il codice si trova nel file process.php usato nell'attributo action del form:


header('Content-Type: text/html');

$connection = mysql_connect('host', 'xxxx', 'xxxx');
mysql_select_db('xxxx', $connection);

$email = $_POST['email'];
$pwd = $_POST['pwd'];


/* @todo Aggiungere una routine di filtraggio più accurata */

$clean_email = mysql_real_escape_string($email);
$clean_pwd = mysql_real_escape_string($pwd);
$enc_pwd = md5($clean_pwd);

$message = '';
$errors = '';

$query1 = "SELECT * FROM users WHERE email = '$clean_email'";
$result = mysql_query($query1, $connection);

$results = mysql_fetch_row($result);

if($results == false) {

	$errors .= '<div class="error message">E-mail errata</div>';

}

$query2 = "SELECT * FROM users WHERE pwd = '$enc_pwd'";
$result2 = mysql_query($query2, $connection);

$results2 = mysql_fetch_row($result2);

if($results2 == false) {

	$errors .= '<div class="error message">Password errata</div>';

}

if($errors != '') {

	$message = $errors;

} else {

	$message = '<div class="success message">Login effettuato con successo</div>';

}



echo $message;

A livello di database esiste un'ipotetica tabella con questa struttura creata unicamente a scopo dimostrativo:


CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(255) NOT NULL,
  `pwd` varchar(32) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;

32 (caratteri) è la lunghezza della stringa generata dalla funzione md5() quando opera in modalità raw. VARCHAR è un tipo di dati che ben si applica alle e-mail, ma qui la sua lunghezza è stata definita in modo loose, nel senso che in genere la lunghezza massima di un indirizzo e-mail non dovrebbe superare i 64 caratteri (controllate comunque le specifiche RFC o consultate Wikipedia).

Abbiamo deciso di generare una pagina HTML per un motivo molto semplice: se JavaScript non è supportato, il browser riuscirà comunque a visualizzare i risultati dell'elaborazione del form, cosa non sempre agevole o possibile con altri tipi di formato (come JSON o XML).

Il codice jQuery

Il metodo $.ajax() di jQuery è il modo più completo per gestire una richiesta AJAX, in questo caso una richiesta POST. L'URL che forniremo al metodo è lo stesso dell'attributo action del form. I dati che passeremo allo script PHP tramite la proprietà data sono una stringa composta dal nome dei due campi del form seguiti dal loro valore, ossia email=valore&pwd=valore. Questi valori li otterremo con il metodo val().

Il nostro codice dovrà intercettare l'invio del form. Per questo motivo useremo l'evento submit. Dobbiamo anche impedire che il browser segua l'URL dello script PHP e carichi una nuova pagina usando il metodo preventDefault() dell'oggetto event (normalizzato da jQuery).

Il tipo di dati sarà html, ossia un documento HTML. Useremo il valore passato al metodo success() per andare ad inserire la marcatura generata dallo script PHP dove vogliamo che appaia. Allo stesso modo rimuoveremo subito tutti gli eventuali elementi già inseriti in un precedente invio.

Ecco il codice:


$(function() {

	$('#login').submit(function(event) {
	
		var $form = $(this);
		var url = $form.attr('action');
		var email = $('#email', $form).val();
		var pwd = $('#pwd', $form).val();
		var data = 'email=' + email + '&pwd=' + pwd;
		
		$.ajax({
			type: 'POST',
			dataType: 'html',
			url: url,
			data: data,
			success: function(html) {
			
				$('div.message', $form).remove();
			
				$(html).prependTo($('ul', $form));
			
			}
			
		});
		
	
		event.preventDefault();
	
	});

});

Ecco come si presentano gli errori di validazione:

Errori di validazione

E il messaggio di avvenuto login:

Login effettuato con successo