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

Ste*_*ler 73 html javascript html5 cross-browser html-datalist

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

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

<input list="answers" name="answer">
<datalist id="answers">
  <option value="42">The answer</option>
</datalist>
Run Code Online (Sandbox Code Playgroud)

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

Chrome和Opera:
Chrome/Opera中的Datalist

FireFox和IE 11:
FireFox中的Datalist

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

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

Ste*_*ler 90

注意datalist与a不同select.它允许用户输入不在列表中的自定义值,如果不首先定义,则无法为此类输入获取备用值.

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

如果你想完全禁止用户输入,也许select是更好的选择.


要仅显示option下拉列表中的文本值,我们将使用内部文本并省略该value属性.我们要发送的实际值存储在自定义data-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">
Run Code Online (Sandbox Code Playgroud)

这样,当原始输入中的文本发生变化时,我们可以使用javascript来检查文本是否也存在于其中datalist并获取其中data-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;
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

脚本需要id answeranswer-hidden常规输入和隐藏输入才能知道哪个输入属于哪个隐藏版本.这样,可以input在同一页面上具有多个s,其中一个或多个datalists提供建议.

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


使用jsFiddle示例:简单的javascriptjQuery

  • 您将如何处理具有相同内部文本但不同数据值的选项?例如 http://jsfiddle.net/7k3sovht/78/ (2认同)
  • 据我所知,没有办法区分这两个选项。因为没有可供监听的用户事件,所以不可能知道他们实际选择了两个中的哪一个;我们所知道的是输入字段中最终的值是什么。 (2认同)

小智 33

我使用的解决方案是

<input list="answers" id="answer">
<datalist id="answers">
  <option data-value="42" value="The answer">
</datalist>
Run Code Online (Sandbox Code Playgroud)

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

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

希望能帮助到你

  • 但是,如果您有两个具有不同数据值的等于标题怎么办 (5认同)

小智 7

我意识到这可能有点晚了,但我偶然发现了这一点,并想知道如何处理具有多个相同值但不同键的情况(根据 bigbearzhu 的评论)。

所以我稍微修改了 Stephan Muller 的回答:

具有非唯一值的数据列表:

<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">
Run Code Online (Sandbox Code Playgroud)

当用户选择一个选项,浏览器内容替换input.valuevalue所述的datalist选项而不是innerText

下面的代码然后检查一个optionwith that value,将其推入隐藏字段并替换input.valueinnerText

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

});
Run Code Online (Sandbox Code Playgroud)

因此,用户会看到选项innerText所说的任何内容,但option.value表单提交时可以使用唯一的 id 。 演示 jsFiddle