jqGrid dynamic column binding

Solution 1:

Try this in document.ready:

$.ajax(
    {
       type: "POST",
       url: "SomeUrl/GetColumnsAndData",
       data: "",
       dataType: "json",
       success: function(result)
       {
            colD = result.colData;
            colN = result.colNames;
            colM = result.colModel;

            jQuery("#list").jqGrid({
                jsonReader : {
                    cell: "",
                    id: "0"
                },
                url: 'SomeUrl/Getdata',
                datatype: 'jsonstring',
                mtype: 'POST',
                datastr : colD,
                colNames:colN,
                colModel :colM,
                pager: jQuery('#pager'),
                rowNum: 5,
                rowList: [5, 10, 20, 50],
                viewrecords: true
            })
       },
       error: function(x, e)
       {
            alert(x.readyState + " "+ x.status +" "+ e.msg);   
       }
    });
setTimeout(function() {$("#list").jqGrid('setGridParam',{datatype:'json'}); },50);

this work fine for me.

Solution 2:

My solution is kind of the same idea as Teoman Shipahi's excellent answer from August 2015.

I have a web service which returns a set of JSON data, but the actual columns could vary over time.

What I wanted to do was hide some of the JSON columns in my jqGrid, and set the widths of some of the columns based on if this particular JSON field was one of the important fields (in this case, SegmentName).

Here's what I came up with:

$(function () {
    //  Load the JSON data we'll need to populate our jqGrid

    // ID of a [Segment_Set] record in our database (which our web service will load the data for.
    var SegmentSetId = 12345;

    $.ajax(
    {
        type: "GET",
        url: "/Service1.svc/LoadSegmentAttributes/" + SegmentSetId,
        dataType: "json",
        success: function (JSONdata) {
            // 
            //  Work through our JSON data, and create the two arrays needed by jqGrid 
            //  to display this dynamic data.
            //
            var listOfColumnModels = [];
            var listOfColumnNames = [];

            for (var prop in JSONdata[0]) {
                if (JSONdata[0].hasOwnProperty(prop)) {
                    //  We have found one property (field) in our JSON data.
                    //  Add a column to the list of Columns which we want our jqGrid to display
                    listOfColumnNames.push(prop);

                    //  How do we want this field to be displayed in our jqGrid ?
                    var bHidden = (prop == "SegmentID") || (prop == "SegmentSequenceInx");
                    var columnWidth = (prop == "SegmentName") ? 200 : 50;

                    listOfColumnModels.push({
                        name: prop,
                        width: columnWidth,
                        sortable: true,
                        hidden: bHidden
                    });
                }
            }

            //  Now we have our JSON data, and list of Column Headings and Models, we can create our jqGrid.
            CreateJQGrid(JSONdata, listOfColumnModels, listOfColumnNames);
        }
    });
});

And here's the function which creates the jqGrid:

function CreateJQGrid(JSONdata, listOfColumnModels, listOfColumnNames) {
    //  After loading the JSON data from our webservice, and establishing the list of 
    //  Column Names & Models, we can call this function to create the jqGrid.
    $("#SegmentRulesGrid").jqGrid({

        datatype: "local",
        data: JSONdata,
        localReader: {
            id: "SegmentID",        //  The Primary Key field in our JSONdata 
            repeatitems: false
        },
        mtype: "GET",
        colNames: listOfColumnNames,
        colModel: listOfColumnModels,
        rowNum: 15,
        loadonce: true,
        gridview: true,
        autowidth: true,
        height: 350,
        pager: '#pager',
        rowList: [15, 30, 100, 300],
        rownumbers: true,
        viewrecords: true,
        caption: 'Segment Rules',
    });
}

Hope this helps.

Obviously one downside to my solution is that it insists that you load all of your JSON data before displaying it in a grid, rather than loading just one page of the data at a time. This could be a problem if you have a huge amount of data.

Solution 3:

If somebody wants to implement this functionality using mvc then http://blog.lieberlieber.com/2010/07/07/asp-net-mvc-and-a-generic-jqquery-grid-jqtgrid/ is a nicer solution.

Solution 4:

Is it feasible to recreate the grid each time a column is added? You could store the data locally and just Unload / Recreate the grid each time, using a dynamic column model.

You may also want to look at some of the demos that show/hide columns dynamically. Depending upon how many columns you have, you might be able to use the same concept in your application.

Does that help?

Solution 5:

Yet another solution;

 $("#datagrid").jqGrid({
        //url: "user.json",
        //datatype: "json",
        datatype: "local",
        data: dataArray,
        colNames:getColNames(dataArray[0]),
        colModel:getColModels(dataArray[0]),
        rowNum:100,
        loadonce: true,
        pager: '#navGrid',
        sortname: 'SongId',
        sortorder: "asc",
        height: "auto", //210,
        width:"auto",
        viewrecords: true,
        caption:"JQ GRID"
    });

    function getColNames(data) {
        var keys = [];
        for(var key in data) {
            if (data.hasOwnProperty(key)) {
                keys.push(key);
            }
        }

        return keys;
    }

    function  getColModels(data) {
        var colNames= getColNames(data);
        var colModelsArray = [];
        for (var i = 0; i < colNames.length; i++) {
            var str;
            if (i === 0) {
                str = {
                    name: colNames[i],
                    index:colNames[i],
                    key:true,
                    editable:true
                };
            } else {
                str = {
                    name: colNames[i],
                    index:colNames[i],
                    editable:true
                };
            }
            colModelsArray.push(str);
        }

        return colModelsArray;
    }