使用HTML5(DataList控件)自动完成与'包含'的做法,不只是“开头” [英] Use HTML5 (datalist) autocomplete with 'contains' approach, not just 'starts with'

查看:312
本文介绍了使用HTML5(DataList控件)自动完成与'包含'的做法,不只是“开头”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我无法找到它,但随后再次我真的不知道如何寻找它。)

我想用<输入列表= XXX> < D​​ataList控件ID = XXX> 来获得自动完成,但我想在浏览器中通过'包含'的方法匹配所有的选项,而不是'开头',这似乎是标准。有什么办法?

如果不是简单地说,就是有没有办法强制显示,我想说明的建议,而不是那些浏览器是否匹配?比方说,我打字富,我想显示选项栏和巴兹。我可以强制那些在用户?如果我只需填写与那些(与JS)DataList控件,浏览器仍然会尽自己的检查开头,并把它们过滤掉。

我想就如何在DataList选项显示的最终控制权。没过它的用户界面,灵活性,可访问性等,所以我并不想彻底改造它。甚至不建议一个jQuery插件。

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

编辑:我现在看到Firefox没有使用'包含'的方法......这甚至不是一个标准?任何方式强迫呢?我可以改变Firefox的方法是什么?

编辑:我做了这个说明想什么我:的http:/ /jsfiddle.net/rudiedirkx/r3jbfpxw/


解决方案

'包含'的方法

这也许是你在找什么(你的问题的一部分1)。

它跟的开头的限制和更改时做出选择。

\r
\r

使用严格的;\r
功能updateList(即){\r
    VAR lastValue = that.lastValue,\r
        值= that.value,\r
        数组= [],\r
        POS = value.indexOf('|'),\r
        开始= that.selectionStart,\r
        结束= that.selectionEnd,\r
        选择;\r
\r
    如果(that.options){\r
        选项​​= that.options;\r
    }其他{\r
        选项​​= Object.keys(that.list.options).MAP(功能(选件){\r
            返回that.list.options [选项] .value的;\r
        });\r
        that.options =选择;\r
    }\r
\r
    如果(lastValue!==值){\r
        that.list.innerHTML = options.filter(函数(){\r
            返回〜a.toLowerCase()的indexOf(value.toLowerCase())。\r
        })。图(函数(){\r
            回归'<期权价值=+值+'|' + A +'>' + A +'< /选项>';\r
        })。加入();\r
        updateInput(即)\r
        that.lastValue =价值;\r
    }\r
}\r
\r
功能updateInput(即){\r
    VAR值= that.value,\r
        POS = value.indexOf('|'),\r
        开始= that.selectionStart,\r
        最终= that.selectionEnd;\r
\r
    如果(POS〜){\r
        值= value.slice(POS + 1);\r
    }\r
    that.value =价值;\r
    that.setSelectionRange(开始,结束);\r
}\r
\r
document.getElementsByTagName('输入')。browser.addEventListener('KEYUP',函数(E){\r
    updateList(本);\r
});\r
document.getElementsByTagName('输入')。browser.addEventListener(输入,功能(E){\r
    updateInput(本);\r
});

\r

<输入列表=浏览器NAME =浏览器ID =浏览器的onkeyup =updateDatalist(); oninput =updateInput();>\r
< D​​ataList控件ID =浏览器>\r
    <期权价值=Internet Explorer的>\r
    <期权价值=火狐>\r
    <期权价值=铬>\r
    <期权价值=歌剧>\r
    <期权价值=野生动物园>\r
< / DataList控件>

\r

\r
\r

修改

显示搜索内容的不同的方法,要明确,会发生什么情况。这在Chrome的为好。由<一个启发href=\"http://stackoverflow.com/questions/29882361/show-datalist-labels-but-submit-the-actual-value\">Show DataList的标签,但提交的实际值

\r
\r

使用严格的;\r
VAR的DataList = {\r
        R:['拉尔夫','罗尼','rudie'],\r
        る:['rudie','鲁特','rudiedirkx'],\r
        RUD:['rudie','rudiedirkx'],\r
        鲁迪:['rudie'],\r
        鲁多:鲁道夫'],\r
        富:\r
            {值:42,文本:答案},\r
            {值:1337,文本:精英},\r
            {值:69,文本:脏},\r
            {值:3.14,文本:'皮'}\r
        ]\r
    },\r
    分离器='&GT; ';\r
\r
功能updateList(即){\r
    VAR lastValue = that.lastValue,\r
        值= that.value,\r
        阵,\r
        键,\r
        POS = value.indexOf('|'),\r
        开始= that.selectionStart,\r
        最终= that.selectionEnd;\r
\r
    如果(lastValue!==值){\r
        如果(值!==''){\r
            如果(在DataList控件的值){\r
                键=值;\r
            }其他{\r
                Object.keys(DataList控件)。有些(函数(){\r
                    返回〜a.toLowerCase()的indexOf(value.toLowerCase())及。&放大器; (键= A);\r
                });\r
            }\r
        }\r
        that.list.innerHTML =钥匙? DataList控件[关键] .MAP(函数(){\r
            回归'&LT;选项数据值='+(a.value中|| A)+'&GT;' +价值+(价值​​===键'?':分隔符+键)+分离器+(a.text || A)+'&LT; /选项&GT;';\r
        })join()方法:'';\r
        updateInput(即)\r
        that.lastValue =价值;\r
    }\r
}\r
\r
功能updateInput(即){\r
    VAR值= that.value,\r
        POS = value.lastIndexOf(分隔符),\r
        开始= that.selectionStart,\r
        最终= that.selectionEnd;\r
\r
    如果(POS〜){\r
        值= value.slice(POS + SEPARATOR.length);\r
    }\r
    Object.keys(that.list.options)。有些(功能(选件){\r
        变种O = that.list.options [选项]\r
            P = o.text.lastIndexOf(分隔符);\r
        如果(o.text.slice(P + SEPARATOR.length)===值){\r
            值= o.getAttribute('数据值');\r
            返回true;\r
        }\r
    });\r
    that.value =价值;\r
    that.setSelectionRange(开始,结束);\r
}\r
\r
document.getElementsByTagName('输入')。xx.addEventListener('KEYUP',函数(E){\r
    updateList(本);\r
});\r
document.getElementsByTagName('输入')。xx.addEventListener(输入,功能(E){\r
    updateInput(本);\r
});

\r

&LT;输入列表=XXXNAME =XXID =XX &GT;\r
&LT; D​​ataList控件ID =XXX类型=文本&GT;&LT; / DataList控件&GT;

\r

\r
\r

(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) {
    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) {
    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="updateDatalist();" 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(DataList控件)自动完成与'包含'的做法,不只是“开头”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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