Las listas desplegables son una forma elegante de proporcionar opciones para un campo de entrada, especialmente cuando la lista de opciones disponibles es larga. Un usuario puede elegir la opción que desee escribiendo en el campo o buscar entre las opciones que puedan coincidir con lo que están buscando. Sin embargo, la solución ideal es poder buscar a través de las opciones.

Este comportamiento se puede lograr con el elemento HTML <datalist> que muestra sugerencias de entrada para diferentes controles, como la etiqueta <input>. Sin embargo, <datalist> solo muestra las opciones disponibles cuando el usuario ya ha escrito algo en el campo de entrada.

Podemos hacer que un campo de entrada sea más usable si permitimos a los usuarios acceder a la lista completa de opciones en cualquier momento durante el proceso de entrada.

En esta publicación, vamos a ver cómo crear una lista desplegable que sea buscable en cualquier momento utilizando los elementos HTML <select> y <datalist> y un poco de JavaScript.

Crear un Datalist con Opciones

Primero, creamos un datalist para diferentes editores de texto. Asegúrate de que el valor del atributo “list” de la etiqueta <input> sea el mismo que el id de la etiqueta <datalist>, de esta manera los vinculamos entre sí.

HTML
<input type="text" list="text_editors">
<datalist id="text_editors">
    <option value="Atom">Atom
    <option value="Brackets">Brackets
    <option value="Notepad ++">Notepad ++
    <option value="Notepad">Notepad
    <option value="Sublime Text">Sublime Text
    <option value="TextEdit">TextEdit
    <option value="TextMate">TextMate
    <option value="Wordpad">Wordpad
</datalist>
Ejemplo de Datalist sobre editores de texto
Ejemplo de Datalist sobre editores de texto

Hacer visible el Datalist

Por defecto, el elemento HTML <datalist> está oculto. Solo podemos verlo cuando comenzamos a escribir una entrada en el campo al que está adjunto el datalist.

Sin embargo, existe una forma de “forzar” que el contenido del datalist (es decir, todas sus opciones) aparezca en la página web. Solo necesitamos asignarle un valor adecuado a la propiedad de visualización (display) distinto de “none“, por ejemplo, display:block;.

CSS
datalist {
    display: block;
}

Las opciones mostradas en este punto aún no son seleccionables; el navegador solo representa las opciones que encuentra dentro del datalist.

Elementos visibles de un datalist
Elementos visibles de un datalist

Como se mencionó anteriormente, debido al comportamiento incorporado del elemento <datalist>, algunas de las opciones ya aparecen y son seleccionables, pero solo cuando el usuario comienza a escribir una cadena para la cual el navegador puede encontrar una opción coincidente.

Ejemplo de Datalist visible con sugerencias
Ejemplo de Datalist visible con sugerencias

También necesitamos encontrar un mecanismo para hacer que todas las opciones (en la captura de pantalla anterior que se muestra debajo de la lista desplegable del datalist) sean seleccionables en cualquier otro momento del proceso de entrada, ya sea cuando los usuarios deseen consultar las opciones antes de escribir algo o mientras ya han introducido algo en el campo de entrada.

Introducir el Elemento HTML <select>

Existen dos formas de permitir a los usuarios ver y seleccionar todas las opciones cuando lo deseen:

  • Podemos agregar un controlador de eventos de clic (click event handler) a cada opción y utilizarlo para seleccionar una opción cuando se hace clic en ella, o también podemos transformar las opciones en una lista desplegable real, que, por defecto, es seleccionable.
  • Podemos envolver las opciones del datalist con el elemento HTML <select>.

Elegiremos el segundo método, ya que es más sencillo y se permite su uso como mecanismo de respaldo en navegadores que no admiten el elemento <datalist>. Cuando un navegador no puede representar y mostrar el datalist, en su lugar representa el elemento <select> con todas sus opciones.

Por defecto, el elemento select no aparece en los navegadores que admiten datalist, es decir, hasta que forcemos al datalist a representar su contenido con la regla CSS display: block;.

Entonces, cuando envolvemos las opciones del ejemplo anterior (donde el datalist tiene display:block) con la etiqueta HTML <select>, el código se ve de la siguiente manera:

HTML
<input type="text" list="text_editors">
<datalist id="text_editors">
    <select>
        <option value="Atom">Atom
        <option value="Brackets">Brackets
        <option value="Notepad ++">Notepad ++
        <option value="Notepad">Notepad
        <option value="Sublime Text">Sublime Text
        <option value="TextEdit">TextEdit
        <option value="TextMate">TextMate
        <option value="Wordpad">Wordpad
    </select>
</datalist>
Ejemplo de datalist combinado con select
Ejemplo de datalist combinado con select

