【问题标题】:how to make jqgrid advanced search dialog keyboard accessible如何使 jqgrid 高级搜索对话框键盘可访问
【发布时间】:2012-04-08 14:27:09
【问题描述】:

how to enable enter in jqgrid advanced search window 中的答案描述了如何在 jqgrid 高级搜索对话框中启用 enter 和其他键。

在高级搜索对话框中单击添加组、添加子组、删除规则或删除组按钮后,Enter 和其他键仍然被忽略。如何在添加元素或删除剩余元素后设置焦点以启用 Enter 和其他键?

【问题讨论】:

    标签: jqgrid


    【解决方案1】:

    高级搜索对话框的当前版本(参见grid.filter.jsjqFilter 的定义)重新创建对话框的所有控件以更改某人。看reDraw的代码,看起来

    this.reDraw = function() {
        $("table.group:first",this).remove();
        var t = this.createTableForGroup(p.filter, null);
        $(this).append(t);
        if($.isFunction(this.p.afterRedraw) ) {
            this.p.afterRedraw.call(this, this.p);
        }
    };
    

    如何才能看到第一行$("table.group:first",this).remove();删除所有过滤器的内容。当前焦点将丢失,并且出现您描述的问题。

    我建议使用 document.activeElement 元素修复reDraw 的代码,该元素最初是在 Internet Explorer 中引入的(至少在 IE4 中),现在所有 Web 浏览器都支持它,因为它是 HTML5 标准的一部分(参见 @987654322 @)。原来有焦点的元素会被销毁,以后就不能再设置焦点了。所以我建议保存元素的元素名称及其类(如input.add-groupinput.add-rule.ui-add)并在搜索对话框中找到元素的位置。稍后,在重新创建对话框元素后,我们会将焦点设置在具有相同索引的元素上。

    我建议把reDraw的代码改成如下

    this.reDraw = function() {
        var activeElement = document.activeElement, selector, $dialog, activeIndex = -1, $newElem, $buttons,
            buttonClass,
            getButtonClass = function (classNames) {
                var arClasses = ['add-group', 'add-rule', 'delete-group', 'delete-rule'], i, n, className;
                for (i = 0, n = classNames.length; i < n; i++) {
                    className = classNames[i];
                    if ($.inArray(className, arClasses) >= 0) {
                        return className;
                    }
                }
                return null;
            };
        if (activeElement) {
            selector = activeElement.nodeName.toLowerCase();
            buttonClass = getButtonClass(activeElement.className.split(' '));
            if (buttonClass !== null) {
                selector += '.' + buttonClass;
                if (selector === "input.delete-rule") {
                    $buttons = $(activeElement).closest('table.group')
                        .find('input.add-rule,input.delete-rule');
                    activeIndex = $buttons.index(activeElement);
                    if (activeIndex > 0) {
                        // find the previous "add-rule" button
                        while (activeIndex--) {
                            $newElem = $($buttons[activeIndex]);
                            if ($newElem.hasClass("add-rule")) {
                                activeElement = $newElem[0];
                                selector = activeElement.nodeName.toLowerCase() + "." +
                                    getButtonClass(activeElement.className.split(' '));
                                break;
                            }
                        }
                    }
                } else if (selector === "input.delete-group") {
                    // change focus to "Add Rule" of the parent group
                    $newElem = $(activeElement).closest('table.group')
                        .parent()
                        .closest('table.group')
                        .find('input.add-rule');
                    if ($newElem.length > 1) {
                        activeElement = $newElem[$newElem.length-2];
                        selector = activeElement.nodeName.toLowerCase() + "." +
                            getButtonClass(activeElement.className.split(' '));
                    }
                }
                $dialog = $(activeElement).closest(".ui-jqdialog");
                activeIndex = $dialog.find(selector).index(activeElement);
            }
        }
        $("table.group:first",this).remove();
        $(this).append(this.createTableForGroup(this.p.filter, null));
        if($.isFunction(this.p.afterRedraw) ) {
            this.p.afterRedraw.call(this, this.p);
        }
        if (activeElement && activeIndex >=0) {
            $newElem = $dialog.find(selector + ":eq(" + activeIndex + ")");
            if ($newElem.length>0) {
                $newElem.focus();
            } else {
                $dialog.find("input.add-rule:first").focus();
            }
        }
    };
    

    就像在the next demo 上看到的那样,在按下“添加子组”或“添加规则”按钮后,搜索对话框中的焦点保持不变。如果按“删除组”,我将其设置在上一个行组的“添加规则”按钮上。

    One more demo 使用 jQuery UI 样式的按钮和按钮中的文本(参见 the answer)。单击“删除”(规则或组)按钮后,我尝试将焦点设置到上一个“添加规则”按钮,因为将焦点设置在另一个“删除”(规则或组)按钮上我觉得很危险。

    另外在我使用的演示中

    afterShowSearch: function ($form) {
        var $lastInput = $form.find(".input-elm:last");
        if ($lastInput.length > 0) {
            $lastInput.focus();
        }
    }
    

    因为在对话框打开时将初始焦点设置在最后一个输入字段上似乎很有意义。

    更新:我发现将焦点设置在当前单击的按钮“添加子组”、“添加规则”或“删除组”上也很有意义。在首先用鼠标单击某个按钮然后想继续使用键盘工作的情况下,人们看到的优势。所以我建议改the line

    inputAddSubgroup.bind('click',function() {
    

    inputAddSubgroup.bind('click',function(e) {
        $(e.target).focus();
    

    更改the line

    inputAddRule.bind('click',function() {
    

    inputAddRule.bind('click',function(e) {
        $(e.target).focus();
    

    the line

    inputDeleteGroup.bind('click',function() {
    

    inputDeleteGroup.bind('click',function(e) {
        $(e.target).focus();
    

    the line

    ruleDeleteInput.bind('click',function() {
    

    ruleDeleteInput.bind('click',function(e) {
        $(e.target).focus();
    

    【讨论】:

    • 我使用其他答案的 afterRedraw 代码尝试了这些更改,这些代码将 jQuieryUI button() 应用于对话框按钮。在这种情况下,按钮不会获​​得焦点,并且在单击按钮后仍会忽略键盘键
    • @Andrus:我又更新了一次代码(见上文)。新的演示是here
    • 谢谢,它有效。我尝试禁用正文垂直滚动条。多次单击添加按钮按钮后,对话框高度会增加到屏幕外(对话框中不会出现垂直滚动条)。此外,如果鼠标悬停在添加角色按钮上,单击 IE9 中的添加规则按钮后,每次悬停时对话框高度都会增加。我想我们为编辑表单修复了这个问题(我在其他问题中为此提供了测试用例)。
    猜你喜欢
    • 1970-01-01
    • 2012-05-20
    • 2012-03-11
    • 1970-01-01
    • 1970-01-01
    • 2012-09-18
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多