Form HTML5 con datalist, range, date e file accessibili

by Anastasia P.
SHARE
Form HTML5 con datalist, range, date e file accessibili
© Guida-HTML5.it

Per raccogliere richieste di assistenza senza dipendere da librerie esterne, combina datalist, range, date e file con etichette associate e vincoli HTML nativi. Il browser può fornire suggerimenti, controlli e feedback immediati; JavaScript serve solo per aggiornare il valore mostrato e impostare la data minima. La validazione e la verifica degli allegati devono essere ripetute sul server.

Sintassi rapida (TL;DR):

<input type="text" name="categoria" list="categorie">
<datalist id="categorie"><option value="Accesso"></datalist>
<input type="range" name="urgenza" min="1" max="5" value="3">
<input type="date" name="data_contatto" required>
<input type="file" name="allegato" accept=".png,.jpg,.jpeg,.pdf">

Quando usare datalist, range, date e file in un form HTML5

Un form di assistenza deve raccogliere dati comprensibili e validabili senza imporre un’interfaccia complessa. I controlli nativi sono un buon punto di partenza: datalist propone valori frequenti lasciando libero l’inserimento; range rappresenta una scala numerica; date offre un controllo data; file apre il selettore di file del dispositivo.

Questi elementi non sostituiscono le regole di business. Un suggerimento di datalist non limita i valori, accept non certifica il contenuto di un file e gli attributi di validazione possono essere aggirati inviando una richiesta costruita manualmente. Per questo il browser migliora l’esperienza, mentre il server resta responsabile dell’accettazione e della sicurezza dei dati.

Implementazione completa di un form di assistenza in HTML5

L’esempio seguente è un frammento da inserire nel body di una pagina. Include un endpoint applicativo d’esempio, il caricamento multipart necessario per i file e JavaScript nativo separato dal markup tramite un blocco script. Il server deve implementare l’endpoint indicato.

<form action="/assistenza/invia" method="post" enctype="multipart/form-data">
  <fieldset>
    <legend>Nuova richiesta di assistenza</legend>

    <p>
      <label for="email">Indirizzo email</label>
      <input type="email" id="email" name="email"
        autocomplete="email" required>
    </p>

    <p>
      <label for="categoria">Categoria del problema</label>
      <input type="text" id="categoria" name="categoria"
        list="categorie-problema" autocomplete="off"
        placeholder="Per esempio: accesso" required>
      <datalist id="categorie-problema">
        <option value="Accesso all'account">
        <option value="Pagamento">
        <option value="Errore dell'applicazione">
        <option value="Connessione">
        <option value="Richiesta informazioni">
      </datalist>
    </p>

    <p>
      <label for="urgenza">
        Urgenza: <output id="valore-urgenza" for="urgenza">3</output> su 5
      </label>
      <input type="range" id="urgenza" name="urgenza"
        min="1" max="5" step="1" value="3"
        aria-describedby="descrizione-urgenza">
      <small id="descrizione-urgenza">
        1: poco urgente. 5: servizio completamente bloccato.
      </small>
    </p>

    <p>
      <label for="data-contatto">Data preferita per il contatto</label>
      <input type="date" id="data-contatto" name="data_contatto" required>
    </p>

    <p>
      <label for="allegato">Allegato diagnostico (facoltativo)</label>
      <input type="file" id="allegato" name="allegato"
        accept=".png,.jpg,.jpeg,.pdf"
        aria-describedby="aiuto-allegato">
      <small id="aiuto-allegato">
        PNG, JPG o PDF; massimo 5 MB. Il limite va verificato anche sul server.
      </small>
    </p>

    <p>
      <label for="descrizione">Descrizione del problema</label>
      <textarea id="descrizione" name="descrizione"
        rows="6" maxlength="1000" required></textarea>
    </p>

    <button type="submit">Invia richiesta</button>
  </fieldset>
</form>

<script>
  const urgenza = document.getElementById('urgenza');
  const valoreUrgenza = document.getElementById('valore-urgenza');
  const dataContatto = document.getElementById('data-contatto');

  urgenza.addEventListener('input', () => {
    valoreUrgenza.value = urgenza.value;
  });

  // Usa la data locale, non toISOString(), che converte in UTC.
  const oggi = new Date();
  const anno = oggi.getFullYear();
  const mese = String(oggi.getMonth() + 1).padStart(2, '0');
  const giorno = String(oggi.getDate()).padStart(2, '0');
  dataContatto.min = `${anno}-${mese}-${giorno}`;
</script>

Risultato nel Browser e Comportamento Accessibilità / DOM

Stato iniziale:
- Urgenza: 3 su 5
- Data minima selezionabile: data locale corrente (AAAA-MM-GG)
- Allegato: facoltativo; formati suggeriti PNG, JPG e PDF

