Controlli di Completamento Automatico Leggeri con la Datalist HTML5

In questo tutorial, approfondiremo l’elemento HTML5 poco utilizzato <datalist>. Può implementare un controllo di autocomplete leggero, accessibile e compatibile tra browser che non richiede JavaScript.

Cosa c’è di sbagliato nel <select>?

I controlli HTML5 <select> sono ideali quando si desidera che l’utente scelga tra un piccolo range di opzioni. Sono meno pratici quando:

  • ci sono molte opzioni, come paesi o titoli di lavoro
  • l’utente desidera inserire la propria opzione che non è nell’elenco

La soluzione ovvia è un controllo di autocomplete. Questo permette all’utente di inserire alcuni caratteri, limitando così le opzioni disponibili per una selezione più rapida.

<select> si sposta nella posizione giusta quando si inizia a digitare, ma ciò non è sempre evidente. Non funzionerà su tutti i dispositivi (come schermi touch), e si resetta entro un secondo o due.

I sviluppatori spesso ricorrono a una delle molte soluzioni alimentate da JavaScript, ma un controllo di autocomplete personalizzato non è sempre necessario. L’elemento HTML5 <datalist> è leggero, accessibile e non ha dipendenze da JavaScript. Potreste aver sentito che è buggato o manca di supporto. Ciò non è vero nel 2021, ma ci sono incoerenze e avvertenze tra i browser.

<datalist> Guida introduttiva

Selezionare il proprio paese da una lista che contiene più di 200 opzioni è un candidato ideale per un controllo di autocomplete. Definisci un <datalist> con elementi figlio <option> per ogni paese direttamente in una pagina HTML:

<datalist id="countrydata">
  <option>Afghanistan</option>
  <option>Åland Islands</option>
  <option>Albania</option>
  <option>Algeria</option>
  <option>American Samoa</option>
  <option>Andorra</option>
  <option>Angola</option>
  <option>Anguilla</option>
  <option>Antarctica</option>
  ...etc...
</datalist>

L’id del datalist può quindi essere referenziato da un attributo list in qualsiasi campo <input>:

<label for="country">country</label>

<input type="text"
  list="countrydata"
  id="country" name="country"
  size="50"
  autocomplete="off" />

Confusamente, è meglio impostare autocomplete="off". Ciò garantisce che vengano mostrati i valori nel <datalist> ma non i valori che l’utente ha precedentemente inserito nel browser.

Il risultato:

Questa è la visualizzazione predefinita in Microsoft Edge. Altri applicativi implementano una funzionalità simile, ma l’aspetto varia tra piattaforme e browser.

<option> Opzioni

Usare il label come testo figlio di un <option> è comune:

<datalist id="mylist">
  <option>label one</option>
  <option>label two</option>
  <option>label three</option>
</datalist>

Utilizzare un attributo value produce risultati identici:

<datalist id="mylist">
  <option value="label one" />
  <option value="label two" />
  <option value="label three" />
</datalist>

Nota: la barra rovesciata /> è opzionale in HTML5, anche se potrebbe aiutare a prevenire errori di codifica.

Puoi anche impostare un valore in base a un label scelto utilizzando uno dei seguenti formati.

Opzione 1:

<datalist id="mylist">
  <option value="1">label one</option>
  <option value="2">label two</option>
  <option value="3">label three</option>
</datalist>

Opzione 2:

<datalist id="mylist">
  <option value="1" label="label one" />
  <option value="2" label="label two" />
  <option value="3" label="label three" />
</datalist>

In entrambi i casi, il campo di input viene impostato su 1, 2 o 3 quando viene scelta un’opzione valida, ma l’interfaccia utente varia tra i browser:

  • Chrome mostra un elenco con sia il valore che il label. Rimane solo il valore una volta selezionata un’opzione.
  • Firefox mostra un elenco solo con il label. Cambia al valore una volta selezionata un’opzione.
  • Edge mostra solo il valore.

Il seguente esempio CodePen mostra tutte le variazioni:

