显示datalist标签,但提交实际值

目前,大多数主stream浏览器(Safari除外)都支持HTML5 <datalist>元素,这似乎是向input添加build议的有趣方式。

但是, value属性的实现和<option>的内部文本之间似乎有一些差异。 例如:

 <input list="answers" name="answer"> <datalist id="answers"> <option value="42">The answer</option> </datalist> 

这由不同的浏览器处理不同:

Chrome和Opera:
Chrome / Opera中的Datalist

FireFox和IE 11:
数据在FireFox中

select一个之后,input将填充值而不是内部文本。 我只希望用户在下拉菜单和input框中看到文本(“答案”),但是在提交时传递值42 ,就像select一样。

我怎样才能使所有的浏览器有下拉列表显示<option>的标签(内部文本),但发送表单提交时的value属性?

请注意, datalistselect 。 它允许用户input一个不在列表中的自定义值,如果不先定义这个input,就不可能获取这个input的替代值。

处理用户input的可能方法是按原样提交input的值,提交一个空白值或防止提交。 这个答案只处理前两个选项。

如果你想完全禁止用户input,也许select将是一个更好的select。


要在下拉列表中只显示option的文本值,我们使用它的内部文本并省略value属性。 我们想要发送的实际值存储在一个自定义data-value属性中:

要提交这个data-value我们必须使用<input type="hidden"> 。 在这种情况下,我们在常规input上省略name="answer" ,并将其移至隐藏的副本。

 <input list="suggestionList" id="answerInput"> <datalist id="suggestionList"> <option data-value="42" >The answer</option> </datalist> <input type="hidden" name="answer" id="answerInput-hidden"> 

这样,当原始input中的文本发生变化时,我们可以使用javascript来检查文本是否存在于datalist并获取其data-value 。 该值被插入到隐藏的input并提交。

 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.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; } } }); 

标准answeranswer-hidden在常规和隐藏的input是脚本需要知道哪个input属于哪个隐藏的版本。 通过这种方式,可以在同一页面上有多个input ,并且有一个或多个datalist提供build议。

任何用户input都按原样提交。 要在数据列表中不存在用户input时提交一个空值, hiddenInput.value = label更改为hiddenInput.value = ""


工作jsFiddle的例子: 纯javascript和jQuery

我使用的解决scheme是

 <input list="answers" id="answer"> <datalist id="answers"> <option data-value="42" value="The answer"> </datalist> 

通过javascript访问要发送到服务器的值

 var shownVal= document.getElementById("answer").value; var value2send=document.querySelector("#answers option[value='"+shownVal+"']").dataset.value; 

希望它有帮助