126

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

但是,该value属性的实现与<option>. 例如:

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

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

铬和歌剧:
Chrome/Opera 中的数据列表

火狐和 IE 11:
FireFox 中的数据列表

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

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

4

6 回答 6

142

请注意,datalist这与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">

这样,当原始输入中的文本发生更改时,我们可以使用 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;
        }
    }
});

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

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


工作 jsFiddle 示例:纯 javascriptjQuery

于 2015-04-26T19:36:59.767 回答
62

我使用的解决方案如下:

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


希望能帮助到你。

于 2016-05-09T12:45:55.537 回答
9

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

所以我稍微修改了斯蒂芬穆勒的答案:

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

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

当用户选择一个选项时,浏览器将替换input.value为该选项的valuedatalist而不是innerText.

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

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

});

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

于 2020-04-20T17:51:32.390 回答
1

单击搜索按钮时,您可以在没有循环的情况下找到它。
只需在选项中添加一个具有您需要的值的属性(如id)并搜索它。

$('#search_wrapper button').on('click', function(){
console.log($('option[value="'+ 
$('#autocomplete_input').val() +'"]').data('value'));
})
于 2019-04-23T09:29:42.350 回答
0

获取text()而不是val()尝试:

$("#datalistid option[value='" + $('#inputid').val() + "']").text();
于 2021-05-11T08:07:39.253 回答
-15

使用 PHP,我发现了一种非常简单的方法来做到这一点。伙计们,就用这样的东西

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

上面的代码让表单携带也选择的选项的 id。

于 2018-06-25T11:34:24.313 回答