【问题标题】:How to set focus to autocomplete contents on inline edit in free jqgrid如何在免费 jqgrid 中将焦点设置为自动完成内容的内联编辑
【发布时间】:2023-03-05 06:43:01
【问题描述】:

免费 jqgrid 第一列是使用自定义编辑类型的 Jquery UI 自动完成。 使用 focusField: true 使字段可聚焦

$.extend(true,$.jgrid.inlineEdit, {
    position: "beforeSelected",
    focusField: true,
    keys: true } );

如果开始内联编辑,jqgrid 会将焦点放在自动完成下拉按钮上。 如何解决这个焦点放在自动完成输入元素上的问题?

自动完成按钮是用 tabindex=-1 定义的:

<button type='button' class='btn btn-default btn-form-dropdown' tabindex=-1 aria-label='Open menu'>
<span class='caret'></span></button>

如果在内联编辑中按下tab键,它不会获得焦点。

jqgrid代码包含:

    getFocusable = function (elem) {
        return $(elem).find("input,textarea,select,button,object,*[tabindex]")
                                            .filter(":input:visible:not(:disabled)");
                                },

所以 jqgrid 将焦点放在元素上,即使它包含 tabindex=-1

如何解决这个问题?

也发布在https://github.com/free-jqgrid/jqGrid/issues/186

更新

重现问题的步骤:

  1. 在 Chrome 中打开下面的页面
  2. 选择行
  3. 点击内嵌编辑按钮

观察到:

按钮获得焦点

预期:

输入元素应该获得焦点

要重现的代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/redmond/jquery-ui.css" />
    <link rel="stylesheet" href="http://rawgit.com/free-jqgrid/jqGrid/master/css/ui.jqgrid.css" type="text/css" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script>
    <script src="http://rawgit.com/free-jqgrid/jqGrid/master/js/jquery.jqgrid.src.js"></script>
    <script>
        $(document).ready(function () {
            var mydata = [
                { id: 0, Name: "Indiana", Category: "IN" },
                { id: 1, Name: "California", Category: "CA" },
                { id: 2, Name: "Pennsylvania", Category: "PA" },
                { id: 3, Name: "Texas", Category: "TX" }
            ];
            var lastSel;
            var grid = $("#list");

            grid.jqGrid({
                data: mydata,
                datatype: 'local',
                colModel: [
                    {
                        name: 'Name', editable: true, width: 200,
                        edittype: 'custom',
                        editoptions: {
                            custom_element: combobox_element,
                            custom_value: function (elem) {
                                return elem.find("input").val();
                            }
                        }
                    },

                { name: 'Category', index: 'Category', width: 50, editable: true }
                ],
                ignoreCase: true,
                gridview: true,
                viewrecords: true,
                rownumbers: true,
                pager: '#pager',
                editurl: 'clientArray',
                ondblClickRow: function (id, ri, ci) {
                    grid.jqGrid('editRow', id, true, null, null, 'clientArray', {});
                },
                onSelectRow: function (id) {
                    if (id && id !== lastSel) {
                        if (typeof lastSel !== "undefined") {
                            grid.jqGrid('restoreRow', lastSel);
                        }
                        lastSel = id;
                    }
                }
            }).
            jqGrid("inlineNav", '#pager');
        });

        var getColumnByName = function (grid, columnName) {
            var cm = grid.jqGrid('getGridParam', 'colModel'), i = 0, l = cm.length;
            for (; i < l; ++i) {
                if (cm[i].name === columnName) {
                    return cm[i];
                }
            }
            return null;
        };

        function combobox_element(value, options) {
            var elemStr = '<div><input class="FormElement', newel, width;
            if (options.id === options.name) {
                elemStr += '" size="' +
                        options.size + '"' + ' id="' + options.id + '"';
            }
            else {
                elemStr += ' form-control jqgrid-inlineedit-autocomplete" ' +
                   ' style="width:' + width + 'px" ' + ' id="' + options.id + '_x"';
            }
            elemStr += ' value="' + value + '" lookup="' + options.lookup + '"/>';
            elemStr += "<button type='button' class='btn btn-default btn-form-dropdown' tabindex=-1 aria-label='Open menu'>" +
        "<span class='caret'></span></button>";
            elemStr += '</div>';
            newel = $(elemStr)[0];
            setTimeout(function () {
                input_autocomplete(newel);
            }, 50);
            return newel;
        }

        function input_autocomplete(newel) {
            var input = $("input", newel);
            input.autocomplete({
                source: ["Indiana", 
                "California",
                "Pennsylvania"
                ]
            }
           );
            $("button", newel)
            .bind({
                click: function () {
                    input.focus();
                }
            });
        }
    </script>
</head>

<body>
    <table id="list"></table>
    <div id="pager"></div>
</body>
</html>

【问题讨论】:

    标签: javascript jquery autocomplete jqgrid free-jqgrid


    【解决方案1】:

    我不确定你到底在做什么。你代码的哪一部分放在&lt;button type='button' ... tabindex=-1 ...

    tabindex=-1 的放置仅意味着如果用户按 Tab 或 Shift-Tab 时该字段不应获得焦点,但这意味着该字段应该可以通过 API 调用获得焦点。在其他方面,tabindex 的存在使其可聚焦,但 tabindex 的负值通知仅将元素排除在顺序焦点导航之外。 W3 标准将其表述为(见here

    用户代理必须设置元素的 tabindex 焦点标志,但应该 不允许使用顺序焦点导航到达该元素。

    如果不想让按钮成为焦点,应该删除tabindex 属性。

    如果您不创建属性并且它对您使用的一些控件进行了控制,但您仍然不想将焦点设置在&lt;button&gt; 上,那么您可以将焦点设置在另一个可编辑列上。您可以使用focusField: "someColumnName"focusField: indexOfSomeColumn 将焦点设置在特定列上。

    更新:我发布了the fix,它在调用.focus() 之前添加了.first() 的用法。更改后,您发布的演示效果很好。

    【讨论】:

    • 我更新了问题。焦点需要设置到第一列input元素,所以不能指定不同的focusField值。删除 tabindex 属性仍将焦点设置为按钮。按钮只能通过鼠标单击或触摸来单击。它不应该从 focusField 或键盘集中。
    • @Andrus:您现在使用的focusField 的价值是多少?您使用哪种编辑模式?能否提供demo。哪个重现问题?选项focusField: true 表示将焦点的标准设置应用于第一个可聚焦元素。如果您说免费的 jqGrid 有错误,那么您应该为演示提供相应的测试用例。如果不是错误,但您需要在设置焦点时实现自定义逻辑,那么您可以使用focusField: true 并在oneditfunc 中手动设置焦点。
    • focusField: true 用于内联编辑。目前,如果第一列包含多个可聚焦元素,focusField: true 可以将焦点放在第一列中的 any 可聚焦元素上。实际上,它应该将焦点放在第一列中的 first 可聚焦元素上(使用制表符顺序)。我可以根据要求提供演示。
    • @Andrus:我在之前的评论中已经给你写过:“你能提供一个重现问题的演示吗?”如果您使用的 jQuery 版本可能很重要。可能是我可以通过在代码中包含额外的.first() 调用来解决问题。我提醒你一个常见的规则:如果你认为免费的 jqGrid 有一个错误,你应该发布使用来自 GitHub 的非最小化代码jquery.jqgrid.src.js 的演示。在我重现错误并发布错误修复后,相同的演示将正常工作。
    • 使用测试用例和观察到的预期行为更新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    • 1970-01-01
    相关资源
    最近更新 更多