Vedi la Pen
Esempi di autocompletamento HTML5 <datalist>
di SitePoint (@SitePoint)
su CodePen.

Le implementazioni potranno evolvere, ma per ora consiglio di non usare un valore e un label poiché è probabile che confonda gli utenti. (Una soluzione alternativa è discussa di seguito.)

<datalist> Supporto dei browser e Fallback

L’<datalist> elemento è ben supportato nei browser moderni così come Internet Explorer 10 e 11:

Ci sono diverse note sull’implementazione, ma non influiscono sulle situazioni più comuni. Il peggio che potrebbe accadere è che un campo ritorni a un semplice input di testo.

Se devi assolutamente supportare IE9 e versioni precedenti, c’è uno schema di fallback che utilizza un normale <select> in combinazione con un input di testo quando il <datalist> non funziona. Adattando l’esempio del paese:

<label for="country">country</label>

<datalist id="countrydata">

  <select name="countryselect">
    <option></option>
    <option>Afghanistan</option>
    <option>Åland Islands</option>
    <option>Albania</option>
    <option>Algeria</option>
    <option>American Samoa</option>
    <option>Andorra</option>
    <option>Angola</option>
    <option>Anguilla</option>
    <option>Antarctica</option>
    ...etc...
  </select>

  <label for="country">or other</label>

</datalist>

<input type="text"
  id="country" name="country"
  size="50"
  list="countrydata"
  autocomplete="off" />

Vedi la Penna
HTML5 <datalist> autocomplete fallback
di SitePoint (@SitePoint)
su CodePen.

Nei browser moderni, gli elementi <option> diventano parte del <datalist> e la etichetta “o altro” non viene mostrata. Appare identico all’esempio sopra, ma il valore del modulo countryselect sarà impostato su una stringa vuota.

In IE9 e versioni precedenti, sia il lungo <select> che i campi di input di testo sono attivi:

Entrambi i valori potrebbero essere inseriti in vecchie versioni di IE. Il tuo applicativo deve decidere se:

  • stabilire quale sia il più valido, oppure
  • utilizzare una piccola funzione JavaScript per resettare uno quando l’altro viene modificato

Utilizzo di <datalist> su Controlli Non-Testo

I browser basati su Chrome possono anche applicare valori <datalist> a:

  1. Un input con il tipo di "date". L’utente può scegliere da una gamma di opzioni definite come valori YYYY-MM-DD ma presentati nel formato locale.

  2. Un input con tipo "color". L’utente può scegliere tra una selezione di opzioni di colore definite come valori esadecimali a sei cifre (i valori a tre cifre non funzionano).

  3. Un input con tipo "range". Il cursore mostra i segni di spunta, anche se ciò non limita il valore che può essere inserito.

Vedi la Pen
HTML5 <datalist> su altri tipi di input
di SitePoint (@SitePoint)
su CodePen.

<datalist> Stilizzazione CSS

Se hai mai lottato per stilizzare una <select> box, … hai avuto it easy!

Un <input> può essere stilizzato normalmente, ma un <datalist> collegato e i suoi elementi figlio <option> non possono essere stilizzati in CSS. La renderizzazione della lista è interamente determinata dal piattaforma e dal browser.

I hope this situation improves, but for now, a solution is proposed at MDN which:

  1. sovrascrive il comportamento predefinito del browser
  2. tratta efficacemente il <datalist> come un <div> in modo che possa essere stilizzato in CSS
  3. replica tutta la funzionalità di autocomplete in JavaScript

I’ve enhanced it further and the code is available on GitHub. To use it, load the script anywhere in your HTML page as an ES6 module. The jsDelivr CDN URL can be used:

<script src="https://cdn.jsdelivr.net/npm/datalist-css/dist/datalist-css.min.js"></script>

Puoi anche installarlo con npm se stai utilizzando un bundler:

npm install datalist-css

I tuoi elementi <datalist> devono utilizzare il formato <option>value</option>. Ad esempio:

<datalist id="mylist">
  <option>label one</option>
  <option>label two</option>
  <option>label three</option>
</datalist>

