开发者

Inserting markup into hidden jqGrid column

开发者 https://www.devze.com 2023-01-11 11:50 出处:网络
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 i

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

0

精彩评论

暂无评论...
验证码 换一张
取 消