"Gli Jatravartid di Viltvodle VI credono invece che il cosmo sia nato dallo starnuto di un essere chiamato il Grande Ciaparche Verde."

Towel Day - Non fatevi prendere dal Panico

Guida Galattica per gli Autostoppisti

Creare form con validazione e CAPTCHA in Joomla 3 - quarta parte

Logo Joomla
Immagine da Joomla
Siamo alla conclusione di questa serie di articoli dedicata alla creazione di form inserimento dati e validazione tramite CAPTCHA in un sito Joomla. Abbiamo visto come creare un form base nella prima parte, come aggiungere la validazione tramite jQuery Validation Plugin nella seconda parte, come implementare un sistema di reCAPTCHA nella terza parte. Ora l'ultimo passo è integrare reCAPTCHA con la gestione della validazione via jQuery Validation Plugin.
Voglio cioè segnalare all'utente di validare la richiesta di reCAPTCHA, se non l'ha fatto, tramite gli strumenti di jQuery Validation Plugin; quando poi tutti i campi necessari sono compilati e il reCAPTCHA validato correttamente, si possono trasmettere i dati alla pagina che dovrà gestirli.
Più in dettaglio: dobbiamo implementare un sistema che verifica via plugin che la casella di controllo Non sono un robot sia stata selezionata; questo significa che il controllo anti-bot è già stato svolto con successo, per come funziona il sistema reCAPTCHA V2 visto nell'articolo precedente.
Si deve aggiungere al nostro script validate.js visto nella seconda parte (tranquilli, tra poco lo ritrovate in questa pagina) un'ulteriore regola (vedi la sezione rules nel file stesso) per controllare che il reCAPTCHA sia stato compilato e visualizzare un messaggio di errore se l'utente fa clic su Invia senza farlo.
Evito di incartarmi ulteriormente in questa contorta spiegazione; faccio cosa sicuramente gradita e pubblico, nell'ordine, codice HTML, PHP e jQuery.

Form HTML

<form action='#' method='post' id='form_demo'>
	<fieldset>
		<legend>I tuoi dati</legend>
		<div class="control-group">
			<div class="input-prepend">
				<span class="add-on"><span class="icon-user"></span></span>
				<input class="input-xxlarge" type='text' placeholder='Il tuo nome (3-15 caratteri, richiesto)' name='nome' id='nome' />
			</div>
		</div>
		<div class="control-group">
			<div class="input-prepend">
				<span class="add-on"><span class="icon-user"></span></span>
				<input class="input-xxlarge" type='text' placeholder='Il tuo cognome (3-15 caratteri, richiesto)' name='cognome' id='cognome' />
			</div>
		</div>
		<div class="control-group">
			<div class="input-prepend">
				<span class="add-on"><span class="icon-plus"></span></span>
				<input class="input-xxlarge" type='text' placeholder='Età (18-60, richiesto)' name='eta' id='eta' />
			</div>
		</div>
		<div class="control-group">
			<div class="input-prepend">
				<span class="add-on"><span class="icon-envelope"></span></span>
				<input class="input-xxlarge" type='text' placeholder='Il tuo indirizzo email (richiesto)' name='email' id='email' />
			</div>
		</div>
		<div class="control-group">
			<div><strong>Genere</strong> (richiesto)</div>
			<label class='radio inline'>
				<input id='maschio' type='radio' name='sesso' value='Maschio' /> Maschio
			</label>
			<label class='radio inline'> 
				<input id='femmina' type='radio' name='sesso' value='Femmina' /> Femmina
			</label>
			<label for="sesso" class="error"></label>
		</div>
		<div class="control-group">
			<div><strong>Il tuo sistema operativo</strong> (scegli almeno un sistema)</div>
			<label class='checkbox inline'>
				<input type='checkbox' name='os[]' id='win32' value='Windows' /> OS Windows 32/64 bit
			</label>
			<label class='checkbox inline'>
				<input type='checkbox' name='os[]' id='linux' value='Linux' /> Linux
			</label>
			<label class='checkbox inline'>
				<input type='checkbox' name='os[]' id='mac' value='Mac' /> Mac OS 
			</label>
			<label for="os[]" class="error"></label>
		</div>
		<div class="control-group">
			<textarea class="input-xxlarge" id='note' name='note' rows='5'  placeholder='Altre note e richieste'></textarea>
		</div>
		<div class="g-recaptcha" data-sitekey="6LcbzCEUAAAAAEl2nyx_h0kYgy6gOv4JYxnNarYI" data-callback="recaptchaCallback"></div>
		<input type="hidden" class="missingRecaptcha required" name="missingRecaptcha" id="missingRecaptcha">
	</fieldset>
	<div class="control-group text-center">
		<button class="btn btn-primary" type='submit' id='invia_form'>Invia</button>
	</div>
