I'm using jqGrid 4.5.2 and jquery 2.2.2. As it is it still displays the grid like normal but no trees. Digging in the browser debugger I found that it was setting a style of left:NaNpx;. I'm not sure why it's setting the NaN. If I manually change that to 15px, the arrow appears, but the rows aren't under it, nor does it hide the child rows when clicking the arrow.
My code:
<table id="TabAdminAgentsGrid" class="scroll" cellpadding="0" cellspacing="0"></table>
var grid = jQuery("#TabAdminAgentsGrid");
grid.jqGrid({
url: '/Admin/AgentsGrid',
altRows: true,
altclass: 'myAltRowClass',
autowidth: true,
datatype: 'json',
mtype: 'POST',
colNames: ['Agency', 'Name', 'Status', 'City', 'State', 'Contact'],
colModel: [
{ name: 'AgencyCode', index: 'AgencyCode', width: 18, align: 'left', sortable: true, resizable: true, sorttype: 'text', autoFit: true, stype: 'text' },
{ name: 'AgencyName', index: 'AgencyName', width: 40, align: 'left', sortable: true, resizable: true, classes: 'defaultpointer', sorttype: 'text', autoFit: true, stype: 'text' },
{ name: 'StatusCode', index: 'StatusCode', width: 10, align: 'left', sortable: true, resizable: true, classes: 'defaultpointer', formatter: function (cellvalue, options, rowObject) { if (cellvalue === 'S') { return '<span style="background-color: #e2e0e0; width: 100%;">Suspended</span>'; } else if (cellvalue === 'I') { return '<span style="background-color: #e2e0e0; width: 100%;">Inactive</span>'; } else return 'Active'; } },
{ name: 'City', index: 'City', width: 30, align: 'left', sortable: true, resizable: true, classes: 'defaultpointer' },
{ name: 'State', index: 'State', width: 8, align: 'left', resizable: true, classes: 'defaultpointer' },
{ name: 'ContactName', index: 'ContactName', width: 30, align: 'left', resizable: true, classes: 'defaultpointer' }],
height: '400px',
width: '800px',
treeGrid: true,
treeGridModel: 'adjacency',
ExpandColumn: 'AgencyCode',
cmTemplate: { width: 70 },
rowNum: 15,
rowList: [15, 20, 50],
sortname: "AgencyCode",
sortorder: "desc",
viewrecords: true,
caption: '',
pager: "#TabAdminAgentsGridPager",
postData: { searchParam: $("#AdminSearch").val() },
emptyrecords: "No quotes have been submitted",
onSelectRow: function (ids) {
if (ids != null) {
var data = $("#TabAdminAgentsGrid").getRowData(ids);
GetAgency(data.AgencyCode);
}
},
loadComplete: function () { $("#TabAdminAgentsGrid").setGridWidth($('#subTabs').width() - 30, true); }
}).navGrid($('#TabAdminAgentsGridPager'), { edit: false, add: false, del: false, search: false });
My Data, I created a class for the cell and tree info and one for the cell fields. Agencies will only ever have one level below them:
public class JSONAgent
{
public string AgencyCode { get; set; }
public JSONAgentCell cell { get; set; }
public string level { get; set; }
public string parent { get; set; }
public bool isLeaf { get; set; }
public bool expanded { get; set; }
public bool loaded { get; set; }
}
public class JSONAgentCell
{
public string AgencyCode { get; set; }
public string AgencyName { get; set; }
public string StatusCode { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ContactName { get; set; }
}
List<JSONAgent> agents = new List<JSONAgent>();
foreach(var agent in agencyRecords)
{
JSONAgent ag = new JSONAgent();
ag.i = agent.AgencyCode;
ag.cell = new JSONAgentCell();
ag.cell.AgencyCode = agent.AgencyCode;
ag.cell.AgencyName = agent.AgencyName;
ag.cell.StatusCode = agent.StatusCode;
ag.cell.City = agent.City;
ag.cell.State = agent.State;
ag.cell.ContactName = agent.ContactName;
if(string.IsNullOrWhiteSpace(agent.ParentAgencyCode) || agent.ParentAgencyCode == agent.AgencyCode)
{
ag.level = "0";
ag.parent = null;
ag.isLeaf = false;
ag.expanded = false;
ag.loaded = true;
}
else
{
ag.level = "1";
ag.parent = agent.ParentAgencyCode;
ag.isLeaf = true;
ag.expanded = false;
ag.loaded = true;
}
agents.Add(ag);
}
var jsonData = new
{
total = totalPages,
page = page,
records = totalrecords,
rows = agents.ToArray()
};
return Json(jsonData);
Any help that can point me in the right direction is very much appreciated. I've been banging my head against a wall on this for a couple of days. Thank you.
Edit: Here is what the json looks like that is getting passed to the grid(dummy up'd the data a little):
{
"total": 1,
"page": 1,
"records": 4595,
"rows": [
{
"AgencyCode": "077112",
"cell": {
"AgencyCode": "077112",
"AgencyName": "Person McPerson",
"StatusCode": "A",
"City": "Stockton",
"State": "CA",
"ContactName": "Person McPerson"
},
"level": "0",
"parent": null,
"isLeaf": false,
"expanded": false,
"loaded": true
},
{
"AgencyCode": "077112-1",
"cell": {
"AgencyCode": "077112-1",
"AgencyName": "Anon Plus Insurance",
"StatusCode": "A",
"City": "Stockton",
"State": "CA",
"ContactName": "Person McPerson"
},
"level": "1",
"parent": "077112",
"isLeaf": true,
"expanded": false,
"loaded": true
}
]
}
To solve the problem you will need to configure your jsonReader. The cell property in your response is reserved word in jsonReader. cell is used when repeatitems is true, but in your case you do not need repeatitems. Since grid try to autodetect repeatitems, it find cell property, but cell is not array - it is object. You will need to explicitly set repeatitems in jsonReader to false.
There are a lot of solutions (which I tested in 4.5.2 version and they work)
1.in grid options do
grid.jqGrid({
...
jsonReader : {
repeatitems : false
},
...
});
2.In response instead of property cell write some other word like cells
Some notes: In order everything to be correct you will need to set unique id either in jsonReader or as key: true property in colModel. It is a good idea too to set jsonmap in colModel.
All these properties are described into the documentation.