在分组中使用 formatDisplayField

Using formatDisplayField in grouping

我有 3 列(orderType、po number、bill id)作为分组依据,我正在使用 formatDisplayField 添加 link/button 到每个组文本,因此单击时将打开一个上下文菜单,该菜单将允许我的用户向该组添加子组。我需要传递属于该组的直接行数据。现在我正在做一些 hacky,数据不够具体。

示例:

用户点击组 ordertype 并获得一个显示 Add PO Number 的上下文菜单,他们然后可以添加采购订单编号,在该组 header 上,他们会得到一个显示 Add Billing Id 的上下文菜单。用户还可以在不添加订单号的情况下添加账单 ID,这很重要,因为这是我的数据变得不稳定的地方。让我们说网格看起来像:

OrderGroupType: Direct
    PONumber: 12345
        BillingId: abc

OrderGroupType: Direct
    BillingId: abc

我似乎无法弄清楚如何获取与当前组有关的数据行,所以我从网格中获取所有数据,然后搜索它,只搜索 return 行等于我的组名,然后我将该信息放入数据属性中,在上下文菜单中提取信息:

groupText: ['Group Type: <b>{0} - {1} Item(s)</b>',
            'PO Number: <b>{0} - {1} Item(s)</b>',
            'Bill To: <b>{0} - {1} Item(s)</b>'
        ],
 formatDisplayField: [
    function (ordgrpTypVal) {
        //all rowData
        var allRowData = $(this).jqGrid("getGridParam", "data");
        //this row data
        var rowData = $.grep(allRowData, function (v) {
            return v.OrderGroupType == grpTypVal;
        });
        var elementId = "groupType_" + grpTypVal.replace(/\s+/g, '') + "_" + i++;
        var newElement = '<span id="' + elementId + '" data-rowdata=\'' + JSON.stringify(rowData).replace(/'/g, "\'") +'\' class="groupTypeMenu" style="cursor: pointer; color: blue;">' + grpTypVal + '</span>';
        return newElement;
    }
]

我哪里出错了,然后我在 formatDisplayField 属性 中还有两个函数,我还在 child 组上设置了 links/button:

formatDisplayField: [
    function (grpTypVal) {
        //all rowData
        var allRowData = $(this).jqGrid("getGridParam", "data");
        //this row data
        var rowData = $.grep(allRowData, function (v) {
            return v.OrderGroupType == grpTypVal;
        });
        var elementId = "groupType_" + grpTypVal.replace(/\s+/g, '') + "_" + i++;
        var newElement = '<span id="' + elementId + '" data-rowdata=\'' + JSON.stringify(rowData).replace(/'/g, "\'") +'\' class="groupTypeMenu" style="cursor: pointer; color: blue;">' + grpTypVal + '</span>';
        return newElement;
    },
    function (poVal) {
        if (poVal !== null) {
            //all rowData
            var allRowData = $(this).jqGrid("getGridParam", "data");
            //this row data
            var rowData = $.grep(allRowData, function (v) {
                return v.PoNumber == poVal;
            });
            var elementId = "PoNum_" + poVal.replace(/\s+/g, '') + "_" + i++;
            var newElement = '<span id="' + elementId + '" data-rowdata=\'' + JSON.stringify(rowData).replace(/'/g, "\'") + '\'  class="poMenu" style="cursor: pointer; color: blue;">' + poVal + '</span>';
            return newElement;
        }
        else
            return null;
    },
    function (billToVal, val, props, index, obj) {
        if (billToVal !== null) {
            //all rowData
            var allRowData = $(this).jqGrid("getGridParam", "data");
            //this row data
            var rowData = $.grep(allRowData, function (v) {
                return v.BillToId == billToVal;
            });
            var elementId = "BillTo_" + billToVal.replace(/\s+/g, '') + "_" + i++;
            var newElement = '<span id="' + elementId + '" data-rowdata=\'' + JSON.stringify(rowData).replace(/'/g, "\'") + '\' class="billToMenu" style="cursor: pointer; color: blue;">' + billToVal + '</span>';
            return newElement;
        }
        else
            return null;
    }
]

当我有一个具有相同帐单 ID 的 parent 订单号的帐单 ID 时,这会崩溃。如果我有两个订单号在两个不同的订单组中完全相同,它也可能会崩溃。

所以我的问题是如何更可靠地获取属于该组的数据?我宁愿只获得与特定组有关的 rowData。如果我可以获得更多数据,我可以看到这种情况发生,可能是这样的:

formatDisplayField: [
    function (billToVal, val, props, index, obj) {
        if (billToVal !== null) {
            //all rowData
            var allRowData = $(this).jqGrid("getGridParam", "data");
            //this row data
            var rowData = $.grep(allRowData, function (v) {
                return v.BillToId == billToVal **&& v.PoNumber == obj.PoNumber && v.OrderGroupType == obj.OrderGroupType;**
            });
            var elementId = "BillTo_" + billToVal.replace(/\s+/g, '') + "_" + i++;
            var newElement = '<span id="' + elementId + '" data-rowdata=\'' + JSON.stringify(rowData).replace(/'/g, "\'") + '\' class="billToMenu" style="cursor: pointer; color: blue;">' + billToVal + '</span>';
            return newElement;
        }
        else
            return null;
    }
]

下面的 fiddle 说明了我的问题;要查看它是否正常工作,请单击 MANUALS 并选择编辑,您会看到它将手册下的行突出显示为橙色,但是,如果您单击 DSPO 下的 1 并单击编辑,您会看到它为所有行着色计费 ID 为 1 的行,而不仅仅是您选择的行组...要编辑的行应为橙色。 JSFIDDLE

任何帮助都是非凡的,我尝试了很多不同的东西,但数据并不可靠。谢谢!

在我看来,您的代码太复杂了。第一个非常重要的问题:您的输入数据不包含具有唯一值的 id 属性。例如,您放置 JSON.stringify(rowData) 而不是 rowid 的逗号分隔列表只是因为您的输入数据没有 id 值。例如,如果 RecurringOrderLineTemplateId 列的值是唯一的,那么您可以在该列中添加 key: true,jqGrid 将使用该值作为 rowid。如果组合键 (RecurringOrderHeaderTemplateIdRecurringOrderLineTemplateId) 是唯一的,那么您可以用值 item.RecurringOrderHeaderTemplateId + "_" + item.RecurringOrderLineTemplateId 填充 id 属性。您将能够通过使用 rowid.split("_") 从 rowid 中获取值 RecurringOrderHeaderTemplateIdRecurringOrderLineTemplateId。设置好的 rowid 不会解决你的主要问题,但它会节省你以后的时间。

在我看来,您现有代码中的主要问题是 $.grep formatDisplayField 回调中对整个数据 的使用。从性能和通用设计的角度来看,我似乎错了。网格的数据已经分组,但您尝试在每个 formatDisplayField 调用中重做一次。我不喜欢。

我不确定我是否完全理解您要实现的目标。在我看来,您在 header 列的 <span> 元素上设置 data-rowdata 只是为了能够稍后在 click 处理程序内部使用 $link.data('rowdata')上下文菜单。您可以添加

var $tr = $(e.target).closest("tr.jqgroup"),
    jqgrouplevel = parseInt($($tr).data("jqgrouplevel"), 10);

contextMenubuild 回调中并仅使用

edit: {
  ...
  callback: function () {
    for ($tr = $tr.next(); $tr.length; $tr = $tr.next()) {
        if ($tr.hasClass("jqgroup") && parseInt($tr.data("jqgrouplevel"), 10) <= jqgrouplevel) {
            break; // stop enumeration
        } else if ($tr.hasClass("jqgrow")) {
            $tr.addClass("markedForModification"); // mark the row
        }
    }
    //EditBillToHeader(rowData)
  }

修改后的演示 https://jsfiddle.net/dv4v8mmz/3/ 使用上面的代码,在“.billToMenu”和“.poMenu”中添加一些额外的 alerts(只是复制代码)。您可以看到该方法有效。