Atualmente, o <datalist>
elemento HTML5 é compatível com a maioria dos navegadores principais (exceto Safari) e parece uma maneira interessante de adicionar sugestões a uma entrada.
No entanto, parece haver algumas discrepâncias entre a implementação do value
atributo e o texto interno no <option>
. Por exemplo:
<input list="answers" name="answer">
<datalist id="answers">
<option value="42">The answer</option>
</datalist>
Isso é tratado de forma diferente por navegadores diferentes:
Chrome e Opera:
FireFox e IE 11:
Depois de selecionar um, a entrada é preenchida com o valor e não com o texto interno. Só quero que o usuário veja o texto ("A resposta") no menu suspenso e na entrada, mas transmita o valor 42
ao enviar, como select
faria.
Como posso fazer com que todos os navegadores tenham a lista suspensa mostrando os rótulos (texto interno) dos <option>
s, mas enviar o value
atributo quando o formulário for enviado?
fonte
value=""
deve ter precedência sobre uma string dentro das tags, sempre que houver umvalue=""
declarado. Portanto, a sugestão seria tornar "a resposta" seu atributo de valor.Respostas:
Observe que
datalist
não é o mesmo que aselect
. Ele permite que os usuários insiram um valor personalizado que não está na lista, e seria impossível buscar um valor alternativo para essa entrada sem defini-lo primeiro.As maneiras possíveis de lidar com a entrada do usuário são enviar o valor inserido como está, enviar um valor em branco ou evitar o envio. Essa resposta trata apenas das duas primeiras opções.
Se você deseja proibir totalmente a entrada do usuário, talvez
select
seja uma escolha melhor.Para mostrar apenas o valor de texto de
option
na lista suspensa, usamos o texto interno para ele e omitimos ovalue
atributo. O valor real que queremos enviar é armazenado em umdata-value
atributo personalizado :Para enviar
data-value
, temos que usar um<input type="hidden">
. Nesse caso, deixamos de fora oname="answer"
na entrada regular e o movemos para a cópia 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">
Desta forma, quando o texto na entrada original for alterado podemos usar javascript para verificar se o texto também está presente no
datalist
e buscar o seudata-value
. Esse valor é inserido na entrada oculta e enviado.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; } } });
O id
answer
eanswer-hidden
na entrada regular e oculta são necessários para o script saber qual entrada pertence a qual versão oculta. Desta forma, é possível ter váriosinput
s na mesma página com um ou maisdatalist
s fornecendo sugestões.Qualquer entrada do usuário é enviada como está. Para enviar um valor vazio quando a entrada do usuário não estiver presente no datalist, mude
hiddenInput.value = inputValue
parahiddenInput.value = ""
Exemplos de trabalho de jsFiddle: javascript simples e jQuery
fonte
A solução que uso é a seguinte:
<input list="answers" id="answer"> <datalist id="answers"> <option data-value="42" value="The answer"> </datalist>
Em seguida, acesse o valor a ser enviado ao servidor usando JavaScript da seguinte forma:
var shownVal = document.getElementById("answer").value; var value2send = document.querySelector("#answers option[value='"+shownVal+"']").dataset.value;
Espero que ajude.
fonte
input
elemento com o atributodata-value="1"
. Então escrevi o seguinte bloco nos locais onde o valor estava sendo pego e usado:if (typeof $(this).attr('data-value') != 'undefined') { var id = $(this).attr('name'); val = $('#'+id).find('option[value="'+val+'"]').attr('data-value'); }
Sei que pode ser um pouco tarde, mas me deparei com isso e queria saber como lidar com situações com vários valores idênticos, mas chaves diferentes (conforme o comentário de bigbearzhu).
Portanto, modifiquei ligeiramente a resposta de Stephan Muller:
Um datalist com valores não ú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">
Quando o usuário seleciona uma opção, o navegador o substitui
input.value
pelovalue
dadatalist
opção em vez doinnerText
.O código a seguir verifica a existência de um
option
com issovalue
, coloca-o no campo oculto e substitui oinput.value
com oinnerText
.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 consequência, o usuário vê o que quer que a opção
innerText
diga, mas o id exclusivo deoption.value
está disponível no envio do formulário. Demo jsFiddlefonte
Ao clicar no botão de pesquisa, você pode encontrá-lo sem um loop.
Basta adicionar à opção um atributo com o valor que você precisa (like
id
) e pesquisar por ele específico.$('#search_wrapper button').on('click', function(){ console.log($('option[value="'+ $('#autocomplete_input').val() +'"]').data('value')); })
fonte
Usando PHP, descobri uma maneira bastante simples de fazer isso. Pessoal, basta usar algo assim
<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>
O código acima permite que o formulário carregue o id da opção também selecionada.
fonte
customer_id_real
submetido, não o valor selecionado.