jqGrid 在自定义按钮单击时获取行数据

jqGrid get row data on custom button click

我有以下自定义网格

我需要 rowObject 当用户单击序列号列中的图像以显示一个对话框,允许用户从该行的可用列表中 select 另一个序列号,然后发送 selected 串行返回服务器。

由于第 5 列和第 6 列的图像执行与其列中数据相关的功能,我无法将所有图像组合到一个带有编辑和删除按钮的操作列中,因此 this answer 不适合我。

目前我正在使用以下方法查找所需的行并使用行数据调用我的函数。这种方法很慢,因为它必须在 for 循环中遍历数据并找到匹配的记录。我删除了所有不相关的代码,剩下的就在这里

    var TerminalColNames = [
        'id',
        'Serial'
    ];

    var TerminalColModel = [
        { name: 'id', width: '180px', formatter: TerminalID_Formatter},
        { name: 'serial', width: '160px', formatter: Formatter, sortable: false }
    ];

    function TerminalID_Formatter(cellvalue, options, rowObject) {
        return ' ' +
            '<img src="pencil.png" onclick="return edit(\'' + cellvalue + '\')"> ' +
            '<img src="bin.png"    onclick="return delete(\'' + cellvalue + '\')"> ' +
            cellvalue;
    }

    function Formatter(cellvalue, options, rowObject) {
        return '<img src="link.png" onclick="return bind(\'' + rowObject.id + '\')"></a> ' + rowObject.serial.current;
    }

    function CreateGrid(TableElement, colNames, colModel, data) {

        $(TableElement).jqGrid({
            datatype: 'local',
            data: data,
            colNames: colNames,
            colModel: colModel,
            height: '150px',
            //onSelectRow: function (id, status, e) {
            //    rowData = $(this).jqGrid("getLocalRow", id);
            //    return RowAction(rowData);
            //}
        });
    }

    $(function () {
        CreateGrid('#TerminalGrid', TerminalColNames, TerminalColModel, data.terminals);
    });

    function RowAction(rowData) {
        alert('Row Action:' + JSON.stringify(rowData));
    }

    function bind(id) {
        for (i in data.terminals){
            if (data.terminals[i].id == id){
                return ProcessBind(data.terminals[i]);
            }
        }
        return false;
    }


    function ProcessBind(rowObject){
        if (rowObject.id)
            alert('Bind:' + rowObject.serial.avail.length);
        else 
            alert('Bind not found');
        return true;
    }

    var data = {
        "id": "1234",
        "terminals": [
            {
                "id": "111111",
                "serial": {
                    "current": "888888",
                    "avail": [
                        "444444",
                        "555555",
                        "666666"
                    ]
                }
            },
            {
                "id": "777777",
                "serial": {
                    "current": "333333",
                    "avail": [
                        "999999",
                        "000000",
                    ]
                }
            },
            //.....
        ]
        //.....
    }

我没有使用 $(this).closest('tr').attr('id') 因为我相信它要慢得多,因为它必须通过 DOM 找到 id,然后通过 JSON 数据找到行数据。还需要在id列中设置key: true

问题

有没有更好的获取记录数据的方法? 或者是否有 JSON 数组中的 return rowIndex 的 jqGrid 方法?

编辑 我忘了说我正在使用 oleg's free jqgrid 4.15.2

如果我理解正确,您可以使用方法 getLocalRow( rowid ) 以防您使用本地数据。此方法 return 在知道 rowid 时按索引快速获取行数据。

另一个技巧是使用内部 _index jqGrid 参数通过给定的行 id 获取行的索引。

var grid = $("#jqGrid")[0];
var rowid = "somerowid";
var rowIndex = grid.p._index[rowid];

var datarow = grid.p.data[rowIndex];

方法 getLocaRow 使用类似的方法。

如果数据不是本地的,您可以使用 getInd 方法

Guriddo jqGrid中使用了这里的方法。有关这些方法的更多信息,请参见 Guriddo Documentation

首先,我建议您对代码进行一些小的修正:

  • 将属性 width: '180px' 更改为 width: 180,将选项 height: '150px' 更改为 height: 150。当前代码有效,但它会被误解,因为 width: '180em' 将被解释为 width: 180(或 180px),但 height: '150em' 确实会增加网格的高度。
  • 应该减少 JavaScript 代码中 全局 函数的数量。例如,如果 CreateGrid 函数仅在 $(function () {...}); 内部使用一次,而 var data 仅在 CreateGrid 内部使用,那么您应该将 variables/functions 的声明移动到相应的内部范围。