Interazione:
- Spostando il cursore, il valore nell'elemento output si aggiorna.
- Se email, categoria, data o descrizione mancano, il browser blocca l'invio.
- Il selettore di file mostra i tipi suggeriti dal suo sistema operativo.

Invio valido:
POST /assistenza/invia
Content-Type: multipart/form-data (generato dal browser)
Campi: email, categoria, urgenza, data_contatto, allegato, descrizione

L’aspetto del selettore data e del controllo file dipende da browser e sistema operativo. L’output indica il comportamento del markup, non una risposta HTTP: il risultato effettivo dell’invio dipende dall’endpoint configurato e dalla sua implementazione.

Come funzionano datalist, range, date e file nel DOM

1. datalist: suggerimenti senza vincolo sui valori

L’attributo list dell’input deve corrispondere all’id del relativo datalist. L’utente può scegliere un’opzione oppure digitare un valore diverso; se il backend ammette solo categorie predefinite, deve confrontare il dato ricevuto con una lista consentita. Per un insieme chiuso di scelte è più appropriato select.

2. range e output: aggiornare il valore senza librerie

Gli attributi min, max e step definiscono l’intervallo e gli incrementi ammessi. L’evento input aggiorna l’elemento output durante lo spostamento, offrendo un feedback immediato. L’etichetta include il valore corrente e l’attributo for dell’output lo collega al controllo: non usare il cursore se gli utenti devono inserire un numero preciso con facilità.

3. date e file: vincoli del browser e controlli server

Il valore di un input date viene esposto normalmente come AAAA-MM-GG, anche se la visualizzazione locale può essere diversa. Impostare min con la data locale evita il problema del cambio di giorno dovuto alla conversione UTC. Per i file, multipart/form-data è indispensabile; accept filtra i suggerimenti nel selettore, ma non limita in modo sicuro ciò che il client può inviare.

Confronto tecnico tra controlli nativi HTML5 per i form

La scelta dipende da quanto i valori siano liberi o vincolati e da come debbano essere inseriti. I controlli nativi riducono il JavaScript necessario, ma non eliminano la necessità di accessibilità, test e validazione lato server.

Metodo / Approccio Sintassi / Caratteristica Performance / Complessità Quando sceglierlo
datalist input list collegato a datalist Bassa complessità; nessuna libreria richiesta Suggerimenti facoltativi e valori personalizzabili
select select con opzioni delimitate Bassa complessità; scelta vincolata Elenco chiuso di valori ammessi
range min, max, step Basso costo; richiede un’etichetta chiara Valore approssimativo in un intervallo limitato
number input type="number" Bassa complessità; consente precisione testuale Valori numerici che vanno digitati esattamente

Errori comuni e best practice per form HTML5 in produzione

  • Considerare datalist una validazione: i suggerimenti non restringono i valori. Verifica sul server categoria e regole di business.
  • Fidarsi di accept o del limite dichiarato: l’utente può inviare un file di tipo o dimensione diversa. Controlla dimensione, contenuto effettivo e autorizzazione sul server; genera nomi di archiviazione sicuri e non servire file non verificati come contenuto attivo.
  • Dimenticare enctype: senza enctype="multipart/form-data" il file non viene trasmesso correttamente con il form. Configura inoltre limiti coerenti nel server e nel proxy.
  • Usare una data minima statica o UTC: la data diventa obsoleta o può slittare di giorno. Calcolala nel fuso locale, come nell’esempio, e ricontrollala lato server.
  • Rimuovere etichette e feedback: placeholder e tooltip non sostituiscono un elemento label. Mantieni testi comprensibili, associa gli aiuti con aria-describedby e verifica il form con tastiera e tecnologie assistive.
  • Omettere la protezione dell’endpoint: applica autenticazione quando necessaria, protezione CSRF, rate limiting e sanificazione dell’output; non inserire i valori ricevuti direttamente in HTML o query SQL.

Domande frequenti su datalist, range, date e file

Qual è la differenza tra datalist e select in HTML?

datalist mostra suggerimenti ma lascia l’input modificabile, quindi può ricevere valori non elencati. select limita la scelta alle opzioni disponibili ed è preferibile per categorie che il server deve accettare esclusivamente da un insieme definito. In entrambi i casi il server deve validare i dati ricevuti.

Come imposto la data minima di oggi in un input date?

Assegna all’attributo min una stringa nel formato AAAA-MM-GG, costruita usando anno, mese e giorno locali. Evita di derivarla da toISOString() quando il requisito è la data locale: il metodo converte l’orario in UTC e può produrre il giorno precedente o successivo.

L’attributo accept impedisce di caricare file non consentiti?

No. accept aiuta il browser a filtrare o suggerire file nel selettore, ma non è un controllo di sicurezza. Il server deve verificare dimensioni e contenuto effettivo, applicare limiti di upload e conservare i file in modo sicuro.

Documentazione ufficiale HTML5 per i controlli dei form

SHARE