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

目前,大多数主流浏览器(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

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

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

154281 次浏览

请注意,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;
}
}
});

常规和隐藏输入上的 id answeranswer-hidden是脚本知道哪个输入属于哪个隐藏版本所必需的。这样就可以在同一个页面上有多个 input,同时有一个或多个 datalist提供建议。

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


工作 jsFiddle 示例: 普通的 javascriptJQuery

我使用的解决方案如下:

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


希望能有帮助。

使用 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。

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

$('#search_wrapper button').on('click', function(){
console.log($('option[value="'+
$('#autocomplete_input').val() +'"]').data('value'));
})

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

因此,我对斯蒂芬•穆勒(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">

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

然后,下面的代码用该 value检查 option,将其推入隐藏字段,并用 innerText替换 input.value

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所说的任何内容,但是在表单提交时可以看到来自 option.value的惟一 id。 演示 jsFiddle

Text ()代替 Val ()试试:

$("#datalistid option[value='" + $('#inputid').val() + "']").text();