现在谈谈你的主要问题。 beforeSelectRowonSelectRowonCellSelect 回调的事件参数提供了您需要的所有信息。 target 属性 是在网格内部单击的 DOM 元素。可以测试其 classtagNamename 或其他属性以验证特定的 image/icon 是否被单击。不需要使用 onclick 属性。

关于表演。重要的是要了解 DOM 元素(classtagNamenameparentElement 等)的属性访问非常快。访问属性的时间不取决于页面上的元素总数。它使 closesthasClass 和其他功能的工作非常迅速。这是推荐的方式。下面的代码提供了一个访问整行数据的例子:

onSelectRow: function (rowid, status, e) {
    var $self = $(this), $target = $(e.target),
        p = $self.jqGrid("getGridParam"),
        rowData = $self.jqGrid("getLocalRow", rowid),
        $td = $target.closest("tr.jqgrow>td"),
        iCol = $td.length > 0 ? $td[0].cellIndex : -1,
        cmName = iCol >= 0 ? p.colModel[iCol].name : "";

    switch (cmName) {
        case "id":
            if ($target.hasClass("myedit")) {
                alert("edit icon is clicked in the row with rowid=" + rowid);
            } else if ($target.hasClass("mydelete")) {
                alert("delete icon is clicked in the row with rowid=" + rowid);
            }
            break;
        case "serial":
            if ($target.hasClass("mylink")) {
                alert("link icon is clicked in the row with rowid=" + rowid);
            }
            break;
        default:
            break;
                  }
    alert("full row data:\n\n" + JSON.stringify(rowData));
    //    return RowAction(rowData);
}

https://jsfiddle.net/OlegKi/dfra7snb/

代码片段:

$(function () {
    "use strict";
    function CreateGrid(TableElement, colNames, colModel, data) {
        $(TableElement).jqGrid({
            datatype: 'local',
            data: data,
            colNames: colNames,
            colModel: colModel,
            iconSet: "fontAwesome",
            onSelectRow: function (rowid, status, e) {
                var $self = $(this), $target = $(e.target),
                    p = $self.jqGrid("getGridParam"),
                    rowData = $self.jqGrid("getLocalRow", rowid),
                    $td = $target.closest("tr.jqgrow>td"),
                    iCol = $td.length > 0 ? $td[0].cellIndex : -1,
                    cmName = iCol >= 0 ? p.colModel[iCol].name : "";

                switch (cmName) {
                    case "id":
                        if ($target.hasClass("myedit")) {
                            alert("edit icon is clicked in the row with rowid=" + rowid);
                        } else if ($target.hasClass("mydelete")) {
                            alert("delete icon is clicked in the row with rowid=" + rowid);
                        }
                        break;
                    case "serial":
                        if ($target.hasClass("mylink")) {
                            alert("link icon is clicked in the row with rowid=" + rowid);
                        }
                        break;
                    default:
                        break;
                              }
                alert("full row data:\n\n" + JSON.stringify(rowData));
                //    return RowAction(rowData);
            },
            height: 150
        });
    }
    var TerminalColNames = [
        'id',
        'Serial'
    ];

    function TerminalID_Formatter(cellvalue, options, rowObject) {
        return '<span class="fa fa-pencil fa-lg myedit" aria-hidden="true"></span>' +
            '<span class="fa fa-trash-o fa-lg mydelete" aria-hidden="true"></span>' +
            cellvalue;
    }

    function Formatter(cellvalue, options, rowObject) {
        return '<span class="fa fa-link fa-rotate-90 fa-lg mylink" aria-hidden="true"></span>' +
            rowObject.serial.current;
    }
    var TerminalColModel = [
        { name: 'id', width: '180em', formatter: TerminalID_Formatter},
        { name: 'serial', width: 160, formatter: Formatter, sortable: false }
    ];
    var data = {
        "id": "1234",
        "terminals": [
            {
                "id": "111111",
                "serial": {
                    "current": "888888",
                    "avail": [
                        "444444",
                        "555555",
                        "666666"
                    ]
                }
            },
            {
                "id": "777777",
                "serial": {
                    "current": "333333",
                    "avail": [
                        "999999",
                        "000000",
                    ]
                }
            },
            //.....
        ]
        //.....
    };
    CreateGrid('#TerminalGrid', TerminalColNames, TerminalColModel, data.terminals);
});
.myedit, .mydelete, .mylink {
    margin: 0 0.25em;
}
.myedit {
    color: green;
}
.mydelete {
    color: red;
}
.mylink {
    color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/themes/redmond/jquery-ui.min.css"/>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.15.2/css/ui.jqgrid.min.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/free-jqgrid/4.15.2/jquery.jqgrid.min.js"></script>

<table id="TerminalGrid"></table>