with control html5 autocomplete html-datalist

control - Use HTML5(datalist) autocompletar con el enfoque ''contiene'', no solo ''comienza con''



input autocomplete datalist (3)

(No puedo encontrarlo, pero, una vez más, no sé cómo buscarlo).

Quiero usar <input list=xxx> y <datalist id=xxx> para obtener el autocompletado, PERO quiero que el navegador coincida con todas las opciones mediante el enfoque ''contiene'', en lugar de ''comienza con'', lo que parece ser estándar. ¿Hay alguna manera?

Si no es así, ¿hay alguna forma de forzar la presentación de sugerencias que quiero mostrar, no las que coinciden con el navegador? Digamos que estoy escribiendo "foo" y quiero mostrar las opciones "bar" y "baz". ¿Puedo forzarlos sobre el usuario? Si solo lleno el datalist con esos (con JS), el navegador seguirá haciendo su verificación ''comienza con'' y los filtrará.

Quiero el máximo control sobre CÓMO se muestran las opciones de la lista de datos. NO sobre su interfaz de usuario, flexibilidad, accesibilidad, etc., por lo que no quiero rehacerlo por completo. Ni siquiera sugiera un complemento jQuery.

Si puedo controlar la validación de elementos de formulario, ¿por qué no autocompletar, verdad?

editar: Ahora veo que Firefox usa el enfoque ''contiene'' ... ¿Eso ni siquiera es un estándar? ¿Alguna forma de forzar esto? ¿Podría cambiar la forma de Firefox?

editar: Hice esto para ilustrar lo que me gustaría: http://jsfiddle.net/rudiedirkx/r3jbfpxw/


Sin embargo, este hilo se publicó hace aproximadamente 2 años. pero si está leyendo este hilo, tal vez necesite verificar una versión más nueva de su navegador:

Especificación actual: https://html.spec.whatwg.org/multipage/forms.html#the-list-attribute

Se alienta a los agentes de usuario a filtrar las sugerencias representadas por el elemento fuente de sugerencias cuando el número de sugerencias es grande, incluidas solo las más relevantes (por ejemplo, basadas en la entrada del usuario hasta el momento). No se define un umbral preciso, pero es razonable limitar la lista de cuatro a siete valores. Si el filtrado se basa en la entrada del usuario, los agentes del usuario deben usar la coincidencia de subcadenas con la etiqueta y el valor de las sugerencias .

Y cuando se escribió esta publicación, el comportamiento de Firefox (51) y Chrome (56) ya había cambiado para que coincidiera con la especificación.

lo que significa que lo que quiere debería funcionar ahora.


este violín aquí ha roto lo que está pidiendo, pero no estoy seguro de cómo hacerlo funcionar sin esta dependencia, ya que la interfaz de usuario parece un poco extraña y fuera de lugar cuando se usa junto con Bootstrap.

elem.autocomplete({ source: list.children().map(function() { return $(this).text(); }).get()


enfoque ''contiene''

Tal vez esto es lo que estás buscando (parte 1 de tu pregunta).

Va con la limitación de "comienza con" y cambia cuando se realiza una selección.

''use strict''; function updateList(that) { if (!that) { return; } var lastValue = that.lastValue, value = that.value, array = [], pos = value.indexOf(''|''), start = that.selectionStart, end = that.selectionEnd, options; if (that.options) { options = that.options; } else { options = Object.keys(that.list.options).map(function (option) { return that.list.options[option].value; }); that.options = options; } if (lastValue !== value) { that.list.innerHTML = options.filter(function (a) { return ~a.toLowerCase().indexOf(value.toLowerCase()); }).map(function (a) { return ''<option value="'' + value + ''|'' + a + ''">'' + a + ''</option>''; }).join(); updateInput(that); that.lastValue = value; } } function updateInput(that) { if (!that) { return; } var value = that.value, pos = value.indexOf(''|''), start = that.selectionStart, end = that.selectionEnd; if (~pos) { value = value.slice(pos + 1); } that.value = value; that.setSelectionRange(start, end); } document.getElementsByTagName(''input'').browser.addEventListener(''keyup'', function (e) { updateList(this); }); document.getElementsByTagName(''input'').browser.addEventListener(''input'', function (e) { updateInput(this); });

<input list="browsers" name="browser" id="browser" onkeyup="updateList();" oninput="updateInput();"> <datalist id="browsers"> <option value="Internet Explorer"> <option value="Firefox"> <option value="Chrome"> <option value="Opera"> <option value="Safari"> </datalist>

Editar

Un enfoque diferente de mostrar el contenido de la búsqueda, para dejar en claro, lo que sucede. Esto también funciona en Chrome. Inspirado en Mostrar etiquetas de datos pero enviar el valor real

''use strict''; var datalist = { r: [''ralph'', ''ronny'', ''rudie''], ru: [''rudie'', ''rutte'', ''rudiedirkx''], rud: [''rudie'', ''rudiedirkx''], rudi: [''rudie''], rudo: [''rudolf''], foo: [ { value: 42, text: ''The answer'' }, { value: 1337, text: ''Elite'' }, { value: 69, text: ''Dirty'' }, { value: 3.14, text: ''Pi'' } ] }, SEPARATOR = '' > ''; function updateList(that) { var lastValue = that.lastValue, value = that.value, array, key, pos = value.indexOf(''|''), start = that.selectionStart, end = that.selectionEnd; if (lastValue !== value) { if (value !== '''') { if (value in datalist) { key = value; } else { Object.keys(datalist).some(function (a) { return ~a.toLowerCase().indexOf(value.toLowerCase()) && (key = a); }); } } that.list.innerHTML = key ? datalist[key].map(function (a) { return ''<option data-value="'' + (a.value || a) + ''">'' + value + (value === key ? '''' : SEPARATOR + key) + SEPARATOR + (a.text || a) + ''</option>''; }).join() : ''''; updateInput(that); that.lastValue = value; } } function updateInput(that) { var value = that.value, pos = value.lastIndexOf(SEPARATOR), start = that.selectionStart, end = that.selectionEnd; if (~pos) { value = value.slice(pos + SEPARATOR.length); } Object.keys(that.list.options).some(function (option) { var o = that.list.options[option], p = o.text.lastIndexOf(SEPARATOR); if (o.text.slice(p + SEPARATOR.length) === value) { value = o.getAttribute(''data-value''); return true; } }); that.value = value; that.setSelectionRange(start, end); } document.getElementsByTagName(''input'').xx.addEventListener(''keyup'', function (e) { updateList(this); }); document.getElementsByTagName(''input'').xx.addEventListener(''input'', function (e) { updateInput(this); });

<input list="xxx" name="xx" id="xx"> <datalist id="xxx" type="text"></datalist>