如果 window 在免费 jqgrid 中处于活动状态,如何为顶级工具栏命令阻止添加热键

How to add hot keys for top level toolbar command blocking if window is active in free jqgrid

我正在寻找一种方法来为顶级工具栏按钮添加热键:

我尝试了以下在早期版本中有效的代码。

在免费的 jqgrid 中,每次 F4 单击都会在提交和取消按钮上添加新图标。 之后按下取消按钮导致 javascript 异常:

    Uncaught TypeError: Cannot read property 'a' of undefined Line 15011 Column 19
TypeError: Cannot read property 'a' of undefined    at Object.$.jqm.close (http://localhost:52216/admin/Scripts/jqgrid-4.8.0/js/jquery.jqgrid.src.js:15011:19)   
 at HTMLDivElement.<anonymous> (http://localhost:52216/admin/Scripts/jqgrid-4.8.0/js/jquery.jqgrid.src.js:14936:78)   
 at Function.jQuery.extend.each (http://localhost:52216/admin/Scripts/jquery-1.11.2.js:384:23)    at jQuery.fn.jQuery.each (http://localhost:52216/admin/Scripts/jquery-1.11.2.js:136:17)    at $.fn.jqmHide (http://localhost:52216/admin/Scripts/jqgrid-4.8.0/js/jquery.jqgrid.src.js:14936:53) 
   at $.extend.hideModal (http://localhost:52216/admin/Scripts/jqgrid-4.8.0/js/jquery.jqgrid.src.js:6263:43)  
  at Object.$.extend.complete (http://localhost:52216/admin/Scripts/jqgrid-4.8.0/js/jquery.jqgrid.src.js:9703:32)  
  at fire (http://localhost:52216/admin/Scripts/jquery-1.11.2.js:3143:30) 
   at Object.self.fireWith (http://localhost:52216/admin/Scripts/jquery-1.11.2.js:3255:7)
    at done (http://localhost:52216/admin/Scripts/jquery-1.11.2.js:9324:21)

添加和查看热键如果实现了同样的问题。 搜索按钮不会禁用网格。只有搜索按钮热键实现是这种方式也适用于免费的 jqgrid。

如何解决这个问题? 如果编辑或查看 window 处于活动状态,似乎需要禁用热键。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <meta name="author" content="Oleg Kiriljuk"/>
    <link rel="stylesheet" type="text/css" href="http://code.jquery.com/ui/1.11.4/themes/redmond/jquery-ui.css"/>
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
    <!--<link rel="stylesheet" type="text/css" href="http://cdn.jsdelivr.net/free-jqgrid/4.8.0/css/ui.jqgrid.css"/>-->
    <link rel="stylesheet" type="text/css" href="http://rawgit.com/free-jqgrid/jqGrid/master/css/ui.jqgrid.css"/>
    <link rel="stylesheet" href="http://netdna.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css"/>
    <style type="text/css">
        html, body { font-size: 75%; }
        .ui-jqgrid td input[type=date], input[type=time], input[type=datetime-local], input[type=month] {
            line-height: normal;
        }
    </style>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
    <!--<script type="text/javascript" src="http://cdn.jsdelivr.net/free-jqgrid/4.8.0/js/i18n/grid.locale-en.js"></script>-->
    <script type="text/javascript" src="http://rawgit.com/free-jqgrid/jqGrid/master/js/i18n/grid.locale-en.js"></script>
    <script type="text/javascript">
        $.jgrid = $.jgrid || {};
        $.jgrid.no_legacy_api = true;
        $.jgrid.useJSON = true;
    </script>
    <!--<script src="../jqGrid/js/jquery.jqGrid.src.js"></script>-->
    <!--<script type="text/javascript" src="http://cdn.jsdelivr.net/free-jqgrid/4.8.0/js/jquery.jqgrid.src.js"></script>-->
    <script type="text/javascript" src="http://rawgit.com/free-jqgrid/jqGrid/master/js/jquery.jqgrid.src.js"></script>
    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
    <script type="text/javascript">
    //<![CDATA[
        /*global $,Modernizr */
        /*jslint browser: true, unparam: true */
        $(function () {
            "use strict";
            var mydata = [
                    { id: "10",  invdate: "2007-10-01", name: "test1",  note: "note1",  amount: "200.00", tax: "10.00", closed: true,  ship_via: "TN", total: "210.00" },
                    { id: "20",  invdate: "2007-10-02", name: "test2",  note: "note2",  amount: "300.00", tax: "20.00", closed: false, ship_via: "FE", total: "320.00" },
                    { id: "30",  invdate: "2007-09-01", name: "test3",  note: "note3",  amount: "400.00", tax: "30.00", closed: false, ship_via: "FE", total: "430.00" },
                    { id: "40",  invdate: "2007-10-04", name: "test4",  note: "note4",  amount: "200.00", tax: "10.00", closed: true,  ship_via: "TN", total: "210.00" },
                    { id: "50",  invdate: "2007-10-31", name: "test5",  note: "note5",  amount: "300.00", tax: "20.00", closed: false, ship_via: "FE", total: "320.00" },
                    { id: "60",  invdate: "2007-09-06", name: "test6",  note: "note6",  amount: "400.00", tax: "30.00", closed: false, ship_via: "FE", total: "430.00" },
                    { id: "70",  invdate: "2007-10-04", name: "test7",  note: "note7",  amount: "200.00", tax: "10.00", closed: true,  ship_via: "TN", total: "210.00" },
                    { id: "80",  invdate: "2007-10-03", name: "test8",  note: "note8",  amount: "300.00", tax: "20.00", closed: false, ship_via: "FE", total: "320.00" },
                    { id: "90",  invdate: "2007-09-01", name: "test9",  note: "note9",  amount: "400.00", tax: "30.00", closed: false, ship_via: "TN", total: "430.00" },
                    { id: "100", invdate: "2007-09-08", name: "test10", note: "note10", amount: "500.00", tax: "30.00", closed: true,  ship_via: "TN", total: "530.00" },
                    { id: "110", invdate: "2007-09-08", name: "test11", note: "note11", amount: "500.00", tax: "30.00", closed: false, ship_via: "FE", total: "530.00" },
                    { id: "120", invdate: "2007-09-10", name: "test12", note: "note12", amount: "500.00", tax: "30.00", closed: false, ship_via: "FE", total: "530.00" }
                ],
                $grid = $("#list"),
                initDateEdit = function (elem, options) {
                    // we need get the value before changing the type
                    var orgValue = $(elem).val(), newformat,
                        cm = $(this).jqGrid("getColProp", options.name);

                    $(elem).attr("type", "date");
                    if ((typeof Modernizr !== "undefined" && !Modernizr.inputtypes.date) || $(elem).prop("type") !== "date") {
                        $(elem).attr("type", "text"); // !!! important to make saving works correctly
                        $(elem).css({ width: "8em" }).datepicker({
                            dateFormat: "mm/dd/yy",
                            autoSize: true,
                            changeYear: true,
                            changeMonth: true,
                            showButtonPanel: true,
                            showWeek: true
                        });
                    } else {
                        // convert date to ISO
                        if (orgValue !== "") {
                            newformat = cm.formatoptions != null && cm.formatoptions.newformat ?
                                cm.formatoptions.newformat :
                                $(this).jqGrid("getGridRes", "formatter.date.newformat");
                            $(elem).val($.jgrid.parseDate.call(this, newformat, orgValue, "Y-m-d"));
                        }
                        $(elem).css({width: "11em"});
                    }
                },
                initDateSearch = function (elem) {
                    setTimeout(function () {
                        $(elem).datepicker({
                            dateFormat: "mm/dd/yy",
                            autoSize: true,
                            changeYear: true,
                            changeMonth: true,
                            showWeek: true,
                            showButtonPanel: true
                        });
                    }, 50);
                },
                numberTemplate = {formatter: "number", align: "right", sorttype: "number",
                    editrules: {number: true, required: true},
                    searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge", "nu", "nn", "in", "ni"] }};

            $grid.jqGrid({
                datatype: "local",
                data: mydata,
                colNames: ["Client", "Date", "Closed", "Shipped via", "Notes", "Tax", "Amount", "Total"],
                colModel: [
                    { name: "name", align: "center", editable: true, width: 65, editrules: {required: true} },
                    { name: "invdate", width: 125, align: "center", sorttype: "date",
                        formatter: "date", /*formatoptions: { newformat: "m/d/Y"},*/ editable: true,
                        editoptions: { dataInit: initDateEdit },
                        searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"], dataInit: initDateSearch } },
                    { name: "closed", width: 70, align: "center", editable: true, formatter: "checkbox",
                        edittype: "checkbox", editoptions: {value: "Yes:No", defaultValue: "Yes"},
                        stype: "select", searchoptions: { sopt: ["eq", "ne"], value: ":Any;true:Yes;false:No" } },
                    { name: "ship_via", width: 105, align: "center", editable: true, formatter: "select",
                        edittype: "select", editoptions: { value: "FE:FedEx;TN:TNT;IN:Intim", defaultValue: "IN" },
                        stype: "select", searchoptions: { sopt: ["eq", "ne"], value: ":Any;FE:FedEx;TN:TNT;IN:IN" } },
                    { name: "note", width: 60, sortable: false, editable: true, edittype: "textarea" },
                    { name: "tax", width: 52, editable: true, template: numberTemplate },
                    { name: "amount", width: 75, editable: true, template: numberTemplate },
                    { name: "total", width: 60, template: numberTemplate }
                ],
                rowNum: 10,
                rowList: [5, 10, 20],
            toppager: true,

                iconSet: "fontAwesome",
                pager: "#pager",
                gridview: true,
                autoencode: true,
                ignoreCase: true,
                sortname: "invdate",
                viewrecords: true,
                sortorder: "desc",
                height: "auto",
                rownumbers: true,
                editurl: "clientArray",
                onSelectRow: function (rowid) {
                    var $self = $(this),
                        savedRow = $self.jqGrid("getGridParam", "savedRow");
                    if (savedRow.length > 0) {
                        $self.jqGrid("restoreRow", savedRow[0].id);
                    }
                    $self.jqGrid("editRow", rowid);
                },
                inlineEditing: {
                    keys: true
                },
                formEditing: {
                    viewPagerButtons: false
                }
            }).jqGrid("navGrid").jqGrid("inlineNav");


var htmlKeydown = function (evt) {
    if (!evt.ctrlKey && !evt.altKey) {
        switch (evt.keyCode) {
            case 115: $("#edit_list_top").click(); return false;
           }
}
};


$("html").keydown(function (evt) {
    return htmlKeydown(evt);
});

        });
    //]]>
    </script>
</head>
<body>
<div id="outerDiv" style="margin:5px;">
    <table id="list"><tr><td></td></tr></table>
    <div id="pager"></div>
</div>
</body>
</html>

我觉得你只需要替换代码

switch (evt.keyCode) {
    case 115: $("#edit_list_top").click(); return false;
}

var idSelector = $.jgrid.jqID($grid[0].id);
switch (evt.keyCode) {
    case 115:
        if ($("#editmod" + idSelector).length === 0) {
            $("#edit_" + idSelector + "_top").click();
        }
        return false;
}

所以我建议你在模拟之前测试Add/Edit对话框是否已经存在点击导航器工具栏的编辑按钮。