显示数据列表标签但提交实际值

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

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

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

不同的浏览器以不同的方式处理:

Chrome 和 Opera:
Datalist in Chrome/Opera

FireFox 和 IE 11:
Datalist in FireFox

选择一个后,输入将填充值,而不是内部文本。我只希望用户在下拉列表和输入中看到文本(“答案”),但在提交时传递值,就像a一样。42select

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


答案 1

请注意,这与 不同。它允许用户输入不在列表中的自定义值,并且如果不先定义此类输入,就不可能获取此类输入的备用值。datalistselect

处理用户输入的可能方法是按原样提交输入的值、提交空白值或阻止提交。此答案仅处理前两个选项。

如果您想完全禁止用户输入,也许会是一个更好的选择。select


若要在下拉列表中仅显示 的文本值,我们为其使用内部文本并省略该属性。我们要发送的实际值存储在自定义属性中:optionvaluedata-value

要提交此内容,我们必须使用 .在这种情况下,我们省略了常规输入,并将其移动到隐藏副本。data-value<input type="hidden">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">

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

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

脚本需要 id 以及常规和隐藏输入,以便知道哪个输入属于哪个隐藏版本。这样,就可以在同一页面上有多个 s,其中一个或多个 s 提供建议。answeranswer-hiddeninputdatalist

任何用户输入都将按原样提交。要在数据列表中不存在用户输入时提交空值,请将hiddenInput.value = inputValuehiddenInput.value = ""


工作jsFiddle示例:普通javascriptjQuery


答案 2

我使用的解决方案如下:

<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;


希望它有帮助。