显示数据列表标签但提交实际值
Show datalist labels but submit the actual value
目前大多数主流浏览器(Safari 除外)都支持 HTML5 <datalist>
元素,这似乎是一种向输入添加建议的有趣方式。
但是,value
属性的实现与 <option>
的内部文本之间似乎存在一些差异。例如:
<input list="answers" name="answer">
<datalist id="answers">
<option value="42">The answer</option>
</datalist>
不同浏览器的处理方式不同:
Chrome 和歌剧:
FireFox 和 IE 11:
选择一个后,输入填充的是值而不是内部文本。我只希望用户在下拉列表和输入中看到文本 ("The answer"),但在提交时传递值 42
,就像 select
那样。
如何让所有浏览器的下拉列表显示 <option>
的标签(内部文本),但在提交表单时发送 value
属性?
请注意 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 answer
和 answer-hidden
才能知道哪个输入属于哪个隐藏版本。这样就可以在同一页面上有多个 input
,其中一个或多个 datalist
提供建议。
任何用户输入均按原样提交。要在数据列表中不存在用户输入时提交空值,请将 hiddenInput.value = inputValue
更改为 hiddenInput.value = ""
工作 jsFiddle 示例:plain javascript and jQuery
我使用的解决方案如下:
<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'));
})
我意识到这可能有点晚了,但我偶然发现了这一点,想知道如何处理具有多个相同值但不同键的情况(根据 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">
当用户选择一个选项时,浏览器会将 input.value
替换为 datalist
选项的 value
而不是 innerText
。
下面的代码然后用 value
检查 option
,将其推入隐藏字段并将 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
显示的任何内容,但来自 option.value
的唯一 ID 在表单提交时可用。
Demo jsFiddle
获取 text() 而不是 val() 尝试:
$("#datalistid option[value='" + $('#inputid').val() + "']").text();
目前大多数主流浏览器(Safari 除外)都支持 HTML5 <datalist>
元素,这似乎是一种向输入添加建议的有趣方式。
但是,value
属性的实现与 <option>
的内部文本之间似乎存在一些差异。例如:
<input list="answers" name="answer">
<datalist id="answers">
<option value="42">The answer</option>
</datalist>
不同浏览器的处理方式不同:
Chrome 和歌剧:
FireFox 和 IE 11:
选择一个后,输入填充的是值而不是内部文本。我只希望用户在下拉列表和输入中看到文本 ("The answer"),但在提交时传递值 42
,就像 select
那样。
如何让所有浏览器的下拉列表显示 <option>
的标签(内部文本),但在提交表单时发送 value
属性?
请注意 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 answer
和 answer-hidden
才能知道哪个输入属于哪个隐藏版本。这样就可以在同一页面上有多个 input
,其中一个或多个 datalist
提供建议。
任何用户输入均按原样提交。要在数据列表中不存在用户输入时提交空值,请将 hiddenInput.value = inputValue
更改为 hiddenInput.value = ""
工作 jsFiddle 示例:plain javascript and jQuery
我使用的解决方案如下:
<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'));
})
我意识到这可能有点晚了,但我偶然发现了这一点,想知道如何处理具有多个相同值但不同键的情况(根据 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">
当用户选择一个选项时,浏览器会将 input.value
替换为 datalist
选项的 value
而不是 innerText
。
下面的代码然后用 value
检查 option
,将其推入隐藏字段并将 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
显示的任何内容,但来自 option.value
的唯一 ID 在表单提交时可用。
Demo jsFiddle
获取 text() 而不是 val() 尝试:
$("#datalistid option[value='" + $('#inputid').val() + "']").text();