Nota: <option value="value" /> non può essere utilizzato, poiché si traduce in un elemento vuoto che non può essere formattato!

È possibile aggiungere CSS per formattare alcuni o tutti gli elementi <datalist> e <option>. Ad esempio:

datalist {
  position: absolute;
  max-height: 20em;
  border: 0 none;
  overflow-x: hidden;
  overflow-y: auto;
}

datalist option {
  font-size: 0.8em;
  padding: 0.3em 1em;
  background-color: #ccc;
  cursor: pointer;
}

/* stile dell'opzione attiva */
datalist option:hover, datalist option:focus {
  color: #fff;
  background-color: #036;
  outline: 0 none;
}

Esempio:

Vedi la Pen
Formattazione CSS dell’autocomplete di HTML5 <datalist>
di SitePoint (@SitePoint)
su CodePen.

La formattazione funziona, ma ne vale la pena? Dubito …

  • Rieseguire i controlli standard del browser, tastiera, mouse e touch con un’adeguata accessibilità è difficile. L’esempio MDN non supporta gli eventi della tastiera e, sebbene abbia cercato di migliorarlo, ci saranno inevitabilmente problemi su alcuni dispositivi.
  • Stai affidando a 200 righe di JavaScript la soluzione di un problema di CSS. Si minimizza a 1,5kB, ma potrebbe introdurre problemi di prestazioni se richiedessi molti lunghi elementi <datalist> nella stessa pagina.
  • Se JavaScript è un requisito, sarebbe preferibile utilizzare un componente JavaScript più bello, coerente e collaudato in battaglia?

Il controllo ricade su un normale HTML5 <datalist> senza stili quando il JavaScript fallisce, ma questo è un piccolo vantaggio.

Creare un <datalist> potenziato con Ajax

Presupponendo che il tuo designer sia disposto ad accettare le differenze di stile tra i browser, è possibile migliorare la funzionalità standard del <datalist> utilizzando JavaScript. Ad esempio:

  1. Implementare una convalida opzionale che accetta solo un valore noto nel <datalist>.
  2. Impostare gli elementi <option> da dati restituiti da chiamate Ajax a API di ricerca.
  3. Impostare altri valori di campo quando viene selezionata un’opzione. Ad esempio, selezionando “Stati Uniti d’America” imposta “US” in un input nascosto.

Il codice principalmente deve ridefinire gli elementi <option>, anche se ci sono diverse considerazioni di programmazione:

  • Una richiesta API Ajax dovrebbe avvenire solo dopo che sono stati inseriti un numero minimo di caratteri.
  • Gli eventi di digitazione dovrebbero essere debounced. Cioè, una chiamata Ajax viene attivata solo quando l’utente ha smesso di digitare per almeno mezzo secondo.
  • I risultati della ricerca dovrebbero essere memorizzati in cache in modo da non essere necessarie ripetute o chiamate identiche da elaborare.
  • Le query inutili dovrebbero essere evitate. Ad esempio, inserire “un” restituisce 12 paesi. Non c’è bisogno di fare ulteriori chiamate Ajax per “unit” o “united” perché tutte le opzioni risultanti sono contenute negli originali 12 risultati.

I’ve created a standard Web Component for this, and the code is available on GitHub. The CodePen example below allows you to select a valid country after entering at least two characters. A music artist autocomplete then returns artists who originated in that country with names matching the search string:

Vedi la Pen
HTML5 <datalist> con autocomplete Ajax
di SitePoint (@SitePoint)
su CodePen.

Per utilizzarla nella tua applicazione, carica lo script ovunque nella tua pagina HTML come modulo ES6. La URL del CDN jsDelivr può essere usata:

<script src="https://cdn.jsdelivr.net/npm/datalist-ajax/dist/datalist-ajax.min.js"></script>

Oppure puoi installarlo con npm se stai usando un bundler:

npm install datalist-ajax

Crea un elemento <auto-complete> con un figlio <input> da utilizzare come campo di inserimento dati. Ad esempio, la ricerca dei paesi utilizza questo:

<label for="country">country lookup:</label>

