<p:selectOneMenu caseSensitive="true"> 好像没什么效果

<p:selectOneMenu caseSensitive="true"> doesn't seem to have any effect

我有以下 select 一个菜单。但区分大小写在其中不起作用。当我按小 a 或大写 A 时,它总是显示小 a(以先出现的为准)。

        <p:selectOneMenu id="tempSelect" caseSensitive="true">
                        <f:selectItem itemLabel="0" itemValue="0"/>
                        <f:selectItem itemLabel="a" itemValue="a"/>
                        <f:selectItem itemLabel="A" itemValue="A"/>
                        <f:selectItem itemLabel="b" itemValue="b"/>
        </p:selectOneMenu>

我的 primefaces 版本是 5.2。

当 select 框处于焦点时。我按字母 "a" 或按大写字母 "A" ,在这两种情况下,它只在框中显示 "a" (因为它出现在列表的第一位)。这是实际行为。

我的预期行为是,当我按 "a" 时,它会输入 "a",当我按 "A" 时,它会在框中输入 "A"。

我该怎么办?

Primefaces 5.2 documentation(第 430 页)介绍了 CaseSensitive 选项:

Defines if filtering would be case sensitive.

因此,此选项仅在您使用 filter="true" 时适用,并且仅适用于您在筛选框中键入的值。

当您关注 SelectOneMenu 控件并输入一个值时,搜索将始终不区分大小写,如您在 source code of Primefaces (line 848) 中所见。请注意,在比较之前,文本以小写形式放置。

return $(this).text().toLowerCase().indexOf(text.toLowerCase()) === 0;

解决此问题的一种方法(不是很优雅)是覆盖负责此过滤器的 Primefaces 函数。请记住,在这种情况下,同一页面中的其他 SelectOneMenu 控件也将区分大小写。

所以848行会变成这样:

return $(this).text().indexOf(text) === 0;

可能应该考虑的另一个细节(如果您真的想覆盖该函数)是在 line 842 of source code 上,Primefaces 会丢弃所有具有 Shift 键的条目。

metaKey = e.metaKey||e.ctrlKey||e.shiftKey;

因此,这一行也应该像下面这样更改,以方便输入大写字母:

metaKey = e.metaKey||e.ctrlKey;

因此,考虑到这两个更改和 final version of Primefaces 5.2 (minified),解决方案是在 SelectOneMenu 之后的某处添加以下代码。

<script>
    PrimeFaces.widget.SelectOneMenu.prototype.bindKeyEvents = function() {
        var a = this;
        this.focusInput.on("keydown.ui-selectonemenu", function(d) {
            var c = $.ui.keyCode, b = d.which;
            switch (b) {
            case c.UP:
            case c.LEFT:
                a.highlightPrev(d);
                break;
            case c.DOWN:
            case c.RIGHT:
                a.highlightNext(d);
                break;
            case c.ENTER:
            case c.NUMPAD_ENTER:
                a.handleEnterKey(d);
                break;
            case c.TAB:
                a.handleTabKey();
                break;
            case c.ESCAPE:
                a.handleEscapeKey(d);
                break
            }
        }).on(
                "keyup.ui-selectonemenu",
                function(g) {
                    var f = $.ui.keyCode, d = g.which;
                    switch (d) {
                    case f.UP:
                    case f.LEFT:
                    case f.DOWN:
                    case f.RIGHT:
                    case f.ENTER:
                    case f.NUMPAD_ENTER:
                    case f.TAB:
                    case f.ESCAPE:
                    case f.SPACE:
                    case f.HOME:
                    case f.PAGE_DOWN:
                    case f.PAGE_UP:
                    case f.END:
                    case f.DELETE:
                    case 16:
                    case 17:
                    case 18:
                    case 224:
                        break;
                    default:
                        var i = $(this).val(), c = null, h = g.metaKey
                                || g.ctrlKey;
                        if (!h) {
                            clearTimeout(a.searchTimer);
                            c = a.options.filter(function() {
                                return $(this).text()
                                        .indexOf(i) === 0
                            });
                            if (c.length) {
                                var b = a.items.eq(c.index());
                                if (a.panel.is(":hidden")) {
                                    a.selectItem(b)
                                } else {
                                    a.highlightItem(b);
                                    PrimeFaces.scrollInView(
                                            a.itemsWrapper, b)
                                }
                            }
                            a.searchTimer = setTimeout(function() {
                                a.focusInput.val("")
                            }, 1000)
                        }
                        break
                    }
                })
    }
</script>

要进行测试,请记住在每次击键之间有 a timer of 1 second 以清除已输入字母的缓存并开始一个新单词。

虽然这不是完美的解决方案,但您可以使用此解决方法。 使用过滤器。这样你还需要一个 "click" 但它有效。

<p:selectOneMenu id="tempSelect" caseSensitive="true" filter="true" filterMatchMode="startsWith"> <f:selectItem itemLabel="0" itemValue="0"/> <f:selectItem itemLabel="a" itemValue="a"/> <f:selectItem itemLabel="A" itemValue="A"/> <f:selectItem itemLabel="b" itemValue="b"/> </p:selectOneMenu>