diff options
author | Florian Merz <me@fiji-flo.de> | 2021-02-11 14:47:54 +0100 |
---|---|---|
committer | Florian Merz <me@fiji-flo.de> | 2021-02-11 14:47:54 +0100 |
commit | 30feb96f6084a2fb976a24ac01c1f4a054611b62 (patch) | |
tree | d73194ae27b60156ff0ca54013c8c4ad8519f10a /files/it/learn/forms | |
parent | 8260a606c143e6b55a467edf017a56bdcd6cba7e (diff) | |
download | translated-content-30feb96f6084a2fb976a24ac01c1f4a054611b62.tar.gz translated-content-30feb96f6084a2fb976a24ac01c1f4a054611b62.tar.bz2 translated-content-30feb96f6084a2fb976a24ac01c1f4a054611b62.zip |
unslug it: move
Diffstat (limited to 'files/it/learn/forms')
-rw-r--r-- | files/it/learn/forms/form_validation/index.html | 846 | ||||
-rw-r--r-- | files/it/learn/forms/how_to_build_custom_form_controls/index.html | 825 | ||||
-rw-r--r-- | files/it/learn/forms/index.html | 85 |
3 files changed, 1756 insertions, 0 deletions
diff --git a/files/it/learn/forms/form_validation/index.html b/files/it/learn/forms/form_validation/index.html new file mode 100644 index 0000000000..9557758529 --- /dev/null +++ b/files/it/learn/forms/form_validation/index.html @@ -0,0 +1,846 @@ +--- +title: Validazione lato client delle form +slug: Learn/HTML/Forms/Form_validation +tags: + - Apprendere + - Esempio + - Forms + - Guida + - HTML + - JavaScript + - Principiante + - Web + - regex +translation_of: Learn/Forms/Form_validation +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/Forms/UI_pseudo-classes", "Learn/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}</div> + +<div>Prima di inviare dati al server, è importante assicurarsi che tutti i campi richiesti della form siano stati inseriti e siano nel formato richiesto. Questa viene chiamata <strong>validazione delle form lato client</strong>, ed aiuta a fare in modo che i dati inviati siano consistenti con quanto richiesto. Questo articolo illustra anche con esempi i concetti base della validazione.</div> + +<div></div> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisiti:</th> + <td>Conoscenze informatiche, ed una ragionevole comprensione di <a href="/en-US/docs/Learn/HTML">HTML</a>, <a href="/en-US/docs/Learn/CSS">CSS</a>, e <a href="/en-US/docs/Learn/JavaScript">JavaScript</a>.</td> + </tr> + <tr> + <th scope="row">Obiettivo:</th> + <td>Capire che cos'è la validazione delle form lato client, perché è importante e come applicare le varie tecniche per implementarla.</td> + </tr> + </tbody> +</table> + +<p>La validazione lato client è un controllo che va fatto subito ed è una caratteristica importante per una buona esperienza untente; trovando i dati non corretti nel lato client, l'utente li può correggere immediatamente. Se i dati non corretti venissero inviati al server e rifiutati, si assisterebbe ad un considerevole e fastidioso ritardo operativo dovuto al traffico tra client e server per le richieste di correzione.</p> + +<p>Comunque, la validazione lato client <em>non dovrebbe essere considerata</em> una misura di sicurezza sufficiente! La tua app dovrebbe sempre eseguire controlli di sicurezza <strong>anche</strong> nel <em>lato server,</em> perché le validazioni lato client sono troppo facili da bypassare, quindi gli utenti malevoli potrebbero comunque spedire dati non corretti al server. Leggi l'articolo <a href="/en-US/docs/Learn/Server-side/First_steps/Website_security">Website security</a> per farti un idea di quello che <em>potrebbe</em> succedere; in questo articolo non trattiamo la validazione lato server, ma tu dovresti tenerla presente.</p> + +<h2 id="Che_cosè_la_validazione_delle_form">Che cos'è la validazione delle form?</h2> + +<p>Vai su qualche diffuso sito con registrazione delle form e ti accorgerai che ti fornirà informazioni immediate se non inserisci i dati nel formato che loro si aspettano. Otterrai messaggi simili a questi:</p> + +<ul> + <li>"Questo è un camo richiesto" (Non lo puoi lasciare in bianco).</li> + <li>"Per favore inserisci il numero di telefono nel formato xxx-xxxx" (Viene richiesto uno specifico formato di dato per essere considerato valido).</li> + <li>"Per favore inserisci un indirizzo email valido" (la mail inserita non è nel formato corretto).</li> + <li>"La password deve essere compresa tra 8 e 30 caratteri e deve contenere lettere maiuscole, minuscole, simboli e numeri." (Viene richiesto un formato molto particolare).</li> +</ul> + +<p>Questa viene chiamata <strong>validazione della form</strong>. Quando inserisci i dati il browser e/o il web server controllano se i dati sono corretti secondo le regole stabilite dalla applicazione. La validazione fatta dal browser viene chiamata validazione <strong>lato client</strong> e quella fatta dal server viene chiamata validazione <strong>lato server</strong>. Questo articolo si occupa della validazione lato client.</p> + +<p>Se le informazioni hanno il formato corretto, l'applicazione consente che vengano spedite al server il quale di solito le salva in un database. Se invece non sono corrette, viene mandato un messaggo all'utente spiegando l'errore e consentendo di riprovare.</p> + +<p>Noi desideriamo che l'inserimento delle form sia il più facile possibile. Quindi per quale motivo insistiamo per la validazione? I motivi principali sono tre:</p> + +<ul> + <li><strong>Vogliamo che ci arrivino i dati giusti nel formato corretto.</strong> La nostra applicazione potrebbe non funzionare in modo corretto se i dati che ci arrivano sono scorretti o incompleti.</li> + <li><strong>Vogliamo proteggere i dati degli utenti</strong>. Costringendo gli utenti ad inserire password robuste facilitiamo la protezione delle loro informazioni anagrafiche.</li> + <li><strong>Vogliamo proteggere noi stessi</strong>. Ci sono molti modi che gli utenti malevoli possono provare per danneggiare le applicazioni se la form non è protetta (vedi <a href="/en-US/docs/Learn/Server-side/First_steps/Website_security">Website security</a>).<br> + {{warning("Mai fidarsi dei dati inviati al server dal client. Anche se la form è stata validata correttamente, gli utenti malevoli potrebbero alterare la richiesta di rete.")}}</li> +</ul> + +<h2 id="Differenti_tipi_di_validazione_lato_client">Differenti tipi di validazione lato client</h2> + +<p>Ci sono due tipi di validazione che si possono incontrare nel web:</p> + +<ul> + <li><strong>Validazione built-in della form</strong> usando le funzionalità di validazione delle form di HTML5, di cui parleremo spesso in questo articolo. Questo tipo di validazione di solito non richiedono molto JavaScript. La validazione built-in ha prestazioni migliori di JavaScript, ma non è altrettanto configurabile.</li> + <li><strong>Validazione JavaScript</strong> che viene eseguita scrivendo codice JavaScript. Questa validazione si può configurare come si desidera ma deve essere scritta interamente (oppure si usa una delle molte librerie disponibili).</li> +</ul> + +<h2 id="Usare_la_validazione_built-in_delle_form">Usare la validazione built-in delle form</h2> + +<p>Una delle funzionalità più significative dei <a href="/en-US/docs/Learn/Forms/HTML5_input_types">HTML5 form controls</a> è la capacità di effettuare molte validazioni senza richiedere l'uso di JavaScript. Questo viene fatto usando attributi di validazione negli elementi della form. Lo abbiamo visto anche in altre occasioni, ma ricapitolando:</p> + +<ul> + <li><code><a href="/en-US/docs/Web/HTML/Attributes/required">required</a></code>: Specifica che è un campo che deve essere riempito prima di poter invare i dati.</li> + <li><code><a href="/en-US/docs/Web/HTML/Attributes/minlength">minlength</a></code> e <code><a href="/en-US/docs/Web/HTML/Attributes/maxlength">maxlength</a></code>: Specifica la dimensione minima e massima dei campi di testo</li> + <li><code><a href="/en-US/docs/Web/HTML/Attributes/min">min</a></code> e <code><a href="/en-US/docs/Web/HTML/Attributes/max">max</a></code>: Specifica i valori minimi e massimi dei campi di tipo numerico</li> + <li><code>type</code>: Specifica se il dato deve essere un numero, un indirizzo email o qualche altro tipo predefinito. </li> + <li><code><a href="/en-US/docs/Web/HTML/Attributes/pattern">pattern</a></code>: Specifica una <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions">regular expression</a> che definisce le regole che i dati inseriti devono seguire.</li> +</ul> + +<p>Se i dati inseriti nella form seguono tutte le regole specificate dagli attributi è considerata valida. Altrimenti viene considerata non valida.</p> + +<p>Quando un elemento è valido, le seguenti cose sono vere:</p> + +<ul> + <li>L'elemento è conforme alla pseudo-classe {{cssxref(":valid")}} CSS, che ti consente di applicare uno stile specifico agli elementi validi.</li> + <li>Se l'utente prova ad inviare i dati il browser spedirà la form se non c'è nient altro le la blocca (ad esempio ulteriori validazioni JavaScript).</li> +</ul> + +<p>Quando un elemento non è valido, le seguenti cose sono vere:</p> + +<ul> + <li>L'elemento è conforme alla pseudo-classe {{cssxref(":invalid")}} CSS, e qualche altra pseudo-classe (es. {{cssxref(":out-of-range")}}) in base al tipo di errore che ti consente di applicare uno stile specifico agli elementi non validi.</li> + <li>Se l'utente prova ad inviare i dati il browser blocca la form e visualizza un adeguanto messaggio di errore.</li> +</ul> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Esistiono alcuni errori che impediscono la spedizione della form, compreso {{domxref('validityState.badInput', 'badInput')}}, {{domxref('validityState.patternMismatch','patternMismatch')}}, {{domxref('validityState.rangeOverflow','rangeOverflow')}} o {{domxref('validityState.rangeUnderflow','rangeUnderflow')}}, {{domxref('validityState.stepMismatch','stepMismatch')}}, {{domxref('validityState.tooLong','tooLong')}} or {{domxref('validityState.tooShort','tooShort')}}, {{domxref('validityState.typeMismatch','typeMismatch')}}, {{domxref('validityState.valueMissing','valueMissing')}}, o un {{domxref('validityState.customError','customError')}}.</p> +</div> + +<h2 id="Esempi_di_validazione_built-in_delle_form">Esempi di validazione built-in delle form</h2> + +<p>In questa sezione proveremo alcuni degli attributi di cui abbiamo parlato sopra.</p> + +<h3 id="Semplice_esempio_iniziale">Semplice esempio iniziale</h3> + +<p>Incominciamo con un esempio semplice: Un campo di testo che ti permette di scegliere se preferisci le banane o le ciliege (banana or cherry). Questo esempio richiede un semplice testo {{HTMLElement("input")}} con associata una {{htmlelement("label")}} e un pulsante di invio {{htmlelement("button")}}. Il codice sorgente si trova su GitHub su <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-start.html">fruit-start.html</a> con un esempio live.</p> + +<pre class="brush: html notranslate"><form> + <label for="choose">Would you prefer a banana or cherry?</label> + <input id="choose" name="i_like"> + <button>Submit</button> +</form></pre> + +<pre class="brush: css notranslate">input:invalid { + border: 2px dashed red; +} + +input:valid { + border: 2px solid black; +}</pre> + +<p>{{EmbedLiveSample("Simple_start_file", "100%", 80)}}</p> + +<p>Per incominciare fai una copia di <code>fruit-start.html</code> in una directory vuota del tuo disco fisso.</p> + +<h3 id="Lattributo_required">L'attributo required</h3> + +<p>La validazione HTML5 più semplice è l'attributo <code><a href="/en-US/docs/Web/HTML/Attributes/required">required</a></code>. Per rendere obbligatorio un campo input aggiungi questo attributo. Se è presente, l'elemento esegue il controllo con la pseudo-classe {{cssxref(':required')}} e la form non viene inviata e visualizza un messaggio d'errore se il campo input è vuoto. Quando è vuoto il campo è considerato non valido anche dalla pseudo-classe {{cssxref(':invalid')}}.</p> + +<p>Aggiungi l'attributo <code>required</code> come si vede qui sotto.</p> + +<pre class="brush: html notranslate"><form> + <label for="choose">Would you prefer a banana or cherry? (required)</label> + <input id="choose" name="i_like" required> + <button>Submit</button> +</form></pre> + +<p>Considera il CSS che è incluso nel file d'esempio:</p> + +<pre class="brush: css notranslate">input:invalid { + border: 2px dashed red; +} + +input:invalid:required { + background-image: linear-gradient(to right, pink, lightgreen); +} + +input:valid { + border: 2px solid black; +}</pre> + +<p>Questo CSS assegna all'input un bordo rosso a trattini quando il valore non è valido ed una linea nera più sottile quando è valido. Abbiamo anche aggiunto uno sfondo a gradiente quando è richiesto e non valido. Prova il nuovo comportamento nell'esempio sotto:</p> + +<p>{{EmbedLiveSample("The_required_attribute", "100%", 80)}}</p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Puoi trovare questo esempio live su GitHub come <a href="https://mdn.github.io/learning-area/html/forms/form-validation/fruit-required.html">fruit-validation.html</a> (vedi anche il <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-required.html">codice sorgente</a>.)</p> +</div> + +<p>Prova ad inviare la form senza un valore. Nota che i campo non valido acquista il focus ed appare il messaggio predefinito ("Per favore inserisci questo campo"), e la form non viene inviata.</p> + +<p>La presenza dell'attributo <code>required</code> in un elemento che lo supporta comporta che l'elemento controlla la pseudoclasse {{cssxref(':required')}} per controllare se contiene un valore oppure no. Se il campo {{HTMLElement("input")}} non ha un valore, attiva la pseudoclasse {{cssxref(':invalid')}}.</p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Per una buona esperienza utente, indica all'utente quando un campo è richiesto. Non è solo una buona pratica, ma è anche richiesto dalle linee guida <a href="/en-US/docs/Learn/Accessibility">accessibility</a> del WCAG. È anche bene rendere obbligatori i soli campi che ti servono. è inutile rendere obbligatori i campi di cui non hai reale necessità.</p> +</div> + +<h3 id="Validazione_con_una_regular_expression">Validazione con una regular expression</h3> + +<p>Un'altra caratteristica di validazione molto usata è l'attributo <a href="/en-US/docs/Web/HTML/Attributes/pattern"><code>pattern</code></a>, che si aspetta una <a href="/en-US/docs/JavaScript/Guide/Regular_Expressions">Regular Expression</a> come valore. Una regular expression (regex) è un modello che può essere usato per confrontare una combinazione di caratteri in una stringa, questo li rende ottimi per la validazione delle form e vengono usati anche per un certo numero di altri usi in JavaScript.</p> + +<p>I regex sono abbastanza complessi, e non riusciamo a spiegarli in modo completo in questo articolo. Di seguito riportiamo alcuni esempi per darti un'idea di base su come funzionano.</p> + +<ul> + <li><code>a</code> — Accetta un carattere che deve essere <code>a</code> (non <code>b</code>, nemmeno <code>aa</code>, e così via).</li> + <li><code>abc</code> — Accetta <code>a</code>, seguito da <code>b</code>, seguito da <code>c</code>.</li> + <li><code>ab?c</code> — Accetta <code>a</code>, opzionalmente seguito <code>b</code>, seguito <code>c</code>. ( <code>ac</code> oppure <code>abc</code>)</li> + <li><code>ab*c </code>— Accetta <code>a</code>, opzionalmente seguito da qualsiasi numero di <code>b</code>, seguito da <code>c</code>. ( <code>ac</code> , <code>abc</code>, <code>abbbbbc</code>, e via di seguito).</li> + <li><code>a|b</code> — Accetta un carattere che può essere <code>a</code> o <code>b</code>.</li> + <li><code>abc|xyz</code> — Accetta esattamente <code>abc</code> o esattamente <code>xyz</code> (ma non <code>abcxyz</code> o <code>a</code> o <code>y</code>, e così via).</li> +</ul> + +<p>Ci sono moltissime altre possibilità che non trattiamo. Per la lista completa e molti esempi consulta la nostra documentazione delle <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions">Regular expressions</a>.</p> + +<p>Proviamo ad implementare un esemio. Modifica il tuo HTML per aggiungere un attributo <a href="/en-US/docs/Web/HTML/Attributes/pattern"><code>pattern</code></a> come il seguente:</p> + +<pre class="brush: html notranslate"><form> + <label for="choose">Would you prefer a banana or a cherry?</label> + <input id="choose" name="i_like" required pattern="[Bb]anana|[Cc]herry"> + <button>Submit</button> +</form> +</pre> + +<div class="hidden"> +<pre class="brush: css notranslate">input:invalid { + border: 2px dashed red; +} + +input:valid { + border: 2px solid black; +}</pre> +</div> + +<p>Che ci da il seguente aggiornamento — prova:</p> + +<p>{{EmbedLiveSample("Validating_against_a_regular_expression", "100%", 80)}}</p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Puoi trovare questo esempio live su GitHub su <a href="https://mdn.github.io/learning-area/html/forms/form-validation/fruit-pattern.html">fruit-pattern.html</a> (guarda anche il <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-pattern.html">codice sorgente</a>.)</p> +</div> + +<p>In questo esempio, l'elemento {{HTMLElement("input")}} accetta una di quattro possibili valori: "banana", "Banana", "cherry", o "Cherry". Le regular expressions sono sono sensibili a maiuscole e minuscole, ma noi abbiamo supportato sia le parole minuscole che quelle con la prima maiuscola usando il modello "Aa" racchiuso tra parentesi quadre.</p> + +<p>Prova ora a cambiare il valore dell attributo <a href="/en-US/docs/Web/HTML/Attributes/pattern"><code>pattern</code></a> con gli esempi visti in precedenza e vedi in che modo cambiano i valori che puoi inserire. Prova anche a scrivere qualche regola per conto tuo e cerca di dare un senso alle regole rispetto al esempio della frutta!</p> + +<p>Se un valore di {{HTMLElement("input")}} non soddisfa il modello della regular expression il campo <code>input</code> applicherà la pseudoclasse {{cssxref(':invalid')}}.</p> + +<div class="blockIndicator note"> +<p><strong>Nota:</strong> Alcuni tipi di elemento {{HTMLElement("input")}} non necessitano di un attributo <a href="/en-US/docs/Web/HTML/Attributes/pattern"><code>pattern</code></a> per essere validati secondo una regular expression. Specificando il tipo <code>email</code>, ad esempio, l'input viene validato con il consolidato modello per la validazione delle email o con il modello per una lista di email separate da virgole se ha anche l'attributo <a href="/en-US/docs/Web/HTML/Attributes/multiple"><code>multiple</code></a>.</p> +</div> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: L'elemento {{HTMLElement("textarea")}} non supporta l'attributo <a href="/en-US/docs/Web/HTML/Attributes/pattern"><code>pattern</code></a>.</p> +</div> + +<h3 id="Limitare_la_dimensione_dei_campi">Limitare la dimensione dei campi</h3> + +<p>Puoi limitare la dimensione dei campi testo creati con {{HTMLElement("input")}} o {{HTMLElement("textarea")}} usando gli attributi <a href="/en-US/docs/Web/HTML/Attributes/minlength"><code>minlength</code></a> e <code><a href="/en-US/docs/Web/HTML/Attributes/maxlength">maxlength</a></code>. Un campo non è valido se ha meno caratteri del valore di <a href="/en-US/docs/Web/HTML/Attributes/minlength"><code>minlength</code></a> o maggiore del valore di <code><a href="/en-US/docs/Web/HTML/Attributes/maxlength">maxlength</a></code>.</p> + +<p>I browsers spesso non consentono all'utente di inserire più caratteri di quelli consentiti dal campo. Per migliorare l'esperienza utente invece di usare solamente <code>maxlength</code> si può fornire l'indicazione del numero di caratteri residui per dare modo all'utente di regolarsi. Un esempio di questo si trova in Twitter. Con JavaScript esiste una <a href="https://github.com/mimo84/bootstrap-maxlength">soluzione che usa <code>maxlength</code></a>, che si può utilizzare.</p> + +<h3 id="Limitare_i_valori_dei_campi">Limitare i valori dei campi</h3> + +<p>Per i campi numerici (es. <code><a href="/en-US/docs/Web/HTML/Element/input/number"><input type="number"></a></code>), gli attirbuti <code><a href="/en-US/docs/Web/HTML/Attributes/min">min</a></code> e <code><a href="/en-US/docs/Web/HTML/Attributes/max">max</a></code> possono essere utilizzati per fornire i limiti di valori validi. Se il campo contiene valori fuori dai limiti non è valido.</p> + +<p>Vediamo un altro esempio. Creiamo una copia del file <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-start.html">fruit-start.html</a>.</p> + +<p>Ora sostituiamo i contenuto dell'elemento <code><body></code> con il seguente:</p> + +<pre class="brush: html notranslate"><form> + <div> + <label for="choose">Would you prefer a banana or a cherry?</label> + <input type="text" id="choose" name="i_like" required minlength="6" maxlength="6"> + </div> + <div> + <label for="number">How many would you like?</label> + <input type="number" id="number" name="amount" value="1" min="1" max="10"> + </div> + <div> + <button>Submit</button> + </div> +</form></pre> + +<ul> + <li>Si può vedere che abbiamo messo 6 negli attrinuti <code>minlength</code> e <code>maxlength</code> del campo <code>text</code> che corrisponde alla lunghezza delle parole banana e cherry.</li> + <li>Abbiamo anche aggiunto un campo <code>number</code> con un <code>min</code> di uno ed un<code>max</code> di dieci. I numeri fuori dai limiti vengono visualizzati come non validi; gli utenti non possono usare le frecce di incremento e decremento per andare oltre i limiti. Se l'utente inserisce manualmente un dato esterno ai limiti il valore non è valido. Il numero non è obbligatorio quindi se si rimuove il valore, resta comunque valido.</li> +</ul> + +<div class="hidden"> +<pre class="brush: css notranslate">input:invalid { + border: 2px dashed red; +} + +input:valid { + border: 2px solid black; +} + +div { + margin-bottom: 10px; +}</pre> +</div> + +<p>Ecco un esempio live:</p> + +<p>{{EmbedLiveSample("Constraining_the_values_of_your_entries", "100%", 100)}}</p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Puoi trovare questo esempio live su GitHub su <a href="https://mdn.github.io/learning-area/html/forms/form-validation/fruit-length.html">fruit-length.html</a> (guarda anche il <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-length.html">codice sorgente</a>.)</p> +</div> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: <code><input type="number"></code> (ed anche altri tipi come <code>range</code> e <code>date</code>) possono anche avere l'attributo <a href="/en-US/docs/Web/HTML/Attributes/step"><code>step</code></a>, che specifica il valore minimo di incremento e decremento quando viene usato il campo (ad esempio premendo i pulsanti su e giu dei campi numerici). Nel esempio precedente non abbiamo inserito l'attributo <code>step</code> quindi il valore parte da <code>1</code>. Questo significa che i numeri con la virgola come 3.2, sono anch'essi non validi.</p> +</div> + +<h3 id="Esempio_completo">Esempio completo</h3> + +<p>Ecco un esempio completo che dimostra l'uso delle funzionalità di validazione built-in di HTML:</p> + +<pre class="brush: html notranslate"><form> + <p> + <fieldset> + <legend>Do you have a driver's license?<abbr title="This field is mandatory" aria-label="required">*</abbr></legend> + <!-- While only one radio button in a same-named group can be selected at a time, + and therefore only one radio button in a same-named group having the "required" + attribute suffices in making a selection a requirement --> + <input type="radio" required name="driver" id="r1" value="yes"><label for="r1">Yes</label> + <input type="radio" required name="driver" id="r2" value="no"><label for="r2">No</label> + </fieldset> + </p> + <p> + <label for="n1">How old are you?</label> + <!-- The pattern attribute can act as a fallback for browsers which + don't implement the number input type but support the pattern attribute. + Please note that browsers that support the pattern attribute will make it + fail silently when used with a number field. + Its usage here acts only as a fallback --> + <input type="number" min="12" max="120" step="1" id="n1" name="age" + pattern="\d+"> + </p> + <p> + <label for="t1">What's your favorite fruit?<abbr title="This field is mandatory" aria-label="required">*</abbr></label> + <input type="text" id="t1" name="fruit" list="l1" required + pattern="[Bb]anana|[Cc]herry|[Aa]pple|[Ss]trawberry|[Ll]emon|[Oo]range"> + <datalist id="l1"> + <option>Banana</option> + <option>Cherry</option> + <option>Apple</option> + <option>Strawberry</option> + <option>Lemon</option> + <option>Orange</option> + </datalist> + </p> + <p> + <label for="t2">What's your e-mail address?</label> + <input type="email" id="t2" name="email"> + </p> + <p> + <label for="t3">Leave a short message</label> + <textarea id="t3" name="msg" maxlength="140" rows="5"></textarea> + </p> + <p> + <button>Submit</button> + </p> +</form></pre> + +<p>Ed ora un po' di CSS per dare stile al HTML:</p> + +<pre class="brush: css notranslate">form { + font: 1em sans-serif; + max-width: 320px; +} + +p > label { + display: block; +} + +input[type="text"], +input[type="email"], +input[type="number"], +textarea, +fieldset { + width : 100%; + border: 1px solid #333; + box-sizing: border-box; +} + +input:invalid { + box-shadow: 0 0 5px 1px red; +} + +input:focus:invalid { + box-shadow: none; +}</pre> + +<p>Questo viene presentato nel modo seguente:</p> + +<p>{{EmbedLiveSample("Full_example", "100%", 420)}}</p> + +<p>Vedi <a href="/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation#Validation-related_attributes">Validation-related attributes</a> per la lista completa degli attributi che possono essere utilizzati per limitare i valori ed i tipi di input che li supportano.</p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Puoi trovare questo esempio live su GitHub su <a href="https://mdn.github.io/learning-area/html/forms/form-validation/full-example.html">full-example.html</a> (guarda anche il <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/full-example.html">codice sorgente</a>.)</p> +</div> + +<h2 id="Validazione_delle_forms_con_JavaScript">Validazione delle forms con JavaScript</h2> + +<p>Sei costretto ad usare JavaScript se desideri controllare l'aspetto dei messaggi nativi d'errore o per conformarti ai browsers più vecchi che non supportano la validazione built-in di HTML. In questa sezione daremo un occhiata a diversi modi per farlo.</p> + +<h3 id="Le_API_di_limitazione_della_validazione">Le API di limitazione della validazione</h3> + +<p>Molti browsers supportano le <a href="/en-US/docs/Web/API/Constraint_validation">Constraint Validation API</a>, che consistono in un gruppo di metodi e proprietà disponibili nelle seguienti interfaccie degli elementi delle form del DOM:</p> + +<ul> + <li><code><a href="/en-US/docs/Web/API/HTMLButtonElement">HTMLButtonElement</a></code> (risponde all'elemento <code><a href="/en-US/docs/Web/HTML/Element/button"><button></a></code>)</li> + <li><code><a href="/en-US/docs/Web/API/HTMLFieldSetElement">HTMLFieldSetElement</a></code> (risponde all'elemento <code><a href="/en-US/docs/Web/HTML/Element/fieldset"><fieldset></a></code>)</li> + <li><code><a href="/en-US/docs/Web/API/HTMLInputElement">HTMLInputElement</a></code> (risponde all'elemento <code><a href="/en-US/docs/Web/HTML/Element/input"><input></a></code>)</li> + <li><code><a href="/en-US/docs/Web/API/HTMLOutputElement">HTMLOutputElement</a></code> (risponde all'elemento <code><a href="/en-US/docs/Web/HTML/Element/output"><output></a></code>)</li> + <li><code><a href="/en-US/docs/Web/API/HTMLSelectElement">HTMLSelectElement</a></code> (risponde all'elemento <code><a href="/en-US/docs/Web/HTML/Element/select"><select></a></code>)</li> + <li><code><a href="/en-US/docs/Web/API/HTMLTextAreaElement">HTMLTextAreaElement</a></code> (risponde all'elemento <code><a href="/en-US/docs/Web/HTML/Element/textarea"><textarea></a></code>)</li> +</ul> + +<p id="Constraint_validation_API_properties">Le API di validazione rendono le seguenti proprietà disponibili per li elementi di cui sopra.</p> + +<ul> + <li><code>validationMessage</code>: Restituisce un messaggio che descrive il limite di validazione che il campo non soddisfa nella lingua del browser. Se il campo non ha limiti di validazione (<code>willValidate</code> è <code>false</code>) o se il valore è valido restituisce una stringa vuota.</li> + <li><code>validity</code>: Restituisce un oggetto <code>ValidityState</code> che contiene alcune proprietà che descrivono lo stato di validità dell'elemento. Puoi trovare tutti i dettagli delle proprietà disponibili nella pagina di riferimento {{domxref("ValidityState")}}; sotto elenchiamo alcuni dei più comuni: + <ul> + <li>{{domxref("ValidityState.patternMismatch", "patternMismatch")}}: Restituisce <code>true</code> se il valore non è conforme al modello specificato in {{htmlattrxref("pattern", "input")}}, e <code>false</code> se è conforme. Se è <code>true</code>, l'elemento attiva la pseudoclasse CSS {{cssxref(":invalid")}}.</li> + <li>{{domxref("ValidityState.tooLong", "tooLong")}}: Restituisce <code>true</code> se il valore supera la lunghezza massima specificata in {{htmlattrxref("maxlength", "input")}}, o <code>false</code> se è più corta o ugauale al massimo.Se è <code>true</code>, l'elemento attiva la pseudoclasse CSS {{cssxref(":invalid")}}.</li> + <li>{{domxref("ValidityState.tooShort", "tooShort")}}: Restituisce <code>true</code> se il valore è più corto della dimensione minima specificata da {{htmlattrxref("minlength", "input")}}, o <code>false</code> se è uguale o maggiore del minimo. Se è <code>true</code>, l'elemento attiva la pseudoclasse CSS {{cssxref(":invalid")}}.</li> + <li>{{domxref("ValidityState.rangeOverflow", "rangeOverflow")}}: Restituisce <code>true</code> se il valore supera il massimo specificato da {{htmlattrxref("max", "input")}}, o <code>false</code> se è inferiore o uguale al massimo. Se è <code>true</code>, l'elemento attiva le pseudoclassi {{cssxref(":invalid")}} e {{cssxref(":out-of-range")}}.</li> + <li>{{domxref("ValidityState.rangeUnderflow", "rangeUnderflow")}}: Restituisce <code>true</code> se il valore è inferiore al minimo specificato da {{htmlattrxref("min", "input")}}, o <code>false</code> se è maggiore o ugualeal minimo. Se è <code>true</code>, l'elemento attiva le pseudoclassi {{cssxref(":invalid")}} e {{cssxref(":out-of-range")}}.</li> + <li>{{domxref("ValidityState.typeMismatch", "typeMismatch")}}: Restituisce <code>true</code> non rispetta la sintassi (quando {{htmlattrxref("type", "input")}} è <code>email</code> o <code>url</code>), o <code>false</code> se la sintassi è corretta. Se è <code>true</code>, l'elemento attiva la pseudoclasse CSS {{cssxref(":invalid")}}.</li> + <li><code>valid</code>: Restituisce <code>true</code> se l'elemento rispetta tutti i parametri di validazione ed è quindi considerato valido, o <code>false</code> se non ne rispetta almeno uno. Se è <code>true</code>, l'elemento attiva la pseudoclasse CSS {{cssxref(":valid")}}; altimenti attiva la pseudocasse {{cssxref(":invalid")}}.</li> + <li><code>valueMissing</code>: Restituisce <code>true</code> se l'elemento possiede l'attributo {{htmlattrxref("required", "input")}}, ma non è stato inserito un valore o <code>false</code> altirmenti. Se è <code>true</code>, l'elemento attiva la pseudoclasse CSS {{cssxref(":invalid")}}.</li> + </ul> + </li> + <li><code>willValidate</code>: Restituisce <code>true</code> se l'elemento verrà validato quando la form verrà spedita; altrimenti <code>false</code>.</li> +</ul> + +<p id="Constraint_validation_API_methods">Le API di validazione rendono anche disponibili i seguenti metodi per gli elementi di cui sopra.</p> + +<ul> + <li><code>checkValidity()</code>: Restituisce <code>true</code> se il valore dell'elemento non ha problemi di validazione; altrimenti <code>false</code>. Se l'elemento non è valido viene anche lanciato un <a href="/en-US/docs/Web/API/HTMLInputElement/invalid_event"><code>invalid</code> event</a> sul elemento.</li> + <li><code>setCustomValidity(<em>message</em>)</code>: Aggiunge un messaggio di errore personalizzato all'elemento; se si imposta il messaggio di errore personalizzato l'elemento viene considerato non valido, e viene visualizzato l'errore specificato. Questo consente di usare codice JavaScript per stabilire condizioni di errore di validazione diversi da quelli messi a disposizione dallo standard HTML5. Il messaggio viene esposto all'utente quando si presenta il problema.</li> +</ul> + +<h4 id="Implementare_un_messaggio_di_errore_personalizzato">Implementare un messaggio di errore personalizzato</h4> + +<p>Come abbiamo visto negli esempi di limiti di validazione HTML5 in precedenza, ogni volta che l'utente tenta di inviare una form non valida, il browser visualizza un messaggio d'errore. Il modo in cui viene visualizzato dipende dal browser.</p> + +<p>Questi messaggi automatizzati hanno due controindicazioni:</p> + +<ul> + <li>Non c'è modo di cambiare il loro aspetto con CSS.</li> + <li>Essi dipendono dalla lingua del browser, che signfica che potresiti avere una pagina scritta in una lingua ed i messaggi di errore in un'altra come si vede in questa immagine presa da Firefox.</li> +</ul> + +<p><img alt="Example of an error message with Firefox in French on an English page" src="/files/4329/error-firefox-win7.png" style="height: 97px; width: 228px;"></p> + +<p>Personalizzare questi messaggi di errore è uno dei casi più comuni di utilizzo delle <a href="/en-US/docs/Web/API/Constraint_validation" rel="external">constraint validation API</a>. Vediamo un piccolo esempio di come fare questo.</p> + +<p>Incominciamo con un po' di HTML semplice (prova ad inserirlo in un file HTML vuoto o usa come base una copia di of <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/fruit-start.html">fruit-start.html</a> come preferisci):</p> + +<pre class="brush: html notranslate"><form> + <label for="mail">I would like you to provide me with an e-mail address:</label> + <input type="email" id="mail" name="mail"> + <button>Submit</button> +</form></pre> + +<p>Ed aggiungi il seguente JavaScript alla pagina:</p> + +<pre class="brush: js notranslate">const email = document.getElementById("mail"); + +email.addEventListener("input", function (event) { + if (email.validity.typeMismatch) { + email.setCustomValidity("I am expecting an e-mail address!"); + } else { + email.setCustomValidity(""); + } +});</pre> + +<p>Qui aggiungiamo un riferimento al campo email ed aggiungiamo un event listener che viene eseguito ogni volta che il valore cambia.</p> + +<p>Nel codici controlliamo se la proprietà <code>validity.typeMismatch</code> del campo emali diventa <code>true</code>, significa che il valore contenuto non corrisponde al modello degli indirizzi email. Se è così viene chiamato il metodo <a href="/en-US/docs/HTML/HTML5/Constraint_validation#Constraint_API's_element.setCustomValidity()"><code>setCustomValidity()</code></a> con un messaggio appropriato. Questo rende il campo non valido, in modo che quando viene inviata la form, l'invio fallisce e viene visualizzato il messaggio di errore.</p> + +<p>Se la proprietà <code>validity.typeMismatch</code> restituisce <code>false</code>, chiamiamo il metodo <code>setCustomValidity()</code> con una stringa vuota che rende valido il campo in modo che possa essere spedito.</p> + +<p>Lo puoi provare con:</p> + +<p>{{EmbedGHLiveSample("learning-area/html/forms/form-validation/custom-error-message.html", '100%', 80)}}</p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Puoi trovare questo esempio live su GitHub su <a href="https://mdn.github.io/learning-area/html/forms/form-validation/custom-error-message.html">custom-error-message.html</a> (vedi anche il <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/custom-error-message.html">codice sorgente</a>.)</p> +</div> + +<h4 id="Un_esempio_più_dettagliato">Un esempio più dettagliato</h4> + +<p>Ora che abbiamo visto un esempio molto semplice, vediamo come possiamo usare le API per costurire un sistema di validazione un po' più complesso.</p> + +<p>Prima di tutto il codice HTML:</p> + +<pre class="brush: html notranslate"><form novalidate> + <p> + <label for="mail"> + <span>Please enter an email address:</span> + <input type="email" id="mail" name="mail" required minlength="8"> + <span class="error" aria-live="polite"></span> + </label> + </p> + <button>Submit</button> +</form></pre> + +<p>Questa semplice form usa l'attributo <code><a href="/en-US/docs/Web/HTML/Attributes/novalidate">novalidate</a></code> per disattivare la validazine automatica del browser; questo consente al nostro script di prendere il controllo della validazione. Questo comunque non disabilita il supporto per le API di validazione e l'applicazione delle pseudoclassi CSS come {{cssxref(":valid")}}, ecc. Questo significa che se anche il browser con controlla la validità della form prima di spedire i dati, tu puoi comunque farlo dal solo ed applicare lo stile appropriato.</p> + +<p>Il nostro input da validare è un <code><a href="/en-US/docs/Web/HTML/Element/input/email"><input type="email"></a></code>, che è <code>required</code>, ed ha un <code>minlength</code> di 8 caratteri. Proviamo a controllare la validità usando il nostro codice e visualizziamo un messaggio appropriato per ciascun attributo.</p> + +<p>Ci proponiamo di visualizzare il messaggio all'intermo di un elemento <code><span></code>. L'attributo <a href="/en-US/docs/Accessibility/ARIA/ARIA_Live_Regions"><code>aria-live</code></a> per assicurarci che il nostro messaggio di errore verrà reso disponibile a tutti compresi coloro che usano i lettori di schermo.</p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Il punto chiave qui è l'uso dell'attributo <code>novalidate</code> per la form che è ciò che impedisce alla form di vidualizzare il proprio messaggio di errore e ci consente invece di visualizzare il nostro messaggio presonalizzato nel DOM in qualche modo scelto da noi.</p> +</div> + +<p>Ora un po' di CSS oer migliorare leggermente il look della form, e fornire qualche tipo di informazione quando il valore non è valido:</p> + +<pre class="brush: css notranslate">body { + font: 1em sans-serif; + width: 200px; + padding: 0; + margin : 0 auto; +} + +p * { + display: block; +} + +input[type=email]{ + -webkit-appearance: none; + appearance: none; + + width: 100%; + border: 1px solid #333; + margin: 0; + + font-family: inherit; + font-size: 90%; + + box-sizing: border-box; +} + +/* This is our style for the invalid fields */ +input:invalid{ + border-color: #900; + background-color: #FDD; +} + +input:focus:invalid { + outline: none; +} + +/* This is the style of our error messages */ +.error { + width : 100%; + padding: 0; + + font-size: 80%; + color: white; + background-color: #900; + border-radius: 0 0 5px 5px; + + box-sizing: border-box; +} + +.error.active { + padding: 0.3em; +}</pre> + +<p>Ora vediamo il codice JavaScript che implementa l'errore personalizzato di validazione.</p> + +<pre class="brush: js notranslate">// There are many ways to pick a DOM node; here we get the form itself and the email +// input box, as well as the span element into which we will place the error message. +const form = document.getElementsByTagName('form')[0]; + +const email = document.getElementById('mail'); +const emailError = document.querySelector('#mail + span.error'); + +email.addEventListener('input', function (event) { + // Each time the user types something, we check if the + // form fields are valid. + + if (email.validity.valid) { + // In case there is an error message visible, if the field + // is valid, we remove the error message. + emailError.innerHTML = ''; // Reset the content of the message + emailError.className = 'error'; // Reset the visual state of the message + } else { + // If there is still an error, show the correct error + showError(); + } +}); + +form.addEventListener('submit', function (event) { + // if the email field is valid, we let the form submit + + if(!email.validity.valid) { + // If it isn't, we display an appropriate error message + showError(); + // Then we prevent the form from being sent by canceling the event + event.preventDefault(); + } +}); + +function showError() { + if(email.validity.valueMissing) { + // If the field is empty + // display the following error message. + emailError.textContent = 'You need to enter an e-mail address.'; + } else if(email.validity.typeMismatch) { + // If the field doesn't contain an email address + // display the following error message. + emailError.textContent = 'Entered value needs to be an e-mail address.'; + } else if(email.validity.tooShort) { + // If the data is too short + // display the following error message. + emailError.textContent = `Email should be at least ${ email.minLength } characters; you entered ${ email.value.length }.`; + } + + // Set the styling appropriately + emailError.className = 'error active'; +}</pre> + +<p>I commenti spiegano le cose per bene, ma brevemente:</p> + +<ul> + <li>Ogni volta che cambia il valore dell'input controlliamo per vedere se contiene dati validi. Se lo sono rimuoviamo eventuali messaggi di errore. Se invece ci sono errori eseguiamo <code>showError()</code> per inviare il messaggio appropriato.</li> + <li>Ogni volta che proviamo ad inviare la form controlliamo nuovamente se i dati sono validi. Se è così consentiamo la spedizione. Altrimenti eseguiamo <code>showError()</code> per visaulizzare il messaggio appropriato ed impedire la spedizione della form con <code><a href="/en-US/docs/Web/API/Event/preventDefault">preventDefault()</a></code>.</li> + <li>La funzione <code>showError()</code> utilizza varie proprietà della <code>validity</code> dell'input per determinare il tipo di errore e quindi visualizzare il messaggio appropriato.</li> +</ul> + +<p>Ecco il risultato live:</p> + +<p>{{EmbedGHLiveSample("learning-area/html/forms/form-validation/detailed-custom-validation.html", '100%', 150)}}</p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Puoi trovare questo esempio live su GitHub su <a href="https://mdn.github.io/learning-area/html/forms/form-validation/detailed-custom-validation.html">detailed-custom-validation.html</a> (vedi anche il <a href="https://github.com/mdn/learning-area/blob/master/html/forms/form-validation/detailed-custom-validation.html">codice sorgente</a>.)</p> +</div> + +<p>Le API di validazione ti forniscono uno stumento potente per gestire la validaizone delle form, fornendoti un grande controllo sulla interfaccia utente sopra e sotto quello che puoi fare con i soli HTML e CSS.</p> + +<div class="blockIndicator note"> +<p><strong>Nota</strong>: Per ulteriori ingormazioni vedi il nostro <a href="/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation">Constraint validation guide</a>, ed il riferimento <a href="/en-US/docs/Web/API/Constraint_validation">Constraint Validation API</a>.</p> +</div> + +<h3 id="Validare_le_forms_senza_le_built-in_API">Validare le forms senza le built-in API</h3> + +<p>In alcuni casi come ad esempio per i browsers più vecchi o per il supporto ai <a href="/en-US/docs/Learn/Forms/How_to_build_custom_form_controls">custom controls</a>, non sarà possibile usare le API di validazione. Potrai ancora utilizzare JavaScript per validare la tua form, ma devi scrivere tutto da solo.</p> + +<p>Per validare la form fatti alcune domande:</p> + +<dl> + <dt>Che tipo di validazione devo eseguire?</dt> + <dd>Devi determinare come validare i tuoi dati: operazioni sulle stringhe, conversioni di tipo, regular expressions, e via discorrendo. Sta tutto a te.</dd> + <dt>Cosa devo fare se la form non è valida?</dt> + <dd>Questo chiaramente è materia di UI. Devi decidere come si deve comportare la form. Deve la form spedire i dati ugualmente? Devi illuminare i campi che sono in errore? Devi visualizzare messaggi di errore?</dd> + <dt>Come posso aiutare l'utente a correggere i dati non validi?</dt> + <dd>Per ridurre la frustrazione dell'utente, è molto importante fornire il maggior numero di informazioni possibili per guidarlo a correggere gli errori. Dovresti fornire suggerimenti sui dati attesi ed anche messaggi di errore chiari e comprensibili. Se vuoi approfondire come approntare la UI adeguata per la validazione, ecco alcuni articoli utili che dovresti leggere: + <ul> + <li>SmashingMagazine: <a href="http://uxdesign.smashingmagazine.com/2012/06/27/form-field-validation-errors-only-approach/" rel="external">Form-Field Validation: The Errors-Only Approach</a></li> + <li>SmashingMagazine: <a href="http://www.smashingmagazine.com/2009/07/07/web-form-validation-best-practices-and-tutorials/" rel="external">Web Form Validation: Best Practices and Tutorials</a></li> + <li>Six Revision: <a href="http://sixrevisions.com/user-interface/best-practices-for-hints-and-validation-in-web-forms/" rel="external">Best Practices for Hints and Validation in Web Forms</a></li> + <li>A List Apart: <a href="http://www.alistapart.com/articles/inline-validation-in-web-forms/" rel="external">Inline Validation in Web Forms</a></li> + </ul> + </dd> +</dl> + +<h4 id="Un_esempio_che_non_usa_le_API_di_validazione">Un esempio che non usa le API di validazione</h4> + +<p>Per illustrare questo, quello che segue è una versione semplificata dell'esempio precedente che funziona anche con i browsers più vecchi.</p> + +<p>Il HTML è quasi uguale; abbiamo solo rimosso alcune funzionalità di validazione.</p> + +<pre class="brush: html notranslate"><form> + <p> + <label for="mail"> + <span>Please enter an email address:</span> + <input type="text" class="mail" id="mail" name="mail"> + <span class="error" aria-live="polite"></span> + </label> + </p> + <!-- Some legacy browsers need to have the `type` attribute + explicitly set to `submit` on the `button`element --> + <button type="submit">Submit</button> +</form></pre> + +<p>Allo stesso modo, anche il CSS non necessita di grandi modifiche; abbiamo solo trasformato la pseudoclasse {{cssxref(":invalid")}} in una vera classe ed evitato di usare il selettore di attiributo che non funziona con Internet Explorer 6.</p> + +<pre class="brush: css notranslate">body { + font: 1em sans-serif; + width: 200px; + padding: 0; + margin : 0 auto; +} + +form { + max-width: 200px; +} + +p * { + display: block; +} + +input.mail { + -webkit-appearance: none; + + width: 100%; + border: 1px solid #333; + margin: 0; + + font-family: inherit; + font-size: 90%; + + box-sizing: border-box; +} + +/* This is our style for the invalid fields */ +input.invalid{ + border-color: #900; + background-color: #FDD; +} + +input:focus.invalid { + outline: none; +} + +/* This is the style of our error messages */ +.error { + width : 100%; + padding: 0; + + font-size: 80%; + color: white; + background-color: #900; + border-radius: 0 0 5px 5px; + box-sizing: border-box; +} + +.error.active { + padding: 0.3em; +}</pre> + +<p>Le modifiche maggiori sono nel codice JavaScript, che richiede una revisione molto più pesante.</p> + +<pre class="brush: js notranslate">// There are fewer ways to pick a DOM node with legacy browsers +const form = document.getElementsByTagName('form')[0]; +const email = document.getElementById('mail'); + +// The following is a trick to reach the next sibling Element node in the DOM +// This is dangerous because you can easily build an infinite loop. +// In modern browsers, you should prefer using element.nextElementSibling +let error = email; +while ((error = error.nextSibling).nodeType != 1); + +// As per the HTML5 Specification +const emailRegExp = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/; + +// Many legacy browsers do not support the addEventListener method. +// Here is a simple way to handle this; it's far from the only one. +function addEvent(element, event, callback) { + let previousEventCallBack = element["on"+event]; + element["on"+event] = function (e) { + const output = callback(e); + + // A callback that returns `false` stops the callback chain + // and interrupts the execution of the event callback. + if (output === false) return false; + + if (typeof previousEventCallBack === 'function') { + output = previousEventCallBack(e); + if(output === false) return false; + } + } +}; + +// Now we can rebuild our validation constraint +// Because we do not rely on CSS pseudo-class, we have to +// explicitly set the valid/invalid class on our email field +addEvent(window, "load", function () { + // Here, we test if the field is empty (remember, the field is not required) + // If it is not, we check if its content is a well-formed e-mail address. + const test = email.value.length === 0 || emailRegExp.test(email.value); + + email.className = test ? "valid" : "invalid"; +}); + +// This defines what happens when the user types in the field +addEvent(email, "input", function () { + const test = email.value.length === 0 || emailRegExp.test(email.value); + if (test) { + email.className = "valid"; + error.innerHTML = ""; + error.className = "error"; + } else { + email.className = "invalid"; + } +}); + +// This defines what happens when the user tries to submit the data +addEvent(form, "submit", function () { + const test = email.value.length === 0 || emailRegExp.test(email.value); + + if (!test) { + email.className = "invalid"; + error.innerHTML = "I expect an e-mail, darling!"; + error.className = "error active"; + + // Some legacy browsers do not support the event.preventDefault() method + return false; + } else { + email.className = "valid"; + error.innerHTML = ""; + error.className = "error"; + } +});</pre> + +<p>Il risultato assomiglia a questo:</p> + +<p>{{EmbedLiveSample("An_example_that_doesnt_use_the_constraint_validation_API", "100%", 130)}}</p> + +<p>Come puoi vedere, non è proprio così difficile costruire un tuo sistema di validazione. La parte difficile è di renderlo abbastanza generico da essere usato su tutte le piattaforme e con ogni form che andarai a creare. Ci sono anche molte librerie pronte che ti aiuntano nella validazione come ad esempio <a href="http://rickharrison.github.com/validate.js/" rel="external">Validate.js</a>.</p> + +<h2 id="Metti_alla_prova_le_tue_capacità!">Metti alla prova le tue capacità!</h2> + +<p>Sei arrivato alla fine di questo articolo, ma riesci a ricordare le informazioni più importanti? Puoi trovare alcuni ulteriori test per verificare che tu abbia recepito questi informazioni prima di proseguire — vedi <a href="/en-US/docs/Learn/Forms/Test_your_skills:_Form_validation">Test your skills: Form validation</a>.</p> + +<h2 id="Sommario">Sommario</h2> + +<p>La validazione delle form lato client alle volte richiede JavaScript se desideri configurare lo stile ed i messaggi di errore, ma richiede <em>sempre</em> che tu pensi attentamente all'utente. Ricordati sempre di guidare l'utente ad inserire dati corretti. Quindi assicurati di:</p> + +<ul> + <li>Visualizzare messaggi di errore espliciti.</li> + <li>Sii permissivo per i formati di input non essenziali.</li> + <li>Segnala in modo esatto il punto in cui si verifica l'errore soprattutto se la form è molto grande.</li> +</ul> + +<p>Quando hai controllato che la form è stata compilata correttamente, la puoi inviare. In seguito spieghiamo come <a href="/en-US/docs/Learn/Forms/Sending_and_retrieving_form_data">spedire i dati delle form</a>.</p> + +<p>{{PreviousMenuNext("Learn/Forms/UI_pseudo-classes", "Learn/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}</p> + +<h2 id="In_questo_modulo">In questo modulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/Forms/Your_first_form">La tua prima form</a></li> + <li><a href="/en-US/docs/Learn/Forms/How_to_structure_a_web_form">Come strutturare una form web</a></li> + <li><a href="/en-US/docs/Learn/Forms/Basic_native_form_controls">I principali controlli nativi delle form</a></li> + <li><a href="/en-US/docs/Learn/Forms/HTML5_input_types">I tipi di input HTML5</a></li> + <li><a href="/en-US/docs/Learn/Forms/Other_form_controls">Altri controlli delle form</a></li> + <li><a href="/en-US/docs/Learn/Forms/Styling_web_forms">Aggiungere stile alle form web</a></li> + <li><a href="/en-US/docs/Learn/Forms/Advanced_form_styling">Stili delle form avanzati</a></li> + <li><a href="/en-US/docs/Learn/Forms/UI_pseudo-classes">Le pseudo-classi UI</a></li> + <li><a href="/en-US/docs/Learn/Forms/Form_validation">Validazione delle form dal dato client</a></li> + <li><a href="/en-US/docs/Learn/Forms/Sending_and_retrieving_form_data">Inviare i dati delle form</a></li> +</ul> + +<h3 id="Argomenti_avanzati">Argomenti avanzati</h3> + +<ul> + <li><a href="/en-US/docs/Learn/Forms/How_to_build_custom_form_controls">Come costurire controlli delle form personalizzati</a></li> + <li><a href="/en-US/docs/Learn/Forms/Sending_forms_through_JavaScript">Inviare le forms con JavaScript</a></li> + <li><a href="/en-US/docs/Learn/Forms/Property_compatibility_table_for_form_widgets">Tabella di compatibilità dei controlli per le form</a></li> +</ul> diff --git a/files/it/learn/forms/how_to_build_custom_form_controls/index.html b/files/it/learn/forms/how_to_build_custom_form_controls/index.html new file mode 100644 index 0000000000..288fa8e1c2 --- /dev/null +++ b/files/it/learn/forms/how_to_build_custom_form_controls/index.html @@ -0,0 +1,825 @@ +--- +title: Come costruire form widget personalizzati +slug: Learn/HTML/Forms/Come_costruire_custom_form_widgets_personalizzati +translation_of: Learn/Forms/How_to_build_custom_form_controls +--- +<div>{{PreviousMenuNext("Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms")}}</div> + +<p class="summary">Ci sono molti casi in cui <a href="/en-US/docs/HTML/Forms/The_native_form_widgets" title="/en-US/docs/HTML/Forms/The_native_form_widgets">i widget del modulo html disponibili</a> non sono abbastanza. Se vuoi eseguire <a href="/en-US/docs/Advanced_styling_for_HTML_forms" title="/en-US/docs/Advanced_styling_for_HTML_forms">uno styling avanzato</a> su alcuni widget come l'elemento {{HTMLElement("select")}} o sei vuoi fornirli di comportamenti personalizzati, l'unica scelta che hai è quella di costruirti il tuo widget personale.</p> + +<p>In quest'articolo vedremo come costruire questo tipo di widget. A tal fine lavoreremo con un esempio: ricostruire l'elemento {{HTMLElement("select")}} .</p> + +<div class="note"> +<p><strong>Nota:</strong> ci concentreremo sulla costruzione del widget, non su come rendere il codice generico e riutilizzabile; questo comporterebbe del codice JavaScript and la manipolazione del DOM in un contesto sconosciuto, uscendo fuori dallo scopo di quest'articolo.</p> +</div> + +<h2 id="Design_strutture_e_semantica">Design, strutture, e semantica</h2> + +<p>Prima di costruire un widget personalizzato, dovresti cominciare a pensare esattamente cosa vuoi. Questo ti aiuterà a evitare perdite di tempo. In particolare, e' importante definire chiaramente tutti gli stati del tuo widget. Per fare ciò, è bene cominciare da un widget esistente che ha stati e comportamenti ben noti.</p> + +<p>Nel nostro esempio ricostruiremo l'elemento {{HTMLElement("select")}} . Ecco il risultato che vogliamo raggiungere:</p> + +<p><img alt="The three states of a select box" src="/files/4481/custom-select.png" style="height: 135px; width: 366px;"></p> + +<p>Questo screenshot ci illustra i tre stati principali del nostro widget: lo stato normale(a sinistra); lo stato di attivazione ( al centro) and lo stato aperto (a destra).</p> + +<p>In termini di compartamento vogliamo che il nostro widget sia utilizabile con il mouse e con la tastiera, proprio come un ogni widget non modificato. Cominciamo definendo come il widget raggiungerà uno stato:</p> + +<dl> + <dt>Il widget è nel suo stato normale quando:</dt> + <dd> + <ul> + <li>la pagina carica</li> + <li>Il widget era attivo e l'utente fa clico ovunque al di fuori del widget</li> + <li>il widget era attivo e l'utente sposta lo stato attivo su un altro widget usando la tastiera</li> + </ul> + + <div class="note"> + <p><strong>Nota:</strong> Moving the focus around the page is usually done through hitting the tab key, but this is not standard everywhere. For example cycling through links on a page is done in Safari by default using the <a href="http://www.456bereastreet.com/archive/200906/enabling_keyboard_navigation_in_mac_os_x_web_browsers/" title="http://www.456bereastreet.com/archive/200906/enabling_keyboard_navigation_in_mac_os_x_web_browsers/">Option+Tab combination</a>.</p> + </div> + </dd> + <dt>Il widget è nel suo stato attivo quando:</dt> + <dd> + <ul> + <li>L'user lo clicca</li> + <li>L'user clicca il tasto tab e lo evidenzia</li> + <li>il widget era aperto and l'user clicca sul widget.</li> + </ul> + </dd> + <dt>Il widget è nello stato di apertura quando:</dt> + <dd> + <ul> + <li>il widget è in uno stato diverso da quello aperto e l'utente fa clic su di esso</li> + </ul> + </dd> +</dl> + +<p>Una volta compreso come cambiare gli stati, e importante definire come cambiare i valori del widget:</p> + +<dl> + <dt>I valori cambiano quando:</dt> + <dd> + <ul> + <li>l'user clicca su un'opzione quando il widget è nello stato di apertura</li> + <li>l'user preme dalla tastiera la frecciasu o giù quando il widget è aperto </li> + </ul> + </dd> +</dl> + +<p>Finalmente, possiamo definire come le opzioni del widget dovranno comportarsi:</p> + +<ul> + <li>Quando il widget è aperto, l'opzione selezionata è evidenziata</li> + <li>Quando il mouse si trova su un'opzione, l'opzione viene evidenziata e l'opzione evidenziata in precedenza viene riportata al suo stato normale</li> +</ul> + +<p>Ai fini del nostro esempio, ci fermeremo qui; comunque, se sei un lettore attendo avrai notato che mancano dei comportamenti. Per esempio: Cosa accadrà se l'user preme tab MENTRE il widget è aperto?La risposta è... Nulla. OK, il comportamento corretto sembra ovvio ma il fatto è che, poiché non è definito nelle nostre specifiche, è molto facile trascurare questo comportamento. Ciò è particolarmente vero in un ambiente di squadra quando le persone che progettano il comportamento del widget sono diverse da quelle che lo implementano.</p> + +<p>Un altro esempio divertente: Cosa succederà se l'user premerà il tasto su o giù mentre il widget è aperto? Questo è un po' più complicato. Se consideri che lo stato attivo e lo stato aperto sono totalmente diversi, la risposta è di nuovo " non succederà niente"!<br> + Perchè non abbiamo definito nessuna interazione con la tastiera quando il widget è aperto.D'altronde, se si considera che lo stato attivo e lo stato aperto si sovrappongono un po', il valore potrebbe cambiare ma l'opzione ma l'opzione non sarà sicuramente evidenziata di conseguenza, ancora una volta perchè non abbiamo definito interazioni con la tastiera con le opzioni quando il widget si trova nel suo stato aperto (abbiamo solo definito cosa dovrebbe accadere quando il widget è aperto, ma nulla dopo).</p> + +<p>le specifiche mancanti sono ovvie, quindi le gestiremo, ma potrebbe rivelare dei problemi in widget nuovi ed esotici, fper cui nessuno ha la minima idea di quale sia il comportamento giusto. E' sempre opportuno utilizzare bene il proprio tempo in questa fase di desgin: se definisci malamente un comportamento, o dimentichi di definirne uno, sarà molto difficile ridefinirlo una volta che gli utenti si saranno abituati. Se hai dubbi, chiedi l'opinione altrui , e se disponi di un budget non esitare in un<a href="http://en.wikipedia.org/wiki/Usability_testing" rel="external" title="http://en.wikipedia.org/wiki/Usability_testing"> user tests</a>. Questo processo è chiamato UX design. Se vuoi conoscere di più a proposito di questo argomento, dovresti controllare le seguenti risorse:</p> + +<ul> + <li><a href="http://www.uxmatters.com/" rel="external" title="http://www.uxmatters.com/">UXMatters.com</a></li> + <li><a href="http://uxdesign.com/" rel="external" title="http://uxdesign.com/">UXDesign.com</a></li> + <li><a href="http://uxdesign.smashingmagazine.com/" rel="external" title="http://uxdesign.smashingmagazine.com/">The UX Design section of SmashingMagazine</a></li> +</ul> + +<div class="note"> +<p><strong>Nota: </strong>In molti sistemi c'è un modo per aprire l'elemento {{HTMLElement("select")}} per esaminare tutte le scelte disponibili (lo stesso elemento {{HTMLElement("select")}} ). This is achieved with Alt+Down arrow under Windows and was not implemented in our example —but it would be easy to do so, as the mechanism has already been implemented for the <code>click</code> event.</p> +</div> + +<h3 id="Definire_la_struttura_e_la_semantica_HTML">Definire la struttura e la semantica HTML</h3> + +<p>Ora che le funzionalità basi del nostro widget sono state deficse, e' tempo di cominciare a costruire il nostro widget. Il primo passo è di definire la struttura HTML . Questo è ciò che dobbiamo ricostruire {{HTMLElement("select")}}:</p> + +<pre class="brush: html"><!-- Questo è il nostro container + principale per il nostro widget. + l'attributo tabindex permette + all'utente di concentrarsi sul widget. + Vedremo dopo cos'è meglio + utilizzare con javascript. --> + +<div class="select" tabindex="0"> + + <!-- Questo container verrà usato per stampare il valore corrente del widget --> + <span class="value">Cherry</span> + + <!-- Questo container conterrà tutte le opzioni disponibili per il nostro widget. + dato che sarà una lista, utilizzare l'opzione ul è valido. --> + <ul class="optList"> + <!-- Ogni opzione contiene solo il valore da visualizzare, vedremo dopo come + manipolare il reale valore che vogliamo inviare col form --> + <li class="option">Cherry</li> + <li class="option">Lemon</li> + <li class="option">Banana</li> + <li class="option">Strawberry</li> + <li class="option">Apple</li> + </ul> + +</div></pre> + +<p>Nota l'uso del nome delle classi; questi identificano ciascuna parte rilevante indipendentemente dagli effettivi elementi HTML sottostanti utilizzati. Questo è importante per essere sicuri che non legheremo il nostro CSS e JavaScript ad una forte struttura HTML, in modo da poter apportare modifiche all'implementazione in un secondo momento senza rompere il codice che utilizza il widget. Per esempio se desideri implementare l'equivalente dell'elemento {{HTMLElement("optgroup")}}.</p> + +<h3 id="Creare_l'aspetto_grafico_utilizzando_i_CSS">Creare l'aspetto grafico utilizzando i CSS</h3> + +<p>Ora che abbiamo una struttura HTML possiamo cominciare a disegnare il nostro widget. L'intero punto di costruzione di questo widget personalizzato è di essere in grado di modellare questo widget esattamente come vogliamo. Al fine di ciò, divideremo i nostri CSS in due parti: la prima parte sarà necessaria per avere un widget simile a {{HTMLElement("select")}} ,la seconda parte consisterà nella parte grafica in modo che appaia come noi vogliamo.</p> + +<h4 id="Stili_richiesti">Stili richiesti</h4> + +<p>Gli stili richiesti sono quelli necessari per gestire i tre stati del nostro widget.</p> + +<pre class="brush: css">.select { + /* Questo creerà un contesto di posizionamento per l'elenco di opzioni */ + position: relative; + + /*Questo renderà il nostro widget parte del flusso di testo e allo stesso tempo considerevole */ + display : inline-block; +}</pre> + +<p>Abbiamo bisogno di una classe extra "active" per definire il look del nostro widget quando è nello stato di attivazione. Poichè il nostro widget è selezionabile,dobbiamo raddoppiare questo stile personale con la pseudo-classe {{cssxref(":focus")}} In modo da essere sicuri che abbiano lo stesso comportamento.</p> + +<pre class="brush: css">.select.active, +.select:focus { + outline: none; + + /* Questo box-shadow non è richiesto al corretto funzionamento , + tuttavia è importante per essere sicuro che lo stato di attivazione + sia visibile e che lo utilizziamo come valore di defaul, + sentiti libero di modificarlo. */ + box-shadow: 0 0 3px 1px #227755; +}</pre> + +<p>Ora manipoliamo la lista delle opzioni:</p> + +<pre class="brush: css">/* il selettore .select è zucchero sintattico ( traduzione letterale, + concettualmente vuol dire " rendere del codice più dolce, più umano " + per essere sicuri che le classi che definiamo siano quelli all'interno del nostro widget. + */ + +.select .optList { + /* Ciò assicurerà che il nostro elenco di opzioni sia visualizzato sotto il valore + e fuori dal flusso HTML */ + position : absolute; + top : 100%; + left : 0; +}</pre> + +<p>Abbiamo bisogno di una classe extra per manipolare la lista quando le opzioni sono nascoste. Questo è necessario per gestire le differenze tra lo stato attivo e lo stato aperto che non corrispondono esattamente.</p> + +<pre class="brush: css">.select .optList.hidden { + /* Questo è un modo semplice per nascondere la lista in modo accessibile, + parleremo di più sull'accessibilità alla fine */ + max-height: 0; + visibility: hidden; +}</pre> + +<h4 id="Abbellimento">Abbellimento</h4> + +<p>Ora che abbiamo le funzionalità base, possiamo cominciare a divertirci. Quello seguente è solo un esempio di ciò che è possibile, e corrisponderà allo screenshot all'inizio di questo articolo. Dovresti sentirti libero di sperimentare e vedere cosa accade.</p> + +<pre class="brush: css">.select { + /* Tutte le taglie saranno espresse con il valore em per motivi di accessibilità + (per assicurarsi che il widget rimanga ridimensionabile se l'utente usa il + zoom del browser in modalità solo testo). I calcoli sono fatti + assumendo 1em == 16px quale è il valore predefinito nella maggior parte dei browser. + Se ti perdi la conversione di px in em, prova http://riddle.pl/emcalc/ * / + font-size : 0.625em; + font-family : Verdana, Arial, sans-serif; + + -moz-box-sizing : border-box; + box-sizing : border-box; + + /* Abbiamo bisogno di spazio extra per la freccia in giù che aggiungeremo + */ + padding : .1em 2.5em .2em .5em; /* 1px 25px 2px 5px */ + width : 10em; /* 100px */ + + border : .2em solid #000; /* 2px */ + border-radius : .4em; /* 4px */ + box-shadow : 0 .1em .2em rgba(0,0,0,.45); /* 0 1px 2px */ + + /* La prima dichiarazione serve per i browser che non supportano i gradienti lineari. + La seconda dichiarazione è perché i browser basati su WebKit non hanno ancora una definizione prefissata. + Se vuoi supportare i browser legacy prova http://www.colorzilla.com/gradient-editor/ */ + background : #F0F0F0; + background : -webkit-linear-gradient(90deg, #E3E3E3, #fcfcfc 50%, #f0f0f0); + background : linear-gradient(0deg, #E3E3E3, #fcfcfc 50%, #f0f0f0); +} + +.select .value { + /* poichè i valori possono essere più larghi del nostro widget, dobbiamo essere sicuri + che il widget cambierà dimensione */ + display : inline-block; + width : 100%; + overflow : hidden; + + vertical-align: top; + + /* E se il contenuto va in overflow, è bello avere un bell'elisse . */ + white-space : nowrap; + text-overflow: ellipsis; +}</pre> + +<p>Non abbiamo bisogno di altri elementi per disegnare la freccia in basso; useremo invece lo pseudo-elemento {{cssxref(":after")}}. Comunque potrebbe anche essere implementato usando una semplice immagine di background.</p> + +<pre class="brush: css">.select:after { + content : "▼"; /* utilizziamo il carattere unicode U+25BC; vedi http://www.utf8-chartable.de */ + position: absolute; + z-index : 1; /* importante per la posizione della freccia in modo da evitare + sovrapposizionamenti */ + top : 0; + right : 0; + + -moz-box-sizing : border-box; + box-sizing : border-box; + + height : 100%; + width : 2em; /* 20px */ + padding-top : .1em; /* 1px */ + + border-left : .2em solid #000; /* 2px */ + border-radius: 0 .1em .1em 0; /* 0 1px 1px 0 */ + + background-color : #000; + color : #FFF; + text-align : center; +}</pre> + +<p>ora cominciamo il design della lista delle opzioni:</p> + +<pre class="brush: css">.select .optList { + z-index : 2; /* Dichiariamo esplicitamente che la lista delle opzioni si sovraporrà + alla freccia */ + + /*Questo resetterà lo stile di default degli elementi <ul> */ + list-style: none; + margin : 0; + padding: 0; + + -moz-box-sizing : border-box; + box-sizing : border-box; + + /* Ciò assicurerà che anche se i valori sono inferiori al widget, + l'elenco delle opzioni sarà grande quanto il widget stesso */ + min-width : 100%; + + /*Nel caso in cui l'elenco sia troppo lungo, il suo contenuto si sovrapporrà verticalmente + (che aggiungerà automaticamente una barra di scorrimento verticale) ma mai in orizzontale + (poiché non abbiamo impostato una larghezza, la lista regolerà automaticamente la sua larghezza. + Se non è possibile, il contenuto verrà troncato) */ + max-height: 10em; /* 100px */ + overflow-y: auto; + overflow-x: hidden; + + border: .2em solid #000; /* 2px */ + border-top-width : .1em; /* 1px */ + border-radius: 0 0 .4em .4em; /* 0 0 4px 4px */ + + box-shadow: 0 .2em .4em rgba(0,0,0,.4); /* 0 2px 4px */ + background: #f0f0f0; +}</pre> + +<p>Per le opzioni abbiamo bisogno di aggiungere la classe <code>highlight</code> in modo da identificare il valore che l'user selezionerà (o ha selezionato).</p> + +<pre class="brush: css">.select .option { + padding: .2em .3em; /* 2px 3px */ +} + +.select .highlight { + background: #000; + color: #FFFFFF; +}</pre> + +<p>ecco i risultati dei nostri 3 stati:</p> + +<table> + <thead> + <tr> + <th scope="col" style="text-align: center;">Basic state</th> + <th scope="col" style="text-align: center;">Active state</th> + <th scope="col" style="text-align: center;">Open state</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{EmbedLiveSample("Basic_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}</td> + <td>{{EmbedLiveSample("Active_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}</td> + <td>{{EmbedLiveSample("Open_state",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}</td> + </tr> + <tr> + <td colspan="3" style="text-align: center;"><a href="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets/Example_1" title="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets/Example_1">Check out the source code</a></td> + </tr> + </tbody> +</table> + +<h2 id="Porta_in_vita_il_tuo_widget_con_javascript">Porta in vita il tuo widget con javascript</h2> + +<p>Ora che il nostro designe e la nostra struttura sono pronti possiamo scrivere il codice JavaScript che farà effettivamente lavorare il widget.</p> + +<div class="warning"> +<p><strong>Pericolo:</strong> Il seguente codice è educativo e non dovrebbe essere usato così com'è. Tra le tante cose, come vedremo, non è a prova di futuro e non funzionerà sui browser legacy. Ha anche parti ridondanti che dovrebbero essere ottimizzate nel codice di produzione.</p> +</div> + +<div class="note"> +<p><strong>Nota:</strong> Creare widget riutilizzabili è qualcosa che può essere un po 'complicato. La bozza del componente Web W3C è una delle risposte a questo specifico problema. Il progetto X-Tag è un'implementazione di test di questa specifica; ti invitiamo a dare un'occhiata a questo.</p> +</div> + +<h3 id="Perchè_non_funziona">Perchè non funziona?</h3> + +<p>Prima di cominciare, è importante ricordare qualcosa di fondamentale a proposito di JavaScript: dentro un browser, <strong>è una tecnologia inaffidabile</strong>. Quando stai costruendo widget personalizzati, dovrai fare affidamento su javascript perchè è un filo necessario per legare tutto insieme. Tuttavia, ci sono molti casi in cui JavaScript non può essere eseguito nel browser:</p> + +<ul> + <li>L'user ha bloccato l'utilizzo di javascript: Questo è il caso più insolito di sempre; veramente poche persone bloccano l'utilizzo di JavaScript oggigiorno.</li> + <li>Lo script non si carica. Questo è uno dei casi più comuni, specialmente nel mondo mobile.</li> + <li>Lo script è buggato. Dovresti sempre considerare questa possibilità.</li> + <li>Lo script entra in conflitto con uno script di terze parti. Questo può accadere con gli script di tracciamento o qualsiasi bookmarklet che l'utente utilizza.</li> + <li>Lo script è in conflitto con, o è affetto da, un'estensione del browser (come Firefox's <a href="https://addons.mozilla.org/fr/firefox/addon/noscript/" rel="external" title="https://addons.mozilla.org/fr/firefox/addon/noscript/">NoScript</a> extension o Chrome's <a href="https://chrome.google.com/webstore/detail/notscripts/odjhifogjcknibkahlpidmdajjpkkcfn" rel="external" title="https://chrome.google.com/webstore/detail/notscripts/odjhifogjcknibkahlpidmdajjpkkcfn">NotScripts</a> ).</li> + <li>L'user sta utilizzando un browser Legacy, e una delle feature che richiedi non è supportata. Ciò si verifica frequentemente quando si utilizzano API all'avanguardia.</li> +</ul> + +<p>Per via di questi rischi, è molto importante considerare seriamente cosa accadrà se JavaScript non funziona. Trattare dettagliatamente questo problema è fuori dallo scopo di questo articolo perché è strettamente legato al modo in cui si desidera rendere generico e riutilizzabile lo script, ma nel nostro esempio considereremo le basi di ciò.</p> + +<p>Nel nostro esempio, se il nostro codice JavaScript non è in esecuzione, ricorreremo alla visualizzazione di un elemento {{HTMLElement("select")}}. Per raggiungere questo abbiamo bisogno di due cose.</p> + +<p>Per prima cosa, dobbiamo aggiungere un normale elemento {{HTMLElement ("select")}} prima di ogni utilizzo del nostro widget personalizzato. Questo è in realtà richiesto anche per poter inviare dati dal nostro widget personalizzato insieme al resto dei dati del nostro modulo;diremo di più a proposito più tardi.</p> + +<pre class="brush: html"><body class="no-widget"> + <form> + <select name="myFruit"> + <option>Cherry</option> + <option>Lemon</option> + <option>Banana</option> + <option>Strawberry</option> + <option>Apple</option> + </select> + + <div class="select"> + <span class="value">Cherry</span> + <ul class="optList hidden"> + <li class="option">Cherry</li> + <li class="option">Lemon</li> + <li class="option">Banana</li> + <li class="option">Strawberry</li> + <li class="option">Apple</li> + </ul> + </div> + </form> + +</body></pre> + +<p>Secondo, abbiamo bisogno di due nuove classi per nascondere l'elemento non necessario (cioè, l'elemento "reale" {{HTMLElement ("select")}} se il nostro script non è in esecuzione o il widget personalizzato è in esecuzione) . Nota che per impostazione predefinita, il nostro codice HTML nasconde il nostro widget personalizzato.</p> + +<pre class="brush: css">.widget select, +.no-widget .select { + /*Questo selettore css afferma: + - o abbiamo impostato la classe del corpo su "widget", + quindi nascondiamo l'effettivo elemento {{HTMLElement ("select")}} + - o non abbiamo cambiato la classe del corpo, quindi la classe del corpo + è ancora "no-widget", + quindi gli elementi di classe "select" devono essere nascosti */ + position : absolute; + left : -5000em; + height : 0; + overflow : hidden; +}</pre> + +<p>Ora abbiamo solo bisogno di un interruttore JavaScript per determinare se lo script è in esecuzione o meno. Questa opzione è molto semplice: se al momento del caricamento della pagina il nostro script è in esecuzione, rimuoverà la classe no-widget e aggiungerà la classe widget, scambiando così la visibilità dell'elemento {{HTMLElement ("select")}} e del widget personalizzato.</p> + +<pre class="brush: js">window.addEventListener("load", function () { + document.body.classList.remove("no-widget"); + document.body.classList.add("widget"); +});</pre> + +<table> + <thead> + <tr> + <th scope="col" style="text-align: center;">Without JS</th> + <th scope="col" style="text-align: center;">With JS</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{EmbedLiveSample("No_JS",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}</td> + <td>{{EmbedLiveSample("JS",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}</td> + </tr> + <tr> + <td colspan="2" style="text-align: center;"><a href="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets/Example_2" title="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets/Example_2">Check out the source code</a></td> + </tr> + </tbody> +</table> + +<div class="note"> +<p><strong>Nota:</strong> Se vuoi veramente rendere il tuo codice generico e riutilizzabile, invece di fare un cambio di classe è meglio aggiungere semplicemente la classe del widget per nascondere gli elementi {{HTMLElement ("select")}} e aggiungere dinamicamente l'albero DOM che rappresenta il widget personalizzato dopo ogni {{HTMLElement ("select")}} elemento nella pagina.</p> +</div> + +<h3 id="Rendere_il_lavoro_più_facile">Rendere il lavoro più facile</h3> + +<p>Nel codice che stiamo per costruire, useremo l'API DOM standard per fare tutto il lavoro di cui abbiamo bisogno. Tuttavia, sebbene il supporto dell'API DOM sia diventato molto meglio nei browser, ci sono sempre problemi con i browser legacy (specialmente con il buon vecchio Internet Explorer).</p> + +<p>Se vuoi evitare problemi con i browser legacy, ci sono due modi per farlo: usando un framework dedicato come jQuery, $ dom, prototype, Dojo, YUI, o simili, o facendo il polyfilling della funzione mancante che vuoi usare ( che può essere fatto facilmente attraverso il caricamento condizionale, ad esempio con la libreria yepnope).</p> + +<p>Le funzionalità che intendiamo utilizzare sono le seguenti (ordinate dal più rischioso al più sicuro):</p> + +<ol> + <li>{{domxref("element.classList","classList")}}</li> + <li>{{domxref("EventTarget.addEventListener","addEventListener")}}</li> + <li><code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach" title="/en-US/docs/JavaScript/Reference/Global_Objects/Array/forEach">forEach</a></code> (This is not DOM but modern JavaScript)</li> + <li>{{domxref("element.querySelector","querySelector")}} and {{domxref("element.querySelectorAll","querySelectorAll")}}</li> +</ol> + +<p>Oltre alla disponibilità di tali funzionalità specifiche, rimane ancora un problema prima dell'avvio. L'oggetto restituito dalla funzione {{domxref ("element.querySelectorAll", "querySelectorAll ()")}} è un {{domxref ("NodeList")}} piuttosto che una matrice. Questo è importante perché gli oggetti Array supportano la funzione forEach, ma {{domxref ("NodeList")}} no. Poiché {{domxref ("NodeList")}} sembra davvero un array e poiché forEach è così comodo da usare, possiamo facilmente aggiungere il supporto di forEach a {{domxref ("NodeList")}} per rendere la nostra vita più facile, così:</p> + +<pre class="brush: js">NodeList.prototype.forEach = function (callback) { + Array.prototype.forEach.call(this, callback); +}</pre> + +<p>We weren't kidding when we said it's easy to do.</p> + +<h3 id="Creazione_di_eventi_Callback">Creazione di eventi Callback</h3> + +<p>Il terreno è pronto, ora possiamo iniziare a definire tutte le funzioni che verranno utilizzate ogni volta che l'utente interagisce con il nostro widget.</p> + +<pre class="brush: js">// Questa funzione verrà utilizzata ogni volta che si desidera disattivare un widget personalizzato +// Richiede un parametro +// seleziona: il nodo DOM con la classe `select` da disattivare +function deactivateSelect(select) { + + // Se il widget non è attivo non c'è nulla da fare + if (!select.classList.contains('active')) return; + + // Abbiamo bisogno di ottenere l'elenco delle opzioni per il widget personalizzato + var optList = select.querySelector('.optList'); + + // Chiudiamo la lista delle opzioni + optList.classList.add('hidden'); + + // e disattiviamo il custom widget + select.classList.remove('active'); +} + +// questa funzione verrà utilizzata ogni volta che l'user(dis)attiverà il widget +// prende due parametri: +// select : il nodo del DOM con le classi 'select' da attivare +// selectList :la lista di tutti i nodi dom con la la classe 'select' + +function activeSelect(select, selectList) { + + // Se il widget è già attivo non c'è niente da fare + if (select.classList.contains('active')) return; + + // Dobbiamo disattivare lo stato attivo su tutti i widget personalizzati + // Perché la funzione deactivateSelect soddisfa tutti i requisiti di + // per ogni funzione di callback, la usiamo direttamente senza usare un intermediario + // funzione anonima. + selectList.forEach(deactivateSelect); + + // E attiviamo lo stato attivo per questo specifico widget + select.classList.add('active'); +} + +// Questa funzione verrà utilizzata ogni volta che l'utente desidera aprire / chiudere l'elenco di opzioni +// Richiede un parametro: +// seleziona: il nodo DOM con l'elenco da attivare +function toggleOptList(select) { + + // L'elenco è tenuto dal widget + var optList = select.querySelector('.optList'); + + // Modifichiamo la classe dell'elenco per mostrarlo / nasconderlo + optList.classList.toggle('hidden'); +} + +// Questa funzione verrà utilizzata ogni volta che sarà necessario evidenziare un'opzione +// Ci vogliono due parametri: +// seleziona: il nodo DOM con la classe `select` contenente l'opzione da evidenziare +// opzione: il nodo DOM con la classe `option` da evidenziare +function highlightOption(select, option) { + + // Otteniamo l'elenco di tutte le opzioni disponibili per il nostro elemento di selezione personalizza + var optionList = select.querySelectorAll('.option'); + + // Rimuoviamo l'evidenziazione da tutte le opzioni + optionList.forEach(function (other) { + other.classList.remove('highlight'); + }); + + // Evidenziamo l'opzione giusta + option.classList.add('highlight'); +};</pre> + +<p> </p> + +<p>Questo è tutto ciò che serve per gestire i vari stati del widget personalizzato.</p> + +<p>Successivamente, associamo queste funzioni agli eventi appropriati:</p> + +<p> </p> + +<pre class="brush: js">// Gestiamo il binding di eventi quando il documento è caricato. +window.addEventListener('load', function () { + var selectList = document.querySelectorAll('.select'); + + // Each custom widget needs to be initialized + selectList.forEach(function (select) { + + // Ogni widget personalizzato deve essere inizializzato + var optionList = select.querySelectorAll('.option'); + + // Ogni volta che un utente passa il mouse su un'opzione, evidenziamo l'opzione data + optionList.forEach(function (option) { + option.addEventListener('mouseover', function () { + // Nota: le variabili `select` e` option` sono le chiusure + // disponibile nell'ambito della nostra chiamata di funzione. + highlightOption(select, option); + }); + }); + + // Ogni volta che l'utente fa clic su un elemento di selezione personalizzato + select.addEventListener('click', function (event) { + // Nota: la variabile `select` è una chiusura + // disponibile nell'ambito della nostra chiamata di funzione. + + // Accendiamo la visibilità dell'elenco di opzioni + toggleOptList(select); + }); + + // Nel caso in cui il widget ottenga lo stato attivo + // Il widget ottiene l'attenzione ogni volta che l'utente fa clic su di esso o ogni volta + // usano la chiave di tabulazione per accedere al widget + select.addEventListener('focus', function (event) { + // Nota: le variabili `select` e` selectList` sono le chiusure + // disponibile nell'ambito della nostra chiamata di funzione. + + // Attiviamo il widget + activeSelect(select, selectList); + }); + + // Nel caso in cui il widget lasci il focus + select.addEventListener('blur', function (event) { + // Nota: la variabile `select` è una chiusura + // disponibile nell'ambito della nostra chiamata di funzione. + + // Disattiamo il widget + deactivateSelect(select); + }); + }); +});</pre> + +<p>A quel punto, il nostro widget cambierà stato in base al nostro progetto, ma il suo valore non viene ancora aggiornato. Lo gestiremo dopo.</p> + +<table> + <thead> + <tr> + <th scope="col" style="text-align: center;">Live example</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_3")}}</td> + </tr> + <tr> + <td style="text-align: center;"><a href="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets/Example_3" title="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets/Example_3">Check out the source code</a></td> + </tr> + </tbody> +</table> + +<h3 id="Gestire_il_valore_del_Widget">Gestire il valore del Widget</h3> + +<p> </p> + +<p>Ora che il nostro widget funziona, dobbiamo aggiungere del codice per aggiornarne il valore in base all'input dell'utente e rendere possibile l'invio del valore insieme ai dati del modulo.</p> + +<p>Il modo più semplice per farlo è usare un widget nativo sotto il cofano. Tale widget terrà traccia del valore con tutti i controlli integrati forniti dal browser e il valore verrà inviato normalmente al momento della presentazione di un modulo. Non ha senso reinventare la ruota quando possiamo fare tutto questo per noi.</p> + +<p>Come visto in precedenza, utilizziamo già un widget di selezione nativo come fallback per motivi di accessibilità; possiamo semplicemente sincronizzare il suo valore con quello del nostro widget personalizzato:</p> + +<p> </p> + +<pre class="brush: js">// Questa funzione aggiorna il valore visualizzato e lo sincronizza con il widget nativo. +// Ci vogliono due parametri: +// seleziona: il nodo DOM con la classe `select` contenente il valore da aggiornare +// indice: l'indice del valore da selezionare +function updateValue(select, index) { + // Abbiamo bisogno di ottenere il widget nativo per il widget personalizzato specificato + // Nel nostro esempio, quel widget nativo è un fratello del widget personalizzato + var nativeWidget = select.previousElementSibling; + + // Abbiamo anche bisogno di ottenere il valore segnaposto del nostro widget personalizzato + var value = select.querySelector('.value'); + + // E abbiamo bisogno dell'intero elenco di opzioni + var optionList = select.querySelectorAll('.option'); + + // Impostiamo l'indice selezionato sull'indice di nostra scelta + nativeWidget.selectedIndex = index; + + // Aggiorniamo il valore placeholder di conseguenza + value.innerHTML = optionList[index].innerHTML; + + // E evidenziamo l'opzione corrispondente del nostro widget personalizzato + highlightOption(select, optionList[index]); +}; + +// Questa funzione restituisce l'indice selezionato corrente nel widget nativo +// Richiede un parametro: +// seleziona: il nodo DOM con la classe `select` relativa al widget nativo +function getIndex(select) { + // È necessario accedere al widget nativo per il widget personalizzato specificato + // Nel nostro esempio, quel widget nativo è un fratello del widget personalizzato + var nativeWidget = select.previousElementSibling; + + return nativeWidget.selectedIndex; +};</pre> + +<p>Con queste due funzioni, possiamo associare i widget nativi a quelli personalizzati:</p> + +<pre class="brush: js">// Gestiamo il binding di eventi quando il documento è caricato. +window.addEventListener('load', function () { + var selectList = document.querySelectorAll('.select'); + + // Ogni widget personalizzato deve essere inizializzato + selectList.forEach(function (select) { + var optionList = select.querySelectorAll('.option'), + selectedIndex = getIndex(select); + + // Rendiamo focalizzabile il nostro widget personalizzato + select.tabIndex = 0; + +// Facciamo in modo che il widget nativo non sia più focalizzabile + select.previousElementSibling.tabIndex = -1; + + // Ci assicuriamo che il valore selezionato di default sia visualizzato correttamente + updateValue(select, selectedIndex); + + // Ogni volta che un utente fa clic su un'opzione, aggiorniamo di conseguenza il valore + optionList.forEach(function (option, index) { + option.addEventListener('click', function (event) { + updateValue(select, index); + }); + }); + + // Ogni volta che un utente usa la propria tastiera su un widget focalizzato, aggiorniamo di conseguenza il valore + select.addEventListener('keyup', function (event) { + var length = optionList.length, + index = getIndex(select); + + // Quando l'utente preme la freccia giù, passiamo all'opzione successiva + if (event.keyCode === 40 && index < length - 1) { index++; } + +// Quando l'utente preme la freccia su, passiamo all'opzione precedente + if (event.keyCode === 38 && index > 0) { index--; } + + updateValue(select, index); + }); + }); +});</pre> + +<p> </p> + +<p>Nel codice sopra, vale la pena notare l'uso della proprietà tabIndex. L'utilizzo di questa proprietà è necessario per garantire che il widget nativo non acquisisca mai l'attenzione e per assicurarsi che il nostro widget personalizzato ottenga lo stato attivo quando l'utente utilizza la sua tastiera o il suo mouse.</p> + +<p>Con quello, abbiamo finito! Ecco il risultato:</p> + +<p> </p> + +<table> + <thead> + <tr> + <th scope="col" style="text-align: center;">Live example</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_4")}}</td> + </tr> + <tr> + <td style="text-align: center;"><a href="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets/Example_4" title="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets/Example_4">Check out the source code</a></td> + </tr> + </tbody> +</table> + +<p>Ma aspetta un secondo, abbiamo davvero finito?</p> + +<h2 id="Renderlo_accessibile">Renderlo accessibile</h2> + +<p> </p> + +<p>Abbiamo costruito qualcosa che funziona e sebbene siamo lontani da una casella di selezione completa, funziona bene. Ma quello che abbiamo fatto non è altro che il violino con il DOM. Non ha una vera semantica e, anche se sembra una casella di selezione, dal punto di vista del browser non ne è uno, quindi le tecnologie assistive non saranno in grado di capire che è una casella di selezione. In breve, questa nuova casella di selezione non è accessibile!</p> + +<p>Fortunatamente, esiste una soluzione e si chiama ARIA. ARIA è l'acronimo di "Accessible Rich Internet Application" ed è una specifica W3C specificamente progettata per ciò che stiamo facendo qui: rendere accessibili le applicazioni web e i widget personalizzati. È fondamentalmente un insieme di attributi che estendono l'HTML in modo da poter meglio descrivere ruoli, stati e proprietà come se l'elemento che abbiamo appena escogitato fosse l'elemento nativo per cui tentava di passare. L'utilizzo di questi attributi è estremamente semplice, quindi facciamolo.</p> + +<p> </p> + +<h3 id="L'attributo_'role'">L'attributo 'role'</h3> + +<p> </p> + +<p>L'attributo chiave utilizzato da ARIA è l'attributo 'role'. L'attributo 'role' accetta un valore che definisce per cosa viene usato un elemento. Ogni 'role' definisce i propri requisiti e comportamenti. Nel nostro esempio, useremo 'role listbox'. È un "ruolo composito", ovvero gli elementi con quel ruolo si aspettano di avere figli, ciascuno con un ruolo specifico (in questo caso, almeno un bambino con il ruolo di opzione).</p> + +<p>Vale anche la pena notare che ARIA definisce i ruoli che vengono applicati di default al markup HTML standard. Ad esempio, l'elemento {{HTMLElement ("table")}} corrisponde alla griglia del ruolo e l'elemento {{HTMLElement ("ul")}} corrisponde all'elenco dei ruoli. Poiché utilizziamo un elemento {{HTMLElement ("ul")}}, vogliamo assicurarci che il ruolo listbox del nostro widget sostituisca il ruolo di lista dell'elemento {{HTMLElement ("ul")}}. A tal fine, useremo la presentazione del ruolo. Questo ruolo è stato progettato per farci indicare che un elemento non ha un significato speciale e viene utilizzato esclusivamente per presentare informazioni. Lo applicheremo al nostro elemento {{HTMLElement ("ul")}}.</p> + +<p>Per supportare il ruolo listbox, dobbiamo solo aggiornare il nostro codice HTML in questo modo:</p> + +<p> </p> + +<pre class="brush: html"><! - Aggiungiamo l'attributo role = "listbox" al nostro elemento principale -><div class="select" role="listbox"> + <span class="value">Cherry</span> + <! - Aggiungiamo anche il role = "presentation" all'elemento ul -> + <ul class="optList" role="presentation"> + <! - E aggiungiamo l'attributo role = "option" a tutti gli elementi li -> + <li role="option" class="option">Cherry</li> + <li role="option" class="option">Lemon</li> + <li role="option" class="option">Banana</li> + <li role="option" class="option">Strawberry</li> + <li role="option" class="option">Apple</li> + </ul> +</div></pre> + +<div class="note"> +<p><strong>Nota:</strong> Includere sia l'attributo role sia un attributo class è necessario solo se si desidera supportare i browser legacy che non supportano i selettori dell'attributo CSS. <a href="/en-US/docs/CSS/Attribute_selectors" title="/en-US/docs/CSS/Attribute_selectors">CSS attribute selectors</a>.</p> +</div> + +<h3 id="L'attributo_aria-selected">L'attributo <code>aria-selected</code> </h3> + +<p>Usare l'attributo <a href="/en-US/docs/Accessibility/ARIA/ARIA_Techniques" title="/en-US/docs/Accessibility/ARIA/ARIA_Techniques"><code>role</code></a> non è abbastanza. <a href="/en-US/docs/Accessibility/ARIA" title="/en-US/docs/Accessibility/ARIA">ARIA</a> fornisce anche molti stati e attributi di proprietà. Più e meglio li usi, più il tuo widget sarà compreso dalle tecnologie assistive. Nel nostro caso, limiteremo il nostro utilizzo a un attributo: <code>aria-selected</code>.</p> + +<p>l'attributo <code>aria-selected</code> è usato per contrassegnare quale opzione è attualmente selezionata; questo consente alle tecnologie assistive di informare l'utente su quale sia la selezione corrente. Lo useremo dinamicamente con JavaScript per contrassegnare l'opzione selezionata ogni volta che l'utente ne sceglie uno. A tal fine, abbiamo bisogno di rivedere la nostra funzione <code>updateValue()</code>:</p> + +<pre class="brush: js">function updateValue(select, index) { + var nativeWidget = select.previousElementSibling; + var value = select.querySelector('.value'); + var optionList = select.querySelectorAll('.option'); + + // Ci assicuriamo che tutte le opzioni non siano selezionate + optionList.forEach(function (other) { + other.setAttribute('aria-selected', 'false'); + }); + + // Ci assicuriamo che l'opzione scelta sia selezionata + optionList[index].setAttribute('aria-selected', 'true'); + + nativeWidget.selectedIndex = index; + value.innerHTML = optionList[index].innerHTML; + highlightOption(select, optionList[index]); +};</pre> + +<p>Ecco il risultato finale di tutti questi cambiamenti (otterrai una sensazione migliore provandola con una tecnologia di assistenza come <a href="http://www.nvda-project.org/" rel="external" title="http://www.nvda-project.org/">NVDA</a> o <a href="http://www.apple.com/accessibility/voiceover/" rel="external" title="http://www.apple.com/accessibility/voiceover/">VoiceOver</a>):</p> + +<table> + <thead> + <tr> + <th scope="col" style="text-align: center;">Live example</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{EmbedLiveSample("Change_states",120,130, "", "HTML/Forms/How_to_build_custom_form_widgets/Example_5")}}</td> + </tr> + <tr> + <td style="text-align: center;"><a href="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets/Example_5" title="/en-US/docs/HTML/Forms/How_to_build_custom_form_widgets/Example_2">Check out the final source code</a></td> + </tr> + </tbody> +</table> + +<h2 id="Conclusioni">Conclusioni</h2> + +<p> </p> + +<p>Abbiamo visto tutti i fondamenti della creazione di un widget di modulo personalizzato, ma come puoi vedere non è banale da fare, e spesso è meglio e più facile affidarsi a librerie di terze parti invece di codificarle da zero da soli (a meno che, ovviamente, il tuo obiettivo è costruire una tale biblioteca).</p> + +<p>Ecco alcune librerie da prendere in considerazione prima di codificare le tue:</p> + +<p> </p> + +<ul> + <li><a href="http://jqueryui.com/" rel="external" title="http://jqueryui.com/">jQuery UI</a></li> + <li><a href="https://github.com/marghoobsuleman/ms-Dropdown" rel="external" title="https://github.com/marghoobsuleman/ms-Dropdown">msDropDown</a></li> + <li><a href="http://www.emblematiq.com/lab/niceforms/" rel="external" title="http://www.emblematiq.com/lab/niceforms/">Nice Forms</a></li> + <li><a href="https://www.google.fr/search?q=HTML+custom+form+controls&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:fr:official&client=firefox-a" rel="external" title="https://www.google.fr/search?q=HTML+custom+form+controls&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:fr:official&client=firefox-a">And many more…</a></li> +</ul> + +<p>Se vuoi andare avanti, il codice in questo esempio necessita di qualche miglioramento prima che diventi generico e riutilizzabile. Questo è un esercizio che puoi provare ad esibirti. Due suggerimenti per aiutarti in questo: il primo argomento per tutte le nostre funzioni è lo stesso, il che significa che quelle funzioni necessitano dello stesso contesto. Costruire un oggetto per condividere quel contesto sarebbe saggio. Inoltre, è necessario renderlo a prova di funzionalità; cioè, deve essere in grado di funzionare meglio con una varietà di browser la cui compatibilità con gli standard Web utilizzati varia. Divertiti!</p> + +<p>{{PreviousMenuNext("Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms")}}</p> + +<p> </p> + +<h2 id="In_questo_modulo">In questo modulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/HTML/Forms/Your_first_HTML_form">Your first HTML form</a></li> + <li><a href="/en-US/docs/Learn/HTML/Forms/How_to_structure_an_HTML_form">How to structure an HTML form</a></li> + <li><a href="/en-US/docs/Learn/HTML/Forms/The_native_form_widgets">The native form widgets</a></li> + <li><a href="/en-US/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data">Sending form data</a></li> + <li><a href="/en-US/docs/Learn/HTML/Forms/Form_validation">Form data validation</a></li> + <li><a href="/en-US/docs/Learn/HTML/Forms/How_to_build_custom_form_widgets">How to build custom form widgets</a></li> + <li><a href="/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript">Sending forms through JavaScript</a></li> + <li><a href="/en-US/docs/Learn/HTML/Forms/HTML_forms_in_legacy_browsers">HTML forms in legacy browsers</a></li> + <li><a href="/en-US/docs/Learn/HTML/Forms/Styling_HTML_forms">Styling HTML forms</a></li> + <li><a href="/en-US/docs/Learn/HTML/Forms/Advanced_styling_for_HTML_forms">Advanced styling for HTML forms</a></li> + <li><a href="/en-US/docs/Learn/HTML/Forms/Property_compatibility_table_for_form_widgets">Property compatibility table for form widgets</a></li> +</ul> + +<p> </p> diff --git a/files/it/learn/forms/index.html b/files/it/learn/forms/index.html new file mode 100644 index 0000000000..45c0d055dd --- /dev/null +++ b/files/it/learn/forms/index.html @@ -0,0 +1,85 @@ +--- +title: HTML forms +slug: Learn/HTML/Forms +tags: + - Beginner + - Featured + - Forms + - Guide + - HTML + - Landing + - Learn + - NeedsTranslation + - TopicStub + - Web +translation_of: Learn/Forms +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">Questo modulo fornisce una serie di articoli che ti aiuteranno ad apprendere le parti essenziali dei web forms. I web forms sono dei tool molto potenti per l'interazione con gli utenti - sono usati di solito per la raccolta di dati dagli utenti, o per permettere loro di controllare l'interfaccia utente. Tuttavia, per questioni storiche e tecniche non è sempre chiaro come sfruttare tutto il loro potenziale. Negli articoli che seguono, copriremo tutti gli aspetti essenziali dei web forms includendo anche la realizzazione della loro struttura HTML, dello stile dei controlli del form, della validazione dei dati del form, e dell'invio dei dati al server.</p> + +<h2 id="Prerequisiti">Prerequisiti</h2> + +<p>Prima di iniziare questo modulo, dovresti almeno affrontare la nostra parte di <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/HTML/Introduction_to_HTML">introduzione all'HTML</a> A questo punto dovresti trovare le {{anch("guide introduttive")}} facili da capire, e dovresti anche sapere utilizzare la guida base sui <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Forms/Basic_native_form_controls">Native form controls</a>.</p> + +<p>Sapere utilizzare perfettamente i forms, comunque, richede molto più della semplice conoscenza HTML - avrai anche bisogno di imparare alcune specifiche tecniche per dare uno stile ai controlli del form, ed è richiesta anche un pò di conoscenza di scripting per affronte cose come la validazione e la creazione di controlli del form personalizzati. Pertanto, prima di andare ad affrontare le altre sezioni presenti qui sotto, ti raccomandiamo di abbandonare questa pagina ed imparare prima un pò di CSS e Javascript.</p> + +<p>Il paragrafo qui sopra spiega bene il perchè abbiamo messo i web forms in una pagina a solo, piuttosto che mischiare un pò di questi contenuti nelle aree delle pagine che spiegano HTML, CSS e Javascript — gli elementi del form sono molto più complessi rispetto a tutti gli altri elementi HTML, e richiedono anche un connubio perfetto con le tecniche CSS e Javascript per ottenere il massimo da loro.</p> + +<div class="note"> +<p><strong>Nota bene</strong>: Se stai lavorando su un computer/tablet/altro dispositivo dove non sei in grado di creare i tuoi file, dovresti provare gli esempi di codice su un programma di coding online come <a href="http://jsbin.com/">JSBin</a> o <a href="https://glitch.com/">Glitch</a></p> +</div> + +<h2 id="Guida_introduttiva">Guida introduttiva</h2> + +<dl> + <dt><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Forms/Your_first_form">Il tuo primo form HTML</a></dt> + <dd>The first article in our series provides your very first experience of creating an HTML form, including designing a simple form, implementing it using the right HTML elements, adding some very simple styling via CSS, and how data is sent to a server.</dd> + <dt><a href="/en-US/docs/Learn/HTML/Forms/How_to_structure_an_HTML_form">How to structure an HTML form</a></dt> + <dd>With the basics out of the way, we now look in more detail at the elements used to provide structure and meaning to the different parts of a form.</dd> +</dl> + +<h2 id="What_form_widgets_are_available">What form widgets are available?</h2> + +<dl> + <dt><a href="/en-US/docs/Learn/HTML/Forms/The_native_form_widgets">The native form widgets</a></dt> + <dd>We now look at the functionality of the different form widgets in detail, looking at what options are available to collect different types of data.</dd> +</dl> + +<h2 id="Validating_and_submitting_form_data">Validating and submitting form data</h2> + +<dl> + <dt><a href="/en-US/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data">Sending form data</a></dt> + <dd>This article looks at what happens when a user submits a form — where does the data go, and how do we handle it when it gets there? We also look at some of the security concerns associated with sending form data.</dd> + <dt><a href="/en-US/docs/Learn/HTML/Forms/Form_validation">Form data validation</a></dt> + <dd>Sending data is not enough — we also need to make sure that the data users fill out in forms is in the correct format we need to process it successfully, and that it won't break our applications. We also want to help our users to fill out our forms correctly and don't get frustrated when trying to use our apps. Form validation helps us achieve these goals — this article tells you what you need to know.</dd> +</dl> + +<h2 id="Advanced_guides">Advanced guides</h2> + +<dl> + <dt><a href="/en-US/docs/Learn/HTML/Forms/How_to_build_custom_form_widgets">How to build custom form widgets</a></dt> + <dd>You'll come across some cases where the native form widgets just don't provide what you need, e.g. because of styling or functionality. In such cases, you may need to build your own form widget out of raw HTML. This article explains how you'd do this and the considerations you need to be aware of when doing so, with a practical case study.</dd> + <dt><a href="/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript">Sending forms through JavaScript</a></dt> + <dd>This article looks at ways to use a form to assemble an HTTP request and send it via custom JavaScript, rather than standard form submission. It also looks at why you'd want to do this, and the implications of doing so. (See also Using FormData objects.)</dd> + <dt><a href="/en-US/docs/Learn/HTML/Forms/HTML_forms_in_legacy_browsers">HTML forms in legacy browsers</a></dt> + <dd>Article covering feature detection, etc. This should be redirected to the cross browser testing module, as the same stuff is covered better there.</dd> +</dl> + +<h2 id="Form_styling_guides">Form styling guides</h2> + +<dl> + <dt><a href="/en-US/docs/Learn/HTML/Forms/Styling_HTML_forms">Styling HTML forms</a></dt> + <dd>This article provides an introduction to styling forms with CSS, including all the basics you might need to know for basic styling tasks.</dd> + <dt><a href="/en-US/docs/Learn/HTML/Forms/Advanced_styling_for_HTML_forms">Advanced styling for HTML forms</a></dt> + <dd>Here we look at some more advanced form styling techniques that need to be used when trying to deal with some of the more difficult-to-style elements.</dd> + <dt><a href="/en-US/docs/Learn/HTML/Forms/Property_compatibility_table_for_form_widgets">Property compatibility table for form widgets</a></dt> + <dd>This last article provides a handy reference allowing you to look up what CSS properties are compatible with what form elements.</dd> +</dl> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/HTML/Element#Forms">HTML forms element reference</a></li> + <li><a href="/en-US/docs/Web/HTML/Element/input">HTML <input> types reference</a></li> +</ul> |