<auto-complete
  api="https://restcountries.eu/rest/v2/name/${country}?fields=name;alpha2Code;region"
  resultname="name"
  querymin="2"
  optionmax="50"
  valid="please select a valid country"
>
  <input type="text" id="country" name="country" size="50" required />
</auto-complete>

Attributi dell’elemento <auto-complete>:

attribute description
api the REST API URL (required)
resultdata the name of the property containing a result array of objects in the returned API JSON (not required if only results are returned)
resultname the name of the property in each result object which matches the search input and is used for datalist <option> elements (required)
querymin the minimum number of characters to enter before a search is triggered (default: 1)
inputdelay the minimum time to wait in milliseconds between keypresses before a search occurs (default debounce: 300)
optionmax the maximum number of autocomplete options to show (default: 20)
valid if set, this error message is shown when an invalid value is selected

L’URL REST deve contenere almeno un identificatore ${id}, che viene sostituito dal valore impostato nell’<input> con quel id. Nell’esempio sopra, ${country} nell’URL api fa riferimento al valore nel figlio <input>, che ha un id di "country". L’URL utilizzerà normalmente l’input del figlio, ma qualsiasi altro campo sulla pagina può essere referenziato.

L’API restcountries.eu restituisce un singolo oggetto o un array di oggetti contenenti dati sui paesi. Ad esempio:

[
  {
    "name": "Cyprus",
    "alpha2Code": "CY",
    "region": "Europe"
  },
  {
    "name": "Sao Tome and Principe",
    "alpha2Code": "ST",
    "region": "Africa"
  },
  {
    "name": "Andorra",
    "alpha2Code": "AD",
    "region": "Europe"
  }
]

L’attributo resultdata non deve essere impostato perché questi sono i soli dati restituiti (non c’è un oggetto wrapper). L’attributo resultname deve essere impostato su "name" perché quella proprietà viene utilizzata per popolare gli elementi datalist <option>.

Altri campi possono essere compilati automaticamente quando viene scelta un’opzione. I seguenti input ricevono i dati delle proprietà "alpha2Code" e "region" perché è stato impostato l’attributo data-autofill:

<input data-autofill="alpha2Code" type="text" id="countrycode" name="countrycode" readonly />

<input data-autofill="region" type="text" id="region" name="region" readonly />

Come funziona datalist-ajax

Puoi saltare questa sezione se preferisci non leggere 230 righe di codice e mantenere la magia in vita!

Il codice inizialmente crea un nuovo `` all’interno del ``, che viene collegato al figlio `` utilizzando un attributo `list`. Un gestore di eventi `input` monitora il `` e chiama la funzione `runQuery()` quando sono stati inseriti un numero minimo di caratteri e l’utente non sta ancora digitando.