Para ver todas las opciones del select en la lista desplegable, necesitamos utilizar los atributos “multiple” para mostrar más de una opción y “size” para especificar el número de opciones que deseamos mostrar.

HTML
<select multiple size=8>
Añadir el atributo multiple a la etiqueta select
Añadir el atributo multiple a la etiqueta select

Añadir un Botón de Alternancia

Se supone que la lista desplegable completa solo aparecerá cuando el usuario haga clic en un botón de alternancia junto al campo de entrada, mientras el usuario escribe, se mostrará el datalist funcional. Cambiemos el valor de visualización (display) del datalist a “none” y agreguemos un botón junto al campo de entrada que cambiará el valor de visualización del datalist y, por ende, activará la aparición del select.

CSS
datalist {
  display: none;
}

También necesitamos agregar el siguiente botón encima del datalist en el archivo HTML:

HTML
<button></button>

Ahora veamos el JavaScript. Primero, definimos las variables iniciales.

JavaScript
button = document.querySelector('button');
datalist = document.querySelector('datalist');
select = document.querySelector('select');
options = select.options;

A continuación, debemos agregar un escucha de eventos (toggle_ddl) para el evento de clic del botón que alternará la aparición del datalist.

JavaScript
button.addEventListener('click', toggle_ddl);

Luego, definimos la función toggle_ddl(). Para ello, debemos verificar el valor de la propiedad datalist.style.display. Si es una cadena vacía, el datalist está oculto, por lo que debemos establecer su valor en “block” y también cambiar el botón de una flecha hacia abajo a una flecha hacia arriba.

JavaScript
function toggle_ddl(){
    /* Si el DDL está oculto */
    if(datalist.style.display === ''){
        /* Mostrar el DDL */
        datalist.style.display = 'block';
        this.textContent = "";
    }
    else hide_select();
}

function hide_select(){
    /* Ocultar el DDL */
    datalist.style.display = '';
    button.textContent = "";
}

La función hide_select() oculta el datalist volviendo a establecer la propiedad datalist.style.display en una cadena vacía y cambia la flecha del botón nuevamente hacia abajo.

En la configuración final, si los campos de entrada contienen una opción previamente seleccionada y la lista desplegable también se ha activado más tarde haciendo clic en un botón, la opción previamente seleccionada también debe mostrarse como seleccionada en la lista desplegable.

Entonces, agreguemos el siguiente código resaltado a la función toggle_ddl():

JavaScript
function toggle_ddl(){
    /* Si el DDL está oculto */
    if(datalist.style.display === ''){
        /* Mostrar DDL */
        datalist.style.display = 'block';
        this.textContent = "";
        var val = input.value;
        for(var i = 0; i < options.length; i++) {
            if (options[i].text === val) {
                select.selectedIndex = i;
                break;
            }
        }
    }
    else hide_select();
}

function hide_select(){
    /* Ocultar DDL */
    datalist.style.display = '';
    button.textContent = "";
}

También deseamos ocultar la lista desplegable cuando el usuario está escribiendo en el campo de entrada (en el momento en que aparecerá el datalist funcional).

JavaScript
/* Cuando el usuario quiere escribir en el campo de texto, ocultar el DDL */
input = document.querySelector('input');
input.addEventListener('focus', hide_select);

Actualizar el Campo de Entrada cuando se Selecciona una Opción

Finalmente, agreguemos un controlador de eventos “change” al elemento <select> para que, cuando el usuario seleccione una opción de la lista desplegable, su valor se muestre dentro del campo <input> también.

JavaScript
/* cuando el usuario selecciona una opción del DDL, escríbala en el campo de texto */
select.addEventListener('change', fill_input);
function fill_input(){
    input.value = options[this.selectedIndex].value;
    hide_select();
}

Desventajas

La principal desventaja de esta técnica es la falta de una forma directa de aplicar estilos al elemento <datalist> con CSS (la apariencia de las etiquetas <datalist> y <select> varía en diferentes navegadores).

Además, en Firefox, el texto de entrada se compara con opciones que contienen los caracteres de entrada, mientras que en otros navegadores se comparan con opciones que comienzan con esos caracteres. La especificación del W3C para datalist no especifica explícitamente cómo debe hacerse la comparación.

Aparte de eso, este método es bueno y funciona en todos los principales navegadores. En los navegadores donde puede no funcionar, los usuarios aún pueden ver la lista desplegable, solo que las sugerencias no aparecerán.

Echa un vistazo a la demostración final con un poco de estilo CSS a continuación:

See the Pen Búsqueda listas desplegables – Datalist by Alex (@htmldesdecero) on CodePen.

5/5 - (1 voto)