I am trying to work out why the percentage number in the field in the corner of this grid is set to NaN. To save you time, look at the JsFiddle here; https://jsfiddle.net/arame3333/ttc83khL/8/
Alternatively if the link is broken here is the code; HTML:
<body>
<hi>SIR Tracker - Outstanding Defects Current on 23rd November 2017</hi>
<div id="outerDiv" style="margin:5px;">
<table id="treegrid"></table>
</div>
</body>
CSS
.ui-jqgrid .ui-jqgrid-htable th div, .ui-jqgrid-sortable {
height:auto;
overflow:hidden;
white-space:normal !important;
}
JQuery/JqGrid:
$(function () {
"use strict";
var thisMonthName = getMonthName();
var lastMonthName = getLastMonthName();
var mydata = [
{ id: "1", name: "CD/N142 Janson Close", yearStart: "10", lastMonth: "1",
thisMonth: "72", outstandingFaults: "83", openFaults: "83", closeFaults: "3", totalFaults: "169",
level: "0", parent: "null", isLeaf: false, expanded: true, loaded: true,
icon: "ui-icon-folder-open,ui-icon-folder-collapsed" },
{ id: "2", name: "Electrical", yearStart: "8", lastMonth: "1",
thisMonth: "48", outstandingFaults: "77", openFaults: "43", closeFaults: "2", totalFaults: "109",
level: "1", parent: "1", isLeaf: true, expanded: false, loaded: true },
{ id: "3", name: "Mechanical", yearStart: "2", lastMonth: "0",
thisMonth: "24", outstandingFaults: "6", openFaults: "40", closeFaults: "1", totalFaults: "60",
level: "1", parent: "1", isLeaf: true, expanded: false, loaded: true },
{ id: "4", name: "CD/L224 Lychet Way", yearStart: "3", lastMonth: "10",
thisMonth: "67", outstandingFaults: "80", openFaults: "130", closeFaults: "265", totalFaults: "475",
level: "0", parent: "null", isLeaf: false, expanded: true, loaded: true,
icon: "ui-icon-folder-open,ui-icon-folder-collapsed" },
{ id: "5", name: "Electrical", yearStart: "2", lastMonth: "8",
thisMonth: "47", outstandingFaults: "40", openFaults: "80", closeFaults: "190", totalFaults: "270",
level: "1", parent: "4", isLeaf: true, expanded: false, loaded: true },
{ id: "6", name: "Mechanical", yearStart: "1", lastMonth: "2",
thisMonth: "20", outstandingFaults: "40", openFaults: "50", closeFaults: "75", totalFaults: "205",
level: "1", parent: "4", isLeaf: true, expanded: false, loaded: true }
];
$("#treegrid").jqGrid({
datatype: "local",
data: mydata,
colNames: ["Project", "From year start", lastMonthName, thisMonthName, "Outstanding faults", "Open", "Close", "Total", "% Outstanding"],
colModel: [
{ name: "name", width: 200 },
{ name: "yearStart", template: "integer", width: 50 },
{ name: "lastMonth", template: "integer", width: 50 },
{ name: "thisMonth", template: "integer", width: 50 },
{ name: "outstandingFaults", template: "integer", width: 80 },
{ name: "openFaults", template: "integer", width: 50 },
{ name: "closeFaults", template: "integer", width: 50 },
{ name: "totalFaults", template: "integer", width: 50 },
{ name: 'faultsPerc', template: "integer", width: 80,
formatter: function (cellvalue, options, rowObject)
{
return Math.round(rowObject["outstandingFaults"] / rowObject["totalFaults"] * 100);
}
}
],
cmTemplate: { autoResizable: true },
autoresize: true,
rownumbers: true,
viewrecords: true,
autoResizing: { compact: true },
treeGrid: true,
treeGridModel: "adjacency",
ExpandColumn: "name",
footerrow: true,
gridComplete: function() {
var $grid = $('#treegrid');
$grid.jqGrid('footerData', 'set', { "name": "Total"} );
var colSumYearStart = $grid.jqGrid('getCol', "yearStart", false, 'sum') / 2;
$grid.jqGrid('footerData', 'set', { "yearStart": colSumYearStart });
var colSumLastMonth = $grid.jqGrid('getCol', "lastMonth", false, 'sum') / 2;
$grid.jqGrid('footerData', 'set', { "lastMonth": colSumLastMonth });
var colSumThisMonth = $grid.jqGrid('getCol', "thisMonth", false, 'sum') / 2;
$grid.jqGrid('footerData', 'set', { "thisMonth": colSumThisMonth });
var colSumOutstandingFaults = $grid.jqGrid('getCol', "outstandingFaults", false, 'sum') / 2;
$grid.jqGrid('footerData', 'set', { "outstandingFaults": colSumOutstandingFaults });
var colSumOpenFaults = $grid.jqGrid('getCol', "openFaults", false, 'sum') / 2;
$grid.jqGrid('footerData', 'set', { "openFaults": colSumOpenFaults });
var colSumCloseFaults = $grid.jqGrid('getCol', "closeFaults", false, 'sum') / 2;
$grid.jqGrid('footerData', 'set', { "closeFaults": colSumCloseFaults });
var colSumCloseFaults = $grid.jqGrid('getCol', "closeFaults", false, 'sum') / 2;
$grid.jqGrid('footerData', 'set', { "closeFaults": colSumCloseFaults });
var colSumTotalFaults = $grid.jqGrid('getCol', "totalFaults", false, 'sum') / 2;
$grid.jqGrid('footerData', 'set', { "totalFaults": colSumTotalFaults });
var avePercentage = colSumOutstandingFaults / colSumTotalFaults * 100;
$grid.jqGrid('footerData', 'set', { "faultsPerc": avePercentage });
}
});
});
var populateFooterTotals = function(item){
var $grid = $('#treegrid');
var colSum = $grid.jqGrid('getCol', item, false, 'sum') / 2;
$grid.jqGrid('footerData', 'set', { item: colSum });
}
var getMonthName = function(){
var d = new Date();
var n = d.getMonth();
return getMonthNameByIndex(n);
}
var getLastMonthName = function(){
var d = new Date();
var n = d.getMonth() - 1;
if(n === -1){
n = 12;
}
return getMonthNameByIndex(n);
}
var getMonthNameByIndex = function(index){
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June',
'July', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
return months[index];
}
You should use one call of footerData
method instead of multiple calls. It's more effective, first of all, and it's important because of the code of formatter of faultsPerc
column uses the content of outstandingFaults
and totalFaults
properties of the same row. footerData
method has 3 parameter. If you don't specify false
as the last parameter then the data will be formatted with respect of formatters of the corresponding columns. Thus it's important that outstandingFaults
and totalFaults
properties will be defined in footerData
.
loadComplete: function() {
var $grid = $(this);
var colSumYearStart = $grid.jqGrid('getCol', "yearStart", false, 'sum') / 2;
var colSumLastMonth = $grid.jqGrid('getCol', "lastMonth", false, 'sum') / 2;
var colSumThisMonth = $grid.jqGrid('getCol', "thisMonth", false, 'sum') / 2;
var colSumOutstandingFaults = $grid.jqGrid('getCol', "outstandingFaults", false, 'sum') / 2;
var colSumOpenFaults = $grid.jqGrid('getCol', "openFaults", false, 'sum') / 2;
var colSumCloseFaults = $grid.jqGrid('getCol', "closeFaults", false, 'sum') / 2;
var colSumTotalFaults = $grid.jqGrid('getCol', "totalFaults", false, 'sum') / 2;
var avePercentage = colSumOutstandingFaults / colSumTotalFaults * 100;
$grid.jqGrid('footerData', 'set', {
name: "Total",
yearStart: colSumYearStart,
lastMonth: colSumLastMonth,
thisMonth: colSumThisMonth,
outstandingFaults: colSumOutstandingFaults,
openFaults: colSumOpenFaults,
closeFaults: colSumCloseFaults,
totalFaults: colSumTotalFaults,
faultsPerc: avePercentage
});
}
Additionally you can consider to use jsonmap
instead of custom formatter:
{ name: 'faultsPerc', formatter: "currency", width: 80,
formatoptions: { suffix: "%", decimalPlaces: 0 },
align: "right", sorttype: "integer",
searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"] },
jsonmap: function (item) {
return Math.round(item.outstandingFaults / item.totalFaults * 100);
}
}
jsonmap
will "gets" the faultsPerc
property from the input data and save it in the local item data. You can then use any standard formatter, like formatter: "currency"
. See https://jsfiddle.net/OlegKi/ttc83khL/9/