La funzione `runQuery()` costruisce l’URL dell’API a partire dai dati del form e effettua una chiamata Ajax utilizzando il Fetch API. Il JSON restituito viene parsificato, quindi si costruisce un frammento DOM riutilizzabile contenente elementi `

A datalistUpdate() function is called, which updates the <datalist> with the appropriate cached DOM fragment. Further calls to runQuery() avoid Ajax calls if a query has already been cached or a previous query can be used.

A change event handler also monitors the <input>, which is triggered when focus is moved from the field and the value has been modified. The function checks that the value matches a known option and, if necessary, uses the Constraint Validation API to show the error message provided in the valid attribute.

Assumendo che sia stata selezionata un’opzione valida, la funzione gestore di cambiamento popola tutti i campi con attributi `data-autofill` corrispondenti. Viene mantenuta una referenza ai campi di auto-riempimento in modo che possano essere resettati se viene inserita successivamente un’opzione non valida.

Si noti che il DOM shadow è non utilizzato. Ciò garantisce che l’elemento `` di auto-completamento (e ``) possa essere formattato con CSS e acceduto da altri script se necessario.

Dunkin’ ``

L’HTML5 `` ha limitazioni ma è ideale se è necessario un campo di auto-completamento semplice e indipendente da framework. La mancanza di supporto CSS è un peccato, ma i fornitori di browser potrebbero eventualmente risolvere quella omissione.

Qualsiasi parte del codice e degli esempi mostrati in questo tutorial può essere adottata per i propri progetti.

Domande frequenti sui controlli di autocomplete leggeri con il Datalist HTML5

Cos’è l’elemento datalist HTML5 e come funziona?

L’elemento datalist HTML5 è un elenco predefinito di opzioni per un elemento input. Fornisce una funzionalità di “autocomplete” su elementi di form. L’elemento datalist utilizza l’attributo id per associarlo a un input specifico. L’elemento input utilizza l’attributo list per identificare il datalist. All’interno del datalist, puoi definire elementi option che rappresentano le opzioni disponibili per il campo input.

Come posso usare il datalist HTML5 per l’autocomplete?

Per utilizzare il datalist HTML5 per l’autocomplete, è necessario associare il datalist a un campo input. Questo si fa aggiungendo l’attributo list al campo input e impostando il suo valore all’id del datalist. Il browser suggerirà quindi opzioni di autocomplete in base all’input dell’utente e alle opzioni definite nel datalist.

Posso usare l’elemento datalist HTML5 in tutti i browser?

L’elemento datalist HTML5 è supportato in quasi tutti i browser moderni, inclusi Chrome, Firefox, Safari e Edge. Tuttavia, non è supportato in Internet Explorer 9 e versioni precedenti. Puoi verificare la compatibilità del browser attuale su siti come Can I Use.

Come posso personalizzare lo stile delle opzioni del datalist HTML5?

Purtroppo, le opzioni di stile per l’elemento datalist HTML5 sono abbastanza limitate. L’aspetto della lista a discesa è controllato dal browser e non può essere facilmente personalizzato con CSS. Tuttavia, puoi personalizzare il campo input associato al datalist.

Posso usare più datalist per un singolo campo input?

No, non puoi associare più datalist a un singolo campo di input. L’attributo list del campo di input può accettare solo un id, che corrisponde a un datalist. Se hai bisogno di fornire più set di opzioni, potresti aver bisogno di utilizzare JavaScript per cambiare dinamicamente le opzioni in base all’input dell’utente.

Posso usare il datalist HTML5 con altri tipi di input?

Sì, il datalist HTML5 può essere utilizzato con vari tipi di input, tra cui testo, ricerca, url, tel, email, data, mese, settimana, ora, datetime-local, numero, range e colore. Tuttavia, la funzione di autocompletamento potrebbe non funzionare come previsto con alcuni tipi di input come range o colore.

Posso usare il datalist HTML5 con un elemento select?

No, il datalist HTML5 non può essere utilizzato con un elemento select. Il datalist è progettato per fornire suggerimenti di autocompletamento per un campo di input, mentre l’elemento select fornisce un elenco a discesa di opzioni. Se hai bisogno di un elenco a discesa, dovresti usare l’elemento select invece.

Posso usare JavaScript con il datalist HTML5?

Sì, puoi usare JavaScript con il datalist HTML5 per aggiungere, rimuovere o modificare le opzioni in modo dinamico. Tuttavia, tieni presente che il datalist non supporta eventi come onchange o onclick sulle sue opzioni. Devi aggiungere gli event listener al campo di input associato invece.

Posso usare il datalist HTML5 per un campo di ricerca?

Sì, il datalist HTML5 può essere un’ottima scelta per un campo di ricerca. Può fornire suggerimenti di autocompletamento in base all’input dell’utente, il che può migliorare l’esperienza dell’utente. Tuttavia, devi popolare manualmente il datalist con i possibili termini di ricerca.

Posso usare il datalist di HTML5 con un textarea?

No, il datalist di HTML5 non può essere utilizzato con un textarea. Il datalist è progettato per fornire suggerimenti di autocompletamento per un campo di input, non per un textarea. Se hai bisogno di funzionalità di autocompletamento per un textarea, potresti dover utilizzare una libreria JavaScript o sviluppare la tua soluzione.

Source:
https://www.sitepoint.com/html5-datalist-autocomplete/