设置隐藏的数据列表选项值 [英] Setting hidden datalist option values

查看:202
本文介绍了设置隐藏的数据列表选项值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码段中,我有两种选择项目的方法:带数据列表的输入和带选项的传统选择.

select元素使选项值保持隐藏,我们仍然可以通过this.value来获取它.但是,使用数据列表时,实际上会显示该值,并且该选项的文本内容将显示为辅助标签.

我想要的是让input + datalist方法的行为像传统的select一样,其中"Foo"和"Bar"显示为选择时分别具有"1"和"2"值的选项./p>

我还添加了一个重复的名称"Foo",其值为"3".这表明任何解决方案都不得依赖唯一选项.

 <input list="options" onchange="console.log(this.value)"/>
<datalist id="options">
  <option value="1">Foo</option>
  <option value="2">Bar</option>
  <option value="3">Foo</option>
</datalist>

<select onchange="console.log(this.value)">
  <option value=""></option>
  <option value="1">Foo</option>
  <option value="2">Bar</option>
  <option value="3">Foo</option>
</select> 

解决方案

没有本地方法.对于 input 元素代表单行纯文本编辑 控件的元素.

因此,不可能使文本输入显示的某些文本与其值不同.

您可以在HTMLInputElement.prototype中劫持value吸气剂,但是我不建议这样做,而且如果值不是唯一的,我也看不出任何方法来知道选择哪个选项.

 var des = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
Object.defineProperty(HTMLInputElement.prototype, 'value', { get: function() {
  if(this.type === 'text' && this.list) {
    var value = des.get.call(this);
    var opt = [].find.call(this.list.options, function(option) {
      return option.value === value;
    });
    return opt ? opt.dataset.value : value;
  }
}}); 

 <input list="options" oninput="console.log(this.value);" />
<datalist id="options">
  <option data-value="1">Foo</option>
  <option data-value="2">Bar</option>
  <option data-value="3">Foo</option>
</datalist> 

或者也许您可以让输入显示选项的值而不是文本,但立即将其替换:

 var inp = document.querySelector('input');
inp.addEventListener('input', function() {
  var value = this.value;
  var opt = [].find.call(this.list.options, function(option) {
    return option.value === value;
  });
  if(opt) {
    this.value = opt.textContent;
  }
}); 

 <input list="options" oninput="console.log(this.value);" />
<datalist id="options">
  <option value="1">Foo</option>
  <option value="2">Bar</option>
  <option value="3">Foo</option>
</datalist> 

在第二个示例中,oninput="console.log(this.value)"显示该选项的值,因为该代码在将值替换为文本内容之前运行.如果您希望以后的.value加入物返回选项值,则需要像第一个示例一样劫持value吸气剂.

In the snippet below, I have two methods to choose an item: input with datalist and traditional select with options.

The select element keeps the option values hidden, and we're still able to get it with this.value. However, with the datalist, the value is actually displayed and the text content of the option is displayed as a secondary label.

What I'd like is to have the input+datalist approach behave like a traditional select, where "Foo" and "Bar" are shown as options that when selected have values of "1" and "2" respectively.

I've also added a repeated name "Foo" with value "3". This is to show that any solution must not depend on unique options.

<input list="options" onchange="console.log(this.value)"/>
<datalist id="options">
  <option value="1">Foo</option>
  <option value="2">Bar</option>
  <option value="3">Foo</option>
</datalist>

<select onchange="console.log(this.value)">
  <option value=""></option>
  <option value="1">Foo</option>
  <option value="2">Bar</option>
  <option value="3">Foo</option>
</select>

解决方案

There is no native way. For text inputs

The input element represents a one line plain text edit control for the element's value.

So it's not possible to make a text input display some text different than its value.

You could hijack the value getter in HTMLInputElement.prototype, but I don't recommend it, and I don't see any way to know which option was chosen if the values are not unique.

var des = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
Object.defineProperty(HTMLInputElement.prototype, 'value', { get: function() {
  if(this.type === 'text' && this.list) {
    var value = des.get.call(this);
    var opt = [].find.call(this.list.options, function(option) {
      return option.value === value;
    });
    return opt ? opt.dataset.value : value;
  }
}});

<input list="options" oninput="console.log(this.value);" />
<datalist id="options">
  <option data-value="1">Foo</option>
  <option data-value="2">Bar</option>
  <option data-value="3">Foo</option>
</datalist>

Or maybe you can let the input show the value of the option instead of the text, but replace it immediately:

var inp = document.querySelector('input');
inp.addEventListener('input', function() {
  var value = this.value;
  var opt = [].find.call(this.list.options, function(option) {
    return option.value === value;
  });
  if(opt) {
    this.value = opt.textContent;
  }
});

<input list="options" oninput="console.log(this.value);" />
<datalist id="options">
  <option value="1">Foo</option>
  <option value="2">Bar</option>
  <option value="3">Foo</option>
</datalist>

In the second example, oninput="console.log(this.value)" shows the value of the option because that code runs before replacing the value to the text content. If you want later .value accessions to return the option value, you will need to hijack the value getter like in the first example.

这篇关于设置隐藏的数据列表选项值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