Devnsyde
Devnsyde

Reputation: 1347

Using formatDisplayField in grouping

I have 3 columns (orderType, po number, bill id) that I am grouping by and I am using formatDisplayField to add a link/button to each group text so when clicked will open a context menu that will allow my users to add subgroups to that group. I need to pass the immediate row data that pertains to that group. Right now I am doing something sort of hacky and the data isnt specific enough.

Example:

A user clicks on the group ordertype and gets a context menu that says Add PO Number, they can then add a po number and on that group header they get a context menu that says Add Billing Id. User can also add a billing id without adding a po number, this is important because this is where my data gets wonky. Lets say grid looks like:

OrderGroupType: Direct
    PONumber: 12345
        BillingId: abc

OrderGroupType: Direct
    BillingId: abc

I can't seem to figure out how to get the data rows that have to do with the current group so I get all the data from the grid and then search through it and only return rows that equal my group name and then I put that information into a data attribute where I pull the information out in the context menu:

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;
    }
]

Where I am going wrong is I then have two more functions in that formatDisplayField property where I also set links/button onto the child groups:

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;
    }
]

This breaks down when I have a billing id that has a parent po number with the same billing id. It could also break down if I had two po numbers that were exactly the same in two different order groups.

So my question is how can I get the data that pertains to the group more reliably? I'd prefer that I only get rowData that has to do with the specific group. I could see that happening if I could get more data, maybe something like:

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;
    }
]

The fiddle below illustrates my issue; to see it working click MANUALS and choose edit, you will see it highlights the rows under manuals to orange, however, if you click on 1 under DSPO and click edit, you will see it colors all the rows that have a billing id of 1 instead of just the row group you chose... The rows that are going to be edited should color orange. JSFIDDLE

Any help would be phenomenal, I have tried lots of different things and the data is just not reliable. Thanks!

Upvotes: 0

Views: 550

Answers (1)

Oleg
Oleg

Reputation: 222017

It seems to me that your code too complex as it could be. The first very important problem: your input data don't contain id property with unique value. You place for example JSON.stringify(rowData) instead of comma separated list of rowid only because your input data has no id value. If the value of RecurringOrderLineTemplateId column for example is unique then you can add key: true in the column and jqGrid will use the value as the rowid. If the composite key (RecurringOrderHeaderTemplateId, RecurringOrderLineTemplateId) is unique instead then you can fill id property with the values item.RecurringOrderHeaderTemplateId + "_" + item.RecurringOrderLineTemplateId. You will be able to get the values RecurringOrderHeaderTemplateId and RecurringOrderLineTemplateId from the rowid by usage rowid.split("_"). Setting good rowid will not solve your main problem, but it will save your time later.

The main problem in your existing code seems to me the usage of $.grep over the whole data inside of formatDisplayField callback. It seems me wrong from performance point of view and from the common design. The data of the grid are already groupped, but you try redo the same once more inside of every formatDisplayField call. I don't like it.

I'm not sure that I full understand what you try to implement. It seems to me that you set data-rowdata on the <span> element of the column header only to be able to use $link.data('rowdata') later inside of click handler of the context menu. You can add

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

inside of build callback of the contextMenu and to use just

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)
  }

The modified demo https://jsfiddle.net/dv4v8mmz/3/ uses the above code with some additional alerts in ".billToMenu" and in ".poMenu" (just duplicating the code). You can see that the approach works.

Upvotes: 1

Related Questions