Actualmente, el <datalist>
elemento HTML5 es compatible con la mayoría de los principales navegadores (excepto Safari) y parece una forma interesante de agregar sugerencias a una entrada.
Sin embargo, parece haber algunas discrepancias entre la implementación del value
atributo y el texto interno en <option>
. Por ejemplo:
<input list="answers" name="answer">
<datalist id="answers">
<option value="42">The answer</option>
</datalist>
Esto se maneja de manera diferente por diferentes navegadores:
Chrome y Opera:
FireFox e IE 11:
Después de seleccionar uno, la entrada se llena con el valor y no con el texto interno. Solo quiero que el usuario vea el texto ("La respuesta") en el menú desplegable y en la entrada, pero pase el valor 42
al enviar, como lo select
haría.
¿Cómo puedo hacer que todos los navegadores tengan la lista desplegable que muestre las etiquetas (texto interno) de los <option>
correos electrónicos, pero envíen el value
atributo cuando se envíe el formulario?
fuente
value=""
debería tener prioridad sobre una cadena dentro de las etiquetas, siempre que haya unvalue=""
declarado. Entonces, la sugerencia sería hacer de "la respuesta" su atributo de valor.Respuestas:
Tenga en cuenta que
datalist
no es lo mismo que aselect
. Permite a los usuarios ingresar un valor personalizado que no está en la lista, y sería imposible obtener un valor alternativo para dicha entrada sin definirlo primero.Las posibles formas de manejar la entrada del usuario son enviar el valor ingresado como está, enviar un valor en blanco o evitar el envío. Esta respuesta maneja solo las dos primeras opciones.
Si desea no permitir la entrada del usuario por completo, tal vez
select
sea una mejor opción.Para mostrar solo el valor de texto de
option
en el menú desplegable, usamos el texto interno y omitimos elvalue
atributo. El valor real que queremos enviar se almacena en undata-value
atributo personalizado :Para enviar esto
data-value
tenemos que usar un<input type="hidden">
. En este caso, dejamos fuera laname="answer"
entrada normal y la movemos a la copia oculta.<input list="suggestionList" id="answerInput"> <datalist id="suggestionList"> <option data-value="42">The answer</option> </datalist> <input type="hidden" name="answer" id="answerInput-hidden">
De esta manera, cuando el texto en la entrada original cambia, podemos usar javascript para verificar si el texto también está presente en
datalist
y recuperar sudata-value
. Ese valor se inserta en la entrada oculta y se envía.document.querySelector('input[list]').addEventListener('input', function(e) { var input = e.target, list = input.getAttribute('list'), options = document.querySelectorAll('#' + list + ' option'), hiddenInput = document.getElementById(input.getAttribute('id') + '-hidden'), inputValue = input.value; hiddenInput.value = inputValue; for(var i = 0; i < options.length; i++) { var option = options[i]; if(option.innerText === inputValue) { hiddenInput.value = option.getAttribute('data-value'); break; } } });
La identificación
answer
yanswer-hidden
la entrada normal y oculta son necesarios para que el script sepa qué entrada pertenece a qué versión oculta. De esta manera, es posible tener varios correosinput
electrónicos en la misma página con uno o másdatalist
correos electrónicos que brinden sugerencias.Cualquier entrada de usuario se envía tal cual. Para enviar un valor vacío cuando la entrada del usuario no está presente en la lista de datos, cambie
hiddenInput.value = inputValue
ahiddenInput.value = ""
Ejemplos de trabajo de jsFiddle: JavaScript simple y jQuery
fuente
La solución que utilizo es la siguiente:
<input list="answers" id="answer"> <datalist id="answers"> <option data-value="42" value="The answer"> </datalist>
Luego acceda al valor que se enviará al servidor usando JavaScript como este:
var shownVal = document.getElementById("answer").value; var value2send = document.querySelector("#answers option[value='"+shownVal+"']").dataset.value;
Espero eso ayude.
fuente
input
elemento con atributodata-value="1"
. Luego escribí el siguiente bloque en los lugares donde se tomó y usó el valor:if (typeof $(this).attr('data-value') != 'undefined') { var id = $(this).attr('name'); val = $('#'+id).find('option[value="'+val+'"]').attr('data-value'); }
Me doy cuenta de que esto puede ser un poco tarde, pero me topé con esto y me preguntaba cómo manejar situaciones con múltiples valores idénticos, pero claves diferentes (según el comentario de bigbearzhu).
Así que modifiqué ligeramente la respuesta de Stephan Muller:
Un datalist con valores no únicos:
<input list="answers" name="answer" id="answerInput"> <datalist id="answers"> <option value="42">The answer</option> <option value="43">The answer</option> <option value="44">Another Answer</option> </datalist> <input type="hidden" name="answer" id="answerInput-hidden">
Cuando el usuario selecciona una opción, el navegador reemplaza
input.value
con elvalue
de ladatalist
opción en lugar delinnerText
.El siguiente código luego busca un
option
con esovalue
, lo empuja al campo oculto y lo reemplazainput.value
con elinnerText
.document.querySelector('#answerInput').addEventListener('input', function(e) { var input = e.target, list = input.getAttribute('list'), options = document.querySelectorAll('#' + list + ' option[value="'+input.value+'"]'), hiddenInput = document.getElementById(input.getAttribute('id') + '-hidden'); if (options.length > 0) { hiddenInput.value = input.value; input.value = options[0].innerText; } });
Como consecuencia, el usuario ve lo que
innerText
dice la opción , pero la identificación única deoption.value
está disponible al enviar el formulario. Demostración jsFiddlefuente
Al hacer clic en el botón de búsqueda, puede encontrarlo sin un bucle.
Simplemente agregue a la opción un atributo con el valor que necesita (me gusta
id
) y búsquelo específico.$('#search_wrapper button').on('click', function(){ console.log($('option[value="'+ $('#autocomplete_input').val() +'"]').data('value')); })
fuente
Usando PHP he encontrado una forma bastante simple de hacer esto. Chicos, usen algo como esto
<input list="customers" name="customer_id" required class="form-control" placeholder="Customer Name"> <datalist id="customers"> <?php $querySnamex = "SELECT * FROM `customer` WHERE fname!='' AND lname!='' order by customer_id ASC"; $resultSnamex = mysqli_query($con,$querySnamex) or die(mysql_error()); while ($row_this = mysqli_fetch_array($resultSnamex)) { echo '<option data-value="'.$row_this['customer_id'].'">'.$row_this['fname'].' '.$row_this['lname'].'</option> <input type="hidden" name="customer_id_real" value="'.$row_this['customer_id'].'" id="answerInput-hidden">'; } ?> </datalist>
El código de arriba permite que el formulario lleve la identificación de la opción también seleccionada.
fuente
customer_id_real
enviado, no el valor seleccionado.