</form>
<script src='https://www.google.com/recaptcha/api.js?hl=it'></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script>
<script src="/script/validate/validate_complete.js" ></script>
Alcuni dettagli sulle novità rispetto al modulo visto nella prima parte dell'articolo:
  • La riga <div class="g-recaptcha" data-sitekey="6LcbzCEUAAAAAEl2nyx_h0kYgy6gOv4JYxnNarYI" data-callback="recaptchaCallback"></div> visualizza il reCAPCTHA. Rispetto a quanto visto nella seconda parte dell'articolo, compare un nuovo parametro data-callback: serve a nascondere il messaggio di errore per mancata compilazione, se presente, dopo che l'utente ha completato il reCAPTCHA. Ulteriori dettagli su questo nel file js più oltre.
  • La riga <input type="hidden" class="missingRecaptcha required" name="missingRecaptcha" id="missingRecaptcha"> serve ad "intercettare" la mancata compilazione del reCAPTCHA, questo sarà più chiaro dando un'occhiata al file js aggiornato. Il tipo di campo è hidden perchè non vogliamo certamente visualizzarlo; si tratta di un campo di comodo, niente di più.
  • Si notino anche i file .js necessari caricati al termine: api per reCAPTCHA, jQuery Validate e il nostro script di regole di validazione.
Questo codice HTML va inserito in un articolo joomla.

PHP

C'è poco da aggiungere a quanto già detto nella terza parte della nostra serie di articoli. Prestare solo attenzione a caricarlo nei percorsi giusti, come spiegato nell'articolo.
<?php  
	require_once('autoload.php'); 
	$secret = "tihogiàdettochequicivalachiaveprivata";
	$lang = 'it';
	$result=false;	
	$recaptcha = new \ReCaptcha\ReCaptcha($secret);
	
	$response = $recaptcha->verify($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);

	if ($response->isSuccess()) {
		$result=true;
	} 
	else {
		foreach ($response->getErrorCodes() as $code) {
			echo '<tt>Errore: ' , $code , '</tt> ';
		}
		
		$result=false;
	}
	echo json_encode($result);
?>

File .js

Eccoci finalmente al sorgente jQuery aggiornato per includere la validazione CAPTCHA:
jQuery(document).ready(function() {
	jQuery("#form_demo").validate(
    {
		ignore: ".ignore",	
        rules:
        {
            nome: {
				required: true,
				minlength: 3,
				maxlength: 15
			},
            cognome: {
				required: true,
				minlength: 3,
				maxlength: 15
			},
			eta: {
				required: true,
				number: true,
				range: [18,60]
			},
            email:
            {
                required: true,
                email: true
            },
            sesso: "required",
            'os[]': "required",
			missingRecaptcha: {
				required: function() {
					if(grecaptcha.getResponse() == '') {
						return true;
					} else {
						return false;
					}
				}
			}
        },
        messages:
        {
            nome: {
				required: "<div class='help-inline'>Inserisci il nome</div>",
				minlength: "<div class='help-inline'>Il nome deve avere almeno 3 caratteri</div>",
				maxlength: "<div class='help-inline'>Il nome deve avere al massimo 15 caratteri</div>"
			},
            cognome: {
				required: "<div class='help-inline'>Inserisci il cognome</div>",
				minlength: "<div class='help-inline'>Il cognome deve avere almeno 3 caratteri</div>",
				maxlength: "<div class='help-inline'>Il cognome deve avere al massimo 15 caratteri</div>"
			},	
			eta: {
				required: "<div class='help-inline'>Indica la tua età</div>",
				number: "<div class='help-inline'>L'età va indicata con un numero</div>",
				range: "<div class='help-inline'>L'età deve essere compresa tra 18 e 60 anni</div>"
			},
            email: "<div class='help-inline'>Inserisci un indirizzo email valido</div>",
            sesso: "<div class='text-error'>Seleziona sesso</div>",
            'os[]': "<div class='text-error'>Seleziona uno o più sistemi operativi</div>",
			missingRecaptcha: "<div class='text-error'>Verifica il reCAPTCHA</div>"
        },
		highlight: function(element) {
			if (jQuery(element).attr("name") != "os[]" && jQuery(element).attr("name") != "sesso")
				jQuery(element).closest('.control-group').removeClass('success').addClass('error');
         },
        unhighlight: function(element){
			if (jQuery(element).attr("name") != "os[]" && jQuery(element).attr("name") != "sesso")
				jQuery(element).closest('.control-group').removeClass('error').addClass('success');
        }
    });
});

