如何使jqgrid高级搜索对话框键盘可访问

时间:2012-04-08 14:27:09

标签: jqgrid

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

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

1 个答案:

答案 0 :(得分:1)

当前版本的“高级搜索”对话框(请参阅jqFilter中的grid.filter.js的定义)重新创建有关更改某人的对话框的所有控件。请参阅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();删除所有过滤器的内容。目前的焦点将会丢失,其中一个会出现你所描述的问题。

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

我建议将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();