Got jqGrid up and running nicely where I've got a hidden field that contains some markup, just a table of data, and when I hover over a grid row the markup for the hidden column in that row appears in a tooltip. I want to be able to duplicate grid items and in doing so I want to clear the grid and repopulate with only the duplicated records and the original.
Unfortunately, i'm getting this issue when reloading the grid:
Message: 's.grid.headers[...].width' is null or not an object
Line: 91
Char: 390
Code: 0
URI: http://localhost:51325/Scripts/jquery.jqGrid.min.js
Here's my grid definition:
$('#RequestGrid').jqGrid({
url: GetUrl(),
datatype: 'json',
mtype: 'POST',
colNames: ['ID', 'AOM', 'Start Date', 'End Date', 'Coordinator 1', 'Coordinator 2', 'Driver?', 'Status', 'Assigned To', 'RequestHours'],
colModel: [
{ name: 'ResourceRequestID', index: 'ResourceRequestID', width: 20, key: true },
{ name: 'AOM', index: 'AOM.Surname', width: 70 },
{ name: 'StartDate', index: 'StartDate', width: 50 },
{ name: 'EndDate', index: 'EndDate', width: 50 },
{ name: 'Coordinator1', index: 'Coordinator.Surname', width: 60 },
{ name: 'Coordinator2', index: 'Coordinator1.Surname', width: 60 },
{ name: 'DriverPreference', index: 'DriverPreference.Description', width: 40 },
{ name: 'Status', index: 'Status', sortable: false, width: 40 },
{ name: 'AssignedResourceID', index: 'AssignedResourceID', width: 50 },
{ name: 'RequestHours', index: 'RequestHours', hidden: true }
],
...
loadui: 'block',
width: 750,
ondblClickRow: function (rowid, iRow, iCol) {
window.location = '/Request/Edit/' + rowid;
},
gridComplete: function() {
$("tr.jqgrow").mouseover(function(e) {
var requestHours = $(this).find('td').eq(9).html();
$(this).tipTip({ activation: "hover", edgeOffset: 5, content: requestHours, keepAlive: false, fadeIn: 0, maxWidth: "250px" });
});
}
});
The markup for the hidden field is built in my controller as below:
public string BuildRequestPlan(ResourceRequest req)
{
string requestPlan = "<p>Request #" + req.ResourceRequestID.ToString() + "</p>";
requestPlan += "<p>Location: " + req.Location.LocationName + "</p>";
requestPlan += "<table id=toolTipAvailability><tr><td>Day</td><td>8-9</td><td>9-10</td><td>10-11</td><td>11-12</td><td>12-1</td><td>1-2</td><td>2-3</td><td>3-4</td><td>4-5</td><td>5-6</td><td>6-7</td><td>7-8</td><td>8-9</td><td>9-10</td><td>O/S</td></tr>";
string[] days = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
int[] hrs = { 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22 };
for (int day = 1; day <= days.Length; day++)
{
requestPlan += "<tr><td oncontextmenu=return false;>" + days[day - 1] + "</td>";
for (int hour = 8; hour < 23; hour++)
{
requestPlan += "<td class=toolTipAvailabilityCell day=" + day + " hour=" + hour + ">";
var requestHour = req.RequestHours.SingleOrDefault(h => h.Hour == hour && h.WeekDay == day);
if (requestHour != null)
{
requestPlan += requestHour.Minutes.ToString();
}
requestPlan += "</td>";
}
requestPlan += "</tr>";
}
requestPlan += "</table>";
return requestPlan;
}
This method is called for each item in the list of duplicates:
[HttpPost]
public JsonResult Duplicate(int cloneRequestID, int cloneCount)
{
ResourceRequest resourceRequest = this._resourceRequestService.GetByID(cloneRequestID);
// get the assignedResourceID of resourceRequest to clone
int? assignedResourceID = resourceRequest.AssignedResourceID;
// nullify the assignedResourceID
resourceRequest.AssignedResourceID = null;
List<ResourceRequest> clones = new List<ResourceRequest>();
for (int i = 0; i < cloneCount; i++)
{
ResourceRequest temp = (ResourceRequest)resourceRequest.Clone();
this._resourceRequestService.Add(temp);
clones.Add(temp);
}
// reinstate the assignedResourceID
resourceRequest.AssignedResourceID = assignedResourceID;
// add original erquest to clones collection
clones.Add(resourceRequest);
try
{
this._unitOfWork.Commit();
int totalRecords = clones.Count();
int totalPages = (int)Math.Ceiling((float)totalRecords / (float)10);
var jsonData = from req in clones
select new
{
ResourceRequestID = req.ResourceRequestID.ToString(),
AOM = string.Format("{0}, {1}", req.AOM.Surname, req.AOM.Forename),
StartDate = req.StartDate.ToString("dd/MM/yyyy"),
EndDate = req.EndDate.ToString("dd/MM/yyyy"),
Coordinator1 = string.Format("{0}, {1}", req.Coordinator.Surname, req.Coordinator.Forename),
Coordinator2 = req.SecondCoordinatorID == null ? "N/A" : string.Format("{0}, {1}", req.Coordinator1.Surname, req.Coordinator1.Forename),
DriverPreference = req.DriverPreference.Description,
Status = req.RequestCancelledDate.HasValue ? "Cancelled" : req.AssignedResourceID.HasValue ? "Assigned" : "Unassigned",
AssignedResourceID = req.Resource == null ? "N/A" : req.Resource.Employee.FullName,
RequestHours = BuildRequestPlan(req)
};
return Json(JsonConvert.SerializeObject(jsonData));
}
catch (Exception e)
{
var data = new { error = e.Message };
return Json(data);
}
}
This is how I rebind the grid:
$.post('/Request/Duplicate', { cloneRequestID: $('#cloneRequestID').val(), cloneCount: $('#cloneCount').val() }, function (data) {
$('#RequestGrid').clearGridData(true);
var jsonData = $.parseJSON(data);
$('#RequestGrid').addRowData('ResourceRequestID', jsonData);
});
I tried returning just an empty ta开发者_高级运维ble e.g. <table><tr></tr></table>
and it worked but when I added an empty cell it stopped working so something is going wrong with the markup.
Has anyone encountered a similar issue? Any thoughts?
Thanks
Fixed this issue by wrapping a HTML comment around the markup in the BuildRequestPlan method. When it comes to passing the markup to the tooltip I just strip out the comments. It's unorthodox but it works.
First of all I would be recommend you to use userdata to save and additional information to the jqGrid. The data saved in userdata can be absolutely free. It can be for example an array with you HTML code fragments or an object with ResourceRequestID
values as properties and the corresponding HTML code fragments as the value. So with jQuery("RequestGrid").getGridParam('userData')
you can get the reference to the data any time and with userData
parameter you can set the data directly for a new jqGrid.
The main advantage of the usage of userData
is that the data will be not placed somewhere as a part of HTML code like you do this now. So the data will be not encoded in any way and it can have any contain without restrictions.
If you want to refresh the data in jqGrid you can either just use jQuery("RequestGrid").trigger("reloadGrid")
or get the grid data with jQuery("RequestGrid").getGridParam('data')
, then create new grid with data
as a parameter and datatype: 'local'
. Then you can change datatype
from 'local'
to 'json'
after the grid is created (if you really want to have 'json'
and not 'local'
grid). It can be a simple way to duplicate the data. Moreover, I am not sure, but probably the usage of loadone: true
can be interesting for you (look at JqGrid Reload not working if you decide to use this).
精彩评论