function recaptchaCallback() {
  jQuery('#missingRecaptcha').valid();
};
Al solito, una breve spiegazione del sorgente, limitandomi alla parte nuova aggiunta:
  • Prima della sezione rules compare una nuova "direttiva", ignore: ".ignore",. Serve per ignorare la validazione per i soli campi con classe ignore. Perchè l'ho aggiunta? Perchè il valore predefinito per questo selettore è hidden, che evita la validazione per i campi nascosti. Come abbiamo visto nel codice HTML, la visualizzazione del messaggio di errore in caso di validazione non compilata fa uso proprio di un campo nascosto, per cui non possiamo ignorarlo.
  • Nella stessa sezione rules ho aggiunto un nuovo elemento: missingRecaptcha:, che è definito come obbligatorio (required) utilizzando una chiamata ad una funzione per verificare se deve tornare true - e allora l'elemento è richiesto o false - elemento non richiesto. Questo è il controllo sul già citato campo nascosto missingRecaptcha, la cui obbligatorietà, in base alle regole, dipende dal fatto che l'utente abbia completato la validazione anti-bot. Quindi: se l'utente non compila il reCAPTCHA, viene visualizzato un messaggio di errore.
  • Di conseguenza ho aggiunto un nuovo messaggio di errore nella sezione messages: hiddenRecaptcha: "<div class='text-error'>Verifica il reCAPTCHA</div>", da visualizzare se viene violata la regola aggiunta.
  • Infine, ho aggiunto nel file validate.js la funzione recaptchaCallback, che verifica la validità dell'elemento con id missingRecaptcha. Serve a rimuovere il messaggio di errore in caso di reCAPTCHA non compilato.
Mi rendo perfettamente conto che tutto questo non è così semplice da comprendere se non si ha alcuna conoscenza di jQuery o PHP... Purtroppo mi è difficile renderlo più semplice, ho davvero ridotto al minimo le funzionalità ed i controlli.
Dopo tanta fatica, vostra e soprattutto mia, ecco qui il form completo, con validazione e controllo CAPTCHA:
I tuoi dati
Genere (richiesto)
Il tuo sistema operativo (scegli almeno un sistema)
Finalmente abbiamo concluso. Soprattutto, ho concluso questa lunga serie di articoli. Questo non significa certo che questa procedura sia completa o perfettamente efficiente: ho sorvolato su diversi aspetti non secondari. Ad esempio, se ho disabilitato javascript cosa succede? E gli utenti ipovedenti? È possibile gestire più reCAPTCHA nella stessa pagina? Se non voglio usare PHP cosa posso fare? E così via.
Tante domande, un'unica risposta: è l'occasione buona per fare un po' di lavoro in autonomia e trovare da soli la soluzione! Considerate questa serie di articoli come una traccia, un punto di partenza su cui costruire i vostri form.

Tags: Joomla, Personalizzare template, Twitter Bootstrap, jQuery

Contattami, ma pensaci bene

  • Scrivimi, affinchè possa ignorarti con calma
  • Pubblico questa roba dalla Bassa Modenese. Sì, la zona del terremoto di maggio 2012...

    ... tromba d'aria nel 2013...

    ... alluvione nel 2014...

    ... nuova tromba d'aria nel 2014

Cominciamo ad essere un po' scocciati

E questo Ciaparche, cos'è?

Se ti punge vaghezza di conoscere la risposta e dimostrare così la tua ignoranza, non temere: nessuno dal monitor ti osserva (sicuro? Meglio essere attenti... controlla le impostazioni di privacy della fotocamera), per cui corri ad informarti facendo clic sul link sotto.

Se sei tra quegli eletti che hanno colto la citazione, hai tutta la mia approvazione.

Soddisfa la tua curiosità

Riassunto per pigri

Se i titoli dei menu non ti sono chiari, al tuo posto mi preoccuperei. Vabbè oggi mi sento magnanimo e ammetto che alcuni sono criptici o ambigui, per cui ho deciso di metterti a disposizione un riassunto che ti spiega in breve cosa troverai in questo sito.

Dissipa i tuoi dubbi