使用带有“包含"方法的 HTML5(数据列表)自动完成,而不仅仅是“开始于" [英] Use HTML5 (datalist) autocomplete with 'contains' approach, not just 'starts with'

查看:23
本文介绍了使用带有“包含"方法的 HTML5(数据列表)自动完成,而不仅仅是“开始于"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我找不到它,但我真的不知道如何搜索它.)

我想使用 来获得自动完成功能,但我希望浏览器通过以下方式匹配所有选项包含"方法,而不是开始于",这似乎是标准的.有办法吗?

如果不是简单的话,有没有办法强制显示我想要显示的建议,而不是浏览器匹配的建议?假设我正在输入foo"并且我想显示选项bar"和baz".我可以将这些强加给用户吗?如果我只是用那些(用 JS)填充数据列表,浏览器仍然会做它的开始于"检查,并将它们过滤掉.

我想要最终控制数据列表选项的显示方式.不在于它的 UI、灵活性、可访问性等,所以我不想完全重新制作它.甚至不建议使用 jQuery 插件.

如果我可以最终控制表单元素验证,为什么不能自动完成,对吗?

我现在看到 Firefox 确实使用包含"方法......这甚至不是标准??有什么办法强制这个吗?我可以改变 Firefox 的方式吗?

我这样做是为了说明我想要什么:http://jsfiddle.net/rudiedirkx/r3jbfpxw/

解决方案

'包含'方法

也许这就是您要找的东西(问题的第 1 部分).

它符合开始于"的限制,并在做出选择时发生变化.

'use strict';函数 updateList(that) {如果说) {返回;}var lastValue = that.lastValue,价值=那个.价值,数组 = [],pos = value.indexOf('|'),开始 = that.selectionStart,end = that.selectionEnd,选项;如果(that.options){选项 = that.options;} 别的 {options = Object.keys(that.list.options).map(function (option) {返回 that.list.options[option].value;});that.options = 选项;}如果(最后一个值!== 值){that.list.innerHTML = options.filter(function (a) {返回 ~a.toLowerCase().indexOf(value.toLowerCase());}).map(函数(a){return '<option value="' + value + '|'+ a + '">'+ a + '</option>';}).加入();更新输入(那个);that.lastValue = 值;}}函数更新输入(那个){如果说) {返回;}var value = that.value,pos = value.indexOf('|'),开始 = that.selectionStart,end = that.selectionEnd;如果(~位置){value = value.slice(pos + 1);}that.value = 值;that.setSelectionRange(start, end);}document.getElementsByTagName('input').browser.addEventListener('keyup', function (e) {更新列表(这个);});document.getElementsByTagName('input').browser.addEventListener('input', function (e) {更新输入(这个);});

<input list="browsers" name="browser" id="browser" onkeyup="updateList();"oninput="updateInput();"><datalist id="浏览器"><option value="Internet Explorer"><option value="火狐"><option value="Chrome"><option value="Opera"><option value="Safari"></datalist>

编辑

显示搜索内容的不同方法,以明确会发生什么.这也适用于 Chrome.灵感来自 显示数据列表标签但提交实际值>

 'use strict';var 数据列表 = {r: ['ralph', 'ronny', 'rudie'],ru: ['rudie', 'rutte', 'rudiedirkx'],rud: ['rudie', 'rudiedirkx'],鲁迪:['鲁迪'],鲁多:['鲁道夫'],富:[{ value: 42, text: '答案' },{值:1337,文本:'精英'},{ 值:69,文本:'脏'},{ 值:3.14,文本:'Pi' }]},分隔符 = ' >';函数 updateList(that) {var lastValue = that.lastValue,价值=那个.价值,大批,钥匙,pos = value.indexOf('|'),开始 = that.selectionStart,end = that.selectionEnd;如果(最后一个值!== 值){如果(值!== ''){如果(数据列表中的值){键 = 值;} 别的 {Object.keys(datalist).some(function (a) {返回 ~a.toLowerCase().indexOf(value.toLowerCase()) &&(key = a);});}}that.list.innerHTML = 键?datalist[key].map(function (a) {return '

<datalist id="xxx" type="text"></datalist>

(I can't find it, but then again I don't really know how to search for it.)

I want to use <input list=xxx> and <datalist id=xxx> to get autocompletion, BUT I want the browser to match all options by 'contains' approach, instead of 'starts with', which seems to be standard. Is there a way?

If not simply, is there a way to force-show suggestions that I want to show, not those that the browser matched? Let's say I'm typing "foo" and I want to show options "bar" and "baz". Can I force those upon the user? If I just fill the datalist with those (with JS), the browser will still do its 'starts with' check, and filter them out.

I want ultimate control over HOW the datalist options show. NOT over its UI, flexibility, accessibility etc, so I don't want to completely remake it. Don't even suggest a jQuery plugin.

If I can ultimate-control form element validation, why not autocompletion, right?

edit: I see now that Firefox does use the 'contains' approach... That's not even a standard?? Any way to force this? Could I change Firefox's way?

edit: I made this to illustrate what I'd like: http://jsfiddle.net/rudiedirkx/r3jbfpxw/

解决方案

'contains' approach

Maybe this is what you are looking for (part 1 of your question).

It goes with the limitation of "starts with" and changes when a selection is made.

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

Edit

A different approach of displaying the search content, to make clear, what happens. This works in Chrome as well. Inspired by 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>

这篇关于使用带有“包含"方法的 HTML5(数据列表)自动完成,而不仅仅是“开始于"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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