Autocompletion é um padrão com o qual todos os utilizadores da web estão familiarizados. Quando se faz uma pesquisa, o seu motor de busca sugere termos. Quando escreve uma nova mensagem de correio electrónico, o seu cliente de correio sugere destinatários. Esta funcionalidade, contudo, não tem estado disponível para programadores web sem uma quantidade não trivial de JavaScript. Um dos novos elementos HTML5, o , traz esta funcionalidade autocompleta para a Web nativamente. Neste artigo, descreverei o que são os datalistas, quando é apropriado utilizá-los, as suas limitações e o que fazer para os navegadores que não os suportam. Vamos começar.
Antes de começar
Quer criar um datalista para o seu site sem usar HTML5? Use JotForm para construir rapidamente um menu dropdown personalizado – ou mesmo um dropdown dinâmico complexo – sem necessidade de codificação.
Criar datalistas
Para mostrar como funciona um datalista, vamos começar com uma entrada de texto tradicional:
- <label for=”favorite_team”> Equipa Favorita:</label>
- <input type=”text” name=”team” id=”favorite_team”>
Este campo pede a um utilizador para fornecer a sua equipa desportiva favorita. Por defeito, o utilizador não receberá ajuda adicional para completar o campo. Mas ao utilizar um datalist, pode fornecer uma lista de opções que o utilizador pode seleccionar para completar o campo. Para o fazer, definir uma lista de dados com um elemento de opção para cada sugestão:
- <datalista>
- <opção>Detroit Lions</opção>
- <opção>Detroit Pistons</opção>
- <opção> Asas Vermelhas de Detroit</opção>
- <opção>Detroit Tigers</opção>
- <!- etc…. ->
- </datalista>
Para ligar um elemento de entrada a um elemento de entrada, dar ao elemento de entrada um atributo de lista e ao elemento de entrada um atributo de id que corresponda. Aqui está um exemplo:
- <label for=”favorite_team”>Favorite Team:</label>
- <input type=”text” name=”team” id=”favorite_team” list=”team_list”>
- <datalista id=”team_list”>
- <opção>Detroit Lions</opção>
- <opção>Detroit Pistons</opção>
- <opção> Asas Vermelhas de Detroit</opção>
- <opção>Detroit Tigers</opção>
- <!- etc… ->
- </datalista>
Nota que o atributo lista do input e o atributo id do datalista contêm o mesmo valor, “team_list”. Isto fornece a ligação entre os dois.
É isso mesmo. Não é necessário JavaScript para fazer um datalist funcionar. A figura 1 mostra o que o utilizador verá nos navegadores de suporte após digitar um D.
br>Figure 1. Exibição Datalista (canto superior esquerdo: Internet Explorer 10; em cima à direita: Firefox 18; em baixo à esquerda: Cromo 24; em baixo à direita: Opera 12)
Nota: Internet Explorer 10 e Opera não requerem que o utilizador escreva um caracter antes de ver sugestões, enquanto que Firefox e Chrome do.
Os elementos de opção também podem ter um atributo de valor. Isto é útil quando um utilizador pode não conhecer o código associado a uma dada opção. Considere os seguintes E.U.A. state input:
- <label for=”state”>State:</label>
- <input type=”text” name=”state” id=”state” list=”state_list”>
- <datalista id=”state_list”>
- < valor da opção=”AL”>Alabama</opção>
- <opção valor=”AK”>Alaska</opção>
- < valor da opção=”AZ”>Arizona</opção>
- < valor da opção=”AR”>Arkansas</opção>
- <!- etc ->
- </datalista>
Aqui, o utilizador verá uma lista de nomes completos do estado, mas quando o utilizador fizer uma selecção, o texto introduzido será preenchido com o código do estado e não com o nome completo. Um exemplo é mostrado na Figura 2.
br>Figure 2. Selecção de uma Opção Datalist com um Valor Correspondente (Firefox 18)
O Atributo Auto-Completar
Se os datalistas da Figura 1 e da Figura 2 parecem familiares, é porque os browsers tiveram o auto-completar implementado durante muito tempo. Todos os browsers têm algum mecanismo de armazenamento das entradas de um utilizador para serem utilizadas para o auto-completar mais tarde.
Os autores podem utilizar o atributo auto-completar para controlar se o browser deve tentar completar automaticamente os dados do utilizador. Os valores possíveis são mostrados no seguinte exemplo:
- <form>>
- <!-
- Se o atributo autocompletar não for especificado, herda o valor
- do seu elemento de forma pai. Se não for especificado, o valor por defeito do atributo autocompletar do formulário
- está “ligado”. Uma vez que nem este input nem o seu
- form têm o atributo especificado, será utilizado o estado “on”.
- ->
- <input type=”text” name=”firstName”>
- <!-
- O estado “on” indica que o navegador pode lembrar o valor para o futuro
- utilizar, bem como sugerir valores previamente armazenados.
- ->
- <input type=”text” name=”address” autocomplete=”on”>
- <!-
- O estado “off” diz ao navegador para não guardar o valor introduzido para
- esta entrada nem para sugerir valores introduzidos anteriormente. Isto deve ser
- usado se os dados forem sensíveis ou se o valor nunca será reutilizado.
- ->
- <input type=”text” name=”secret” autocomplete=”off”>
- </form>
Então qual é a diferença entre o atributo autocompletar e os datalistas? O atributo autocompletar diz ao navegador se deve dar a um utilizador opções de conclusão baseadas em entradas anteriores e se deve armazenar o valor introduzido para conclusão futura. As listas de dados são listas de sugestões fornecidas pelo autor que são sempre exibidas independentemente da entrada anterior.
Uma advertência é que a definição do atributo autocompletar para “off” impede que as listas de dados sejam exibidas no Opera. Aqui está um exemplo:
- <!-
- Este datalista nunca será exibido no Opera porque o atributo autocompletar
- está definido para “off”. Será exibido em todos os outros navegadores de suporte.
- ->
- <input type=”text” list=”pets” autocomplete=”off”>
- <datalista id=”animais de estimação”>
- <opção>Cat</opção>
- <opção>Dog</opção>
- <opção>Hamster</opção>
- <opção>Tartaruga</opção>
- </datalista>
Outros Tipos de Entrada
Enquanto o auto-completamento é tradicionalmente associado à entrada textual, Os datalistas também podem ser utilizados em alguns dos novos tipos de entrada HTML5. Considere o tipo de entrada de gama, que permite a criação de um elemento de formulário deslizante. Ao combinar isto com um datalist, pode sugerir pontos na gama ao utilizador.
Por exemplo, a entrada seguinte pede ao utilizador para fornecer uma doação entre $5 e $200 dólares.
- <label for=”donation”>Donation Amount (USD):</label>
- <input type=”range” name=”donation” id=”donation” list=”donation_list”
- step=”5″ min=”5″ max=”200″>
- <datalista id=”donation_list”>
- <opção></opção>
- <opção></opção>
- <opção></opção>
- <opção></option>
- </datalist>
Figure 3 e a Figura 4 mostram a visualização de uma entrada de gama no Chrome 24 e no Internet Explorer 10, respectivamente.
br>Figure 3. Entrada de gama com Datalist (Cromo 24)
br>Figure 4. Entrada de gama com Datalist (Internet Explorer 10)
P>Pode ver-se que cada browser exibe uma marca de selecção para cada opção datalist fornecida. Além disso, o Chrome irá encaixar o selector nestes valores pré-definidos à medida que o utilizador se aproxima do selector.
Felizmente, o Internet Explorer e o Chrome são os únicos navegadores que suportam a entrada de dados com lista de gama de valores neste momento. A Figura 5 mostra o suporte de listas de dados em tipos de entrada comuns em navegadores modernos.
br>Figure 5. Suporte de Navegadores de Datalistas em Tipos de Entrada de Formulários
Quando se usa um Datalista
Os datalistas não têm um mecanismo incorporado para exigir que um utilizador seleccione uma opção fornecida, são bem adequados para entradas que podem aceitar qualquer valor. O exemplo anterior de fornecer uma equipa desportiva enquadra-se aqui. Enquanto a datalista sugeria equipas, o utilizador era livre de introduzir qualquer valor.
Conversamente, o exemplo do estado americano falha neste teste porque existe um conjunto limitado de valores válidos que o utilizador deve fornecer. Este caso de utilização é melhor tratado pelo elemento seleccionado porque obriga a uma selecção.
Uma excepção a isto são as entradas com um grande número de selecções válidas. Por exemplo, considere a tradicional lista pendente de países mostrada na Figura 6.
br>Figure 6. Lista pendente padrão do país
Esta lista impede os utilizadores ao forçá-los a procurar através de centenas de opções para encontrar a que estão à procura. Uma funcionalidade autocompleta encaixa bem neste caso de utilização porque um utilizador pode filtrar rapidamente a lista digitando um ou dois caracteres.
Aqui está como a selecção do país pode ser implementada com um datalist:
- <label for=”country”>Country:</label>
- <input type=”text” id=”country” list=”country_list”>
- <datalista id=”country_list”>
- < valor da opção=”AF”>Afeganistão</opção>
- <opção value=”AX”> ilhasÅland</opção>
- < valor da opção=”AL”>Albânia</opção>
- < valor da opção=”DZ”>Algeria</opção>
- <!- more ->
- </datalista>
Figure 7 mostra o que o utilizador vai ver depois de digitar um U.
br>Figure 7. A Datalist Approach to the Country Form Field
Enforcing a Value
Embora os datalists não lhe permitam nativamente exigir que uma opção seja seleccionada, pode facilmente adicionar uma validação que o faça. Por exemplo, o seguinte código faz uso da API de validação de restrição HTML5 para adicionar tal validação:
- // Encontrar todas as entradas no DOM que estão ligadas a um datalist através do atributo da sua lista.
- entradas de validação HTML5 = document.querySelectorAll(‘input’);
- for (var i = 0; i < entradas.length; i++) {
- // Quando o valor do input muda…
- inputs.addEventListener(‘change’, function() {
- var optionFound = false,
- datalist = this.list;
- // Determinar se existe uma opção com o valor actual do input.
- para (var j = 0; j < datalist.options.length; j++) {
- if (this.value === datalist.options.valor) {
- optionFound = true;
- break;
- }
- }/li>
- // use a função setCustomValidity do API de validação
- // para fornecer um feedback do utilizador se o valor não existir no datalist
- if (optionFound) {
- isto.setCustomValidity(“);
- } else {
- this.setCustomValidity(‘Por favor seleccione um valor válido.’);
- }
- });
- /li>
A API de validação de restrições é implementada em todos os browsers que suportam datalists, por isso, se o datalist funcionar, a validação deve funcionar também. Agora, quando o utilizador tenta submeter um formulário com uma entrada que tem um datalist (e não seleccionou uma opção), verá o erro mostrado na Figura 8.
br>Figure 8. Erro da API de Validação de Restrição (Internet Explorer 10)
É importante notar que a API de validação de restrição não elimina a necessidade de validação do lado do servidor. Os utilizadores que trabalham com browsers mais antigos não terão disponível a API de validação de restrição, e os utilizadores maliciosos podem facilmente subverter scripts do lado do cliente.
Embora esta abordagem funcione em browsers modernos, apresenta uma IU inutilizável aos utilizadores que executam browsers que não têm suporte. Os utilizadores são informados de que devem seleccionar um valor válido, mas se o seu navegador não suportar datalists, não podem ver as opções. Portanto, se planeia utilizar esta abordagem, é essencial fornecer uma IU que funcione em todos os browsers. Isto pode ser conseguido detectando se o browser suporta datalists e depois polifilling apropriadamente.
Navegadores sem suporte
Na altura desta escrita, os datalists para entradas de texto são suportados no Internet Explorer 10, Firefox 4+, Chrome 20+, e Opera, o que infelizmente deixa de fora um grande número de utilizadores.
Não é semelhante com muitas novas características HTML5, para a maioria dos casos de uso, não é necessário fazer trabalho extra em browsers que não suportam datalists. Por defeito, a lista de opções que fornece são meramente sugestões; portanto, os utilizadores com browsers que não têm suporte precisarão simplesmente de preencher o campo de texto sem quaisquer sugestões.
No entanto, algumas opções de recurso podem ser usadas para fornecer uma experiência mais completa aos utilizadores que executam browsers sem suporte.
Fallback to Alternate HTML Content
Uma opção, popularizada por Jeremy Keith, é aproveitar o facto de que os browsers que não suportam o elemento datalista continuarão a exibir elementos filhos para o utilizador. O seguinte mostra como o exemplo de datalista de país pode ser alterado e voltar a usar <select>:
ol>
A IU apresentada aos utilizadores em navegadores que suportam listas de dados não será alterada, mas os utilizadores que trabalham com browsers sem suporte vêem agora um elemento seleccionado com as opções do país e uma caixa de texto que podem utilizar para introduzir qualquer valor. Isto é mostrado na Figura 9.
br>Figure 9: A Select Fallback for Datalists (Internet Explorer 9)
Polyfilling
Uma característica que o fallback seleccionado não fornece é o comportamento autocompleto que os datalistas oferecem nativamente. Se isso for importante para as listas de dados que está a adicionar, uma segunda opção de recurso é polifilhar uma implementação datalista.
Para começar, é preciso primeiro determinar se o navegador do utilizador suporta listas de dados. A popular biblioteca de detecção de características Modernizr fornece tal teste, como mostrado aqui:
- if (Modernizr.input.list) {
- // O navegador suporta o atributo da lista e as listas de dados.
- } else {
- //O navegador não suporta nem o atributo da lista nem as listas de dados.
- }
- /li>
- }/li>
Utilizando esta abordagem, pode agora polifilar uma implementação datalista para utilizadores em navegadores sem suporte. Enquanto vários polifill estão disponíveis para os datalistas, prefiro utilizar o widget jQuery UI autocomplete. O seguinte código mostra uma implementação polyfill:
- var datalist,
- listAttribute,
- options = ;
- // Se o browser não suportar o atributo list…
- se (!Modernizr.input.list) {
- // Para cada entrada de texto com um atributo de lista…
- $(‘input’).each(function() {
- // Encontre o id do datalist no input
- // Usando isto, encontre o datalist que corresponde ao input.
- listAttribute = $(this).attr(‘list’);
- datalist = $(‘#’ + listAttribute);
- // Se a entrada tiver um elemento datalist correspondente…
- if (datalist.comprimento > 0) {
- opções = ;
- // Construir a lista de opções para passar ao widget autocompletar.
- datalist.find(‘opção’).each(function() {
- options.push({ label: this.innerHTML, value: this.value });
- });
- // Transforme a entrada num widget jQuery UI autocomplete.
- $(this).autocomplete({ fonte: opções });
- }
- });
- // Remove todos os datalists do DOM para que não exibam.
- $(‘datalist’).remove();
- }
Figure 10 mostra a exibição do exemplo da lista de países no Safari com o polifiltro jQuery UI autocompleto.
br>Figure 10. País Datalist Polyfilled Using jQuery UI’s Autocomplete Widget(Safari)
P>Pode ter notado que, por defeito, o widget autocompleto da jQuery UI corresponde a caracteres em qualquer parte das opções, enquanto os datalists correspondem apenas às opções no início da string. Ao contrário do datalist nativo, o widget autocompletar permite-lhe personalizar isto para corresponder às opções que desejar.
O exemplo seguinte mostra como se pode construir uma funcionalidade autocompletar que corresponda às opções apenas no início da cadeia de caracteres:
- <input type=”text” id=”autocomplete”>
- <script>
- opções de var = ;
- $(‘#autocompleto’).autocomplete({
- // req conterá um objecto com uma propriedade “termo” que contém o valor
- // actualmente na entrada de texto. respostaFn deve ser invocada com as opções
- // para mostrar ao utilizador.
- fonte: function (req, responseFn) {
- // Escape any RegExp meaningful characters such as “.”, or “^” from the
- // keyed term.
- var term = $.ui.autocomplete.escapeRegex(req.term),
- // ‘^’ é o caracter RegExp a corresponder no início da string.
- // ‘i’ diz ao RegExp para fazer uma correspondência insensível a maiúsculas e minúsculas.
- matcher = novo RegExp(‘^’ + termo, ‘i’),
- // Loop sobre as opções e selecciona apenas as que correspondem ao RegExp.
- matcher = $.grep(opções, função (item) {
- return matcher.test(item);
- });
- // Devolver as opções correspondentes.
- responseFn(matches);
- }
- });
- </script>
Versões mais antigas do Internet Explorer
Para fazer funcionar qualquer polifill do elemento datalista em versões mais antigas do Internet Explorer, é necessário dar dois passos extra.
Option Elements
A primeira é que a versão 9 e anteriores do Internet Explorer requerem que os elementos da opção sejam filhos imediatos de elementos seleccionados. Se não forem, estas versões não os reconhecem, e não serão visíveis para o polifill.
Felizmente, isto é fácil de contornar. Ao utilizar comentários condicionais, pode colocar um elemento seleccionado em torno das opções apenas para estas versões do Internet Explorer. Consulte este exemplo:
- <datalista>
- <><select><<>
- <opção>Apple</opção>
- <opção>Banana</opção>
- <opção>Cherry</opção>
- <!- etc ->
- <><select><<>
- </datalista>
Internet Explorer versão 9 e anterior irá agora detectar as opções adequadamente. O Internet Explorer 10 não será afectado, uma vez que os comentários condicionais foram removidos do analisador no Internet Explorer 10. Todos os outros navegadores também ignorarão os comentários.
HTML5 Shiv
Na versão 8 e anterior do Internet Explorer, elementos desconhecidos não podem conter crianças. Portanto, mesmo que os elementos de opção de um datalista estejam dentro de elementos seleccionados, eles ainda não serão reconhecidos.
Felizmente, também há uma solução fácil para esta questão. A popular biblioteca HTML5 Shiv permite que elementos desconhecidos do Internet Explorer 6-8 tenham filhos. Este shiv está incluído por defeito no Modernizr; basta ter a certeza que a caixa de verificação “html5shiv” está seleccionada quando configura o seu download.
Limitações dos Datalists
P>Os datalists são perfeitos para adicionar sugestões a entradas de texto, mas sofrem da falta de capacidades de personalização que muitas aplicações Web modernas requerem. Por exemplo, não se pode fazer o seguinte com as listas de dados:
- Utilizar CSS para alterar a sua exibição ou a exibição das suas opções.
- Controlar o posicionamento da lista.
- Controlar o número de caracteres digitados antes de o navegador exibir os resultados ao utilizador.
- Controla o que é considerado uma correspondência (sensibilidade ao caso, correspondência no início da string versus em qualquer lugar, e assim por diante).
- Anexa a entrada a uma fonte de dados do lado do servidor.
Isto significa que se precisar de alguma desta funcionalidade, terá de procurar uma solução mais robusta de autocompletar. O widget jQuery UI autocomplete fornece a capacidade de fazer tudo isto e muito mais. O widget autocompletar também suporta todos os navegadores de volta ao Internet Explorer 7 sem a necessidade de um polifill. Para mais informações sobre o widget autocompletar, consulte as suas demonstrações e a documentação API. (O widget autocompletar trata apenas de entradas baseadas em texto, pelo que não o poderá ajudar em alguns dos tipos de entrada mais especializados como gama e cor.)
Embrulhar para cima
Datalistas fornecem um meio rápido e nativo de exibir sugestões de entrada ao utilizador. Uma vez que as opções são meras sugestões, para muitas situações não é necessário fornecer um fallback para navegadores sem suporte; os utilizadores destes navegadores simplesmente não verão as sugestões.
Para situações em que se pretende fornecer um datalist funcional a todos os utilizadores, é possível detectar suporte e polifilhar a funcionalidade para navegadores que não têm suporte.
Embora os datalists sejam óptimos para oferecer sugestões, são limitados na funcionalidade que fornecem. Se precisar de uma solução autocompleta mais robusta, o widget autocompletar da jQuery UI é um bom local para começar.