(我无法找到它,但我又不知道如何搜索它。)
我想使用<input list=xxx>
和<datalist id=xxx>
来获取自动完成功能,但我希望浏览器能够匹配所有选项,包含&#39;方法,而不是以&#39;开始,这似乎是标准的。有办法吗?
如果不是简单,有没有办法强制显示我想要显示的建议,而不是浏览器匹配的建议?让我们说我打字&#34; foo&#34;我想展示选项&#34; bar&#34;和&#34; baz&#34;。我可以强迫用户使用吗?如果我只是用那些(用JS)填充datalist,浏览器仍然会以&#39;开头。检查并过滤掉它们。
我希望最终控制数据主义选项如何显示。不要超过它的UI,灵活性,可访问性等,所以我不想完全重新制作它。甚至不建议使用jQuery插件。
如果我能最终控制表单元素验证,为什么不自动完成,对吧?
编辑:我现在看到Firefox确实使用了&#39;包含&#39;方法......那甚至不是标准?有什么方法可以强迫这个?我可以改变Firefox的方式吗?
编辑:我这样做是为了说明我的喜好:http://jsfiddle.net/rudiedirkx/r3jbfpxw/
答案 0 :(得分:14)
'包含'方法
也许这就是你要找的东西(问题的第一部分)。
它符合“开始于”的限制,并在进行选择时发生变化。
'use strict';
function updateList(that) {
if (!that) {
return;
}
var lastValue = that.lastValue,
value = that.value,
array = [],
pos = value.indexOf('|'),
start = that.selectionStart,
end = that.selectionEnd,
options;
if (that.options) {
options = that.options;
} else {
options = Object.keys(that.list.options).map(function (option) {
return that.list.options[option].value;
});
that.options = options;
}
if (lastValue !== value) {
that.list.innerHTML = options.filter(function (a) {
return ~a.toLowerCase().indexOf(value.toLowerCase());
}).map(function (a) {
return '<option value="' + value + '|' + a + '">' + a + '</option>';
}).join();
updateInput(that);
that.lastValue = value;
}
}
function updateInput(that) {
if (!that) {
return;
}
var value = that.value,
pos = value.indexOf('|'),
start = that.selectionStart,
end = that.selectionEnd;
if (~pos) {
value = value.slice(pos + 1);
}
that.value = value;
that.setSelectionRange(start, end);
}
document.getElementsByTagName('input').browser.addEventListener('keyup', function (e) {
updateList(this);
});
document.getElementsByTagName('input').browser.addEventListener('input', function (e) {
updateInput(this);
});
<input list="browsers" name="browser" id="browser" onkeyup="updateList();" oninput="updateInput();">
<datalist id="browsers">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>
修改
显示搜索内容的不同方法,以明确,发生了什么。这也适用于Chrome。灵感来自Show datalist labels but submit the actual value
'use strict';
var datalist = {
r: ['ralph', 'ronny', 'rudie'],
ru: ['rudie', 'rutte', 'rudiedirkx'],
rud: ['rudie', 'rudiedirkx'],
rudi: ['rudie'],
rudo: ['rudolf'],
foo: [
{ value: 42, text: 'The answer' },
{ value: 1337, text: 'Elite' },
{ value: 69, text: 'Dirty' },
{ value: 3.14, text: 'Pi' }
]
},
SEPARATOR = ' > ';
function updateList(that) {
var lastValue = that.lastValue,
value = that.value,
array,
key,
pos = value.indexOf('|'),
start = that.selectionStart,
end = that.selectionEnd;
if (lastValue !== value) {
if (value !== '') {
if (value in datalist) {
key = value;
} else {
Object.keys(datalist).some(function (a) {
return ~a.toLowerCase().indexOf(value.toLowerCase()) && (key = a);
});
}
}
that.list.innerHTML = key ? datalist[key].map(function (a) {
return '<option data-value="' + (a.value || a) + '">' + value + (value === key ? '' : SEPARATOR + key) + SEPARATOR + (a.text || a) + '</option>';
}).join() : '';
updateInput(that);
that.lastValue = value;
}
}
function updateInput(that) {
var value = that.value,
pos = value.lastIndexOf(SEPARATOR),
start = that.selectionStart,
end = that.selectionEnd;
if (~pos) {
value = value.slice(pos + SEPARATOR.length);
}
Object.keys(that.list.options).some(function (option) {
var o = that.list.options[option],
p = o.text.lastIndexOf(SEPARATOR);
if (o.text.slice(p + SEPARATOR.length) === value) {
value = o.getAttribute('data-value');
return true;
}
});
that.value = value;
that.setSelectionRange(start, end);
}
document.getElementsByTagName('input').xx.addEventListener('keyup', function (e) {
updateList(this);
});
document.getElementsByTagName('input').xx.addEventListener('input', function (e) {
updateInput(this);
});
<input list="xxx" name="xx" id="xx">
<datalist id="xxx" type="text"></datalist>
答案 1 :(得分:3)
但这个帖子大约在2年前发布。但是如果你正在阅读这个帖子,你可能需要查看更新版本的浏览器:
当前规范:https://html.spec.whatwg.org/multipage/forms.html#the-list-attribute
鼓励用户代理过滤由此表示的建议 建议数量时的建议源元素 大,包括最相关的(例如基于用户的 输入到目前为止)。没有定义精确的阈值,但限制了列表 四到七个值是合理的。如果基于过滤 用户的输入,用户代理应使用子串匹配 建议&#39;标签和价值。
写这篇文章后,Firefox(51)和Chrome(56)的行为已经改变,以符合规范。
这意味着操作系统现在应该正常工作。
答案 2 :(得分:1)
这fiddle here已经破解了你要求的东西 但我不知道如何在没有这种依赖性的情况下使其工作,因为当与Bootstrap一起使用时,UI看起来有点奇怪而且不合适。
(* an infinite stream of natural numbers, starting from 0 *)
let nats =
let rec nats_from n = [< 'n; nats_from (n + 1) >] (* extra syntax *)
in nats_from 0
(* the first n natural numbers: [0; n-1] *)
let range n = Stream.npeek n nats
答案 3 :(得分:0)
我找到了这个问题,是因为我想要“以……开头”的行为,现在所有的浏览器似乎都实现了“包含”。因此,我实现了此功能,在Firefox(可能还有其他)上,如果从输入事件处理程序(以及可选地从focusin事件处理程序)中调用该功能,则会提供“开头为”的行为。
let wrdlimit = prefix =>
{ let elm = mydatalist.firstElementChild;
while( elm )
{ if( elm.value.startsWith( prefix ))
{ elm.removeAttribute('disabled');
} else
{ elm.setAttribute('disabled', true );
}
elm = elm.nextElementSibling;
}
}