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

IT技术 javascript html cross-browser html-datalist
2021-01-22 14:40:48

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

但是,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提交表单时发送属性?

6个回答

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

@StephanMuller 感谢分享,非常有用,我正在按照您的编码运行,但是我仅在输入中使用退格键时获得数据值,而不是在提交或什至选择不同的项目时,有什么问题?
2021-03-13 14:40:48
您将如何处理具有相同内部文本但不同数据值的选项?例如jsfiddle.net/7k3sovht/78
2021-03-22 14:40:48
纯 jquery document.querySelector('input[list]').addEventListener('input', function(e) { var value = $(this).val(); var list = $(this).attr('list' ); var id = $(this).attr('id'); $('#'+list+' option').each(function(){ if($(this).val() == value){ $('#'+id+'-hidden').val($(this).attr('data-value')); } }); });
2021-03-25 14:40:48
@StephanMuller 对于像我这样正在学习更多 HTML5 的人来说很好的答案,谢谢!提交后如何清除演示的文本框?
2021-04-05 14:40:48
据我所知,没有办法区分这两个选项。因为没有用户事件要收听,所以不可能知道他们实际选择了两个中的哪一个;我们只知道输入字段中的值是什么。
2021-04-11 14:40:48

我使用的解决方案如下:

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


希望能帮助到你。

谢谢真主党沙阿,你真的节省了很多时间
2021-03-12 14:40:48
但是如果你有两个具有不同数据值的相等标题怎么办
2021-03-13 14:40:48
这个解决方案真是个好主意!- 我能够在几分钟内简单地实施这个解决方案。首先,我input用属性更新了我的元素data-value="1"然后我在值被抓取和使用的地方写了以下块:if (typeof $(this).attr('data-value') != 'undefined') { var id = $(this).attr('name'); val = $('#'+id).find('option[value="'+val+'"]').attr('data-value'); }
2021-03-24 14:40:48
在每个步骤中使用 console.log 进行故障排除。确保您使用的是您正在调用的相同 id 值。并检查分号。
2021-03-27 14:40:48
我有任何原因未定义吗?
2021-04-10 14:40:48

我意识到这可能有点晚了,但我偶然发现了这一点,并想知道如何处理具有多个相同值但不同键的情况(根据 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.valuevalue所述的datalist选项而不是innerText

然后将以下代码用于检查option与该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;
      }

});

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

不错的补充:)
2021-04-02 14:40:48

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

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

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

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