jQuery jqGrid 动态列绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2277962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 13:10:03  来源:igfitidea点击:

jqGrid dynamic column binding

jqueryjqgrid

提问by rajesh pillai

How to bind jqGrid dynamically?. The columns are not available at design time but will only be available only at runtime.

如何动态绑定jqGrid?。这些列在设计时不可用,但仅在运行时可用。

In the current jqGrid design the colmodels and other properties needs to be pre-populated for the grid to work correctly.

在当前的 jqGrid 设计中,需要预先填充 colmodels 和其他属性以使网格正常工作。

Any input in this direction is greatly appreciated.

非常感谢在这个方向上的任何投入。

回答by bruno

Try this in document.ready:

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

这对我来说很好。

回答by Mike Gledhill

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

我的解决方案与 Teoman Shipahi 从 2015 年 8 月开始的出色回答大致相同。

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

我有一个返回一组 JSON 数据的 Web 服务,但实际的列可能会随着时间的推移而变化。

What I wanted to do was hidesome 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).

我想要做的是在我的 jqGrid 中隐藏一些 JSON 列,并根据此特定 JSON 字段是否是重要字段之一(在本例中为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:

这是创建 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 allof 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.

显然,我的解决方案的一个缺点是它坚持在将所有JSON 数据显示在网格中之前加载它,而不是一次只加载一页数据。如果您有大量数据,这可能是一个问题。

回答by Maulik

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.

如果有人想使用 mvc 实现此功能,那么http://blog.lieberlieber.com/2010/07/07/asp-net-mvc-and-a-generic-jqquery-grid-jqtgrid/是一个更好的解决方案。

回答by suneelsarraf

function columnsData(Data) {
    var str = "[";
    for (var i = 0; i < Data.length; i++) {
        str = str + "{name:'" + Data[i] + "', index:'" + Data[i] + "', editable: true}";
        if (i != Data.length - 1) {
            str = str + ",";
        }
    }
    str = str + "]";
    return str;
}

回答by Justin Ethier

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?

这有帮助吗?

回答by Teoman shipahi

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;
    }

回答by blazkovicz

I've tried solution suggested by bruno both with json and jsonstring type of data return, it works BUT
if option datastr : colD
  exists- further requests for data do not execute, though filter does work on first retrieved data
  do not exist- double request for data on grid loading

我已经尝试过 bruno 建议的解决方案,包括 json 和 jsonstring 类型的数据返回,但
如果选项datastr
  存在,它可以工作:colD存在- 不会执行对数据的进一步请求,尽管过滤器对第一次检索的数据有效
  不存在- 双重请求用于网格加载数据

回答by morgan_il

I would suggest to execute $("#list").jqGrid('setGridParam',{datatype:'json'});on loadComplete event of the grid - this way the grid will exist for sure. So, just add the following to the grid definition instead of setTimeout(...):

我建议$("#list").jqGrid('setGridParam',{datatype:'json'});在网格的 loadComplete 事件上执行 - 这样网格肯定会存在。因此,只需将以下内容添加到网格定义中,而不是setTimeout(...)

loadComplete : function () {
    $ ("#list").jqGrid('setGridParam',{datatype:'json'});
}

Worked for me !

为我工作!

回答by Mike Manard

If you do it with the import feature, you can still utilize the paging features of jqGrid. Make sure "GetColumnsAndData" returns normal grid data as "data" and the configuration as "grid" (or change these values in "jsonGrid").

如果您使用导入功能,您仍然可以利用 jqGrid 的分页功能。确保“GetColumnsAndData”将普通网格数据返回为“data”,将配置返回为“grid”(或在“jsonGrid”中更改这些值)。

EDIT: Also make sure one of the "grid" settings returned is "url" (with a URL value to retrieve only data).

编辑:还要确保返回的“网格”设置之一是“url”(使用 URL 值仅检索数据)。

$('#grid').jqGridImport({
    imptype: 'json',
    impurl: 'SomeUrl/GetColumnsAndData',
    mtype: 'POST',
    impData: {
        '_search': 'false',
        'sidx': 'loc_short_name',
        'sord': 'asc',
        'page': '1',
        'rows': '25',
        'searchField': '',
        'searchOper': '',
        'searchString': ''
        // Add any additional, custom criteria
    },
    jsonGrid: {
        config: 'grid',
        data: 'data'
    }
});

回答by user2458545

**Dynamic JQGrid From Data Table**
$(document).ready(function () {
        var ColN, ColM, ColD, capEN;
        var sPath = window.location.pathname;
        var sPage = sPath.substring(sPath.lastIndexOf('/') + 1);
        //alert(sPage);
        $.ajax({
            url: sPage+'?method=getGridHeadData',
            type: "POST",
            contentType: "application/json; charset=utf-8",
            data: {},
            dataType: "json",
            success: function (data, st) {
                if (st == "success") {
                    ColN = data.rowsHead;//jqgrid heading data
                    ColM = data.rowsM; // its column model
                    ColD = data.rows; // Data
                    createGrid();
                }
            },
            error: function () {
                alert("Error with AJAX callback");
            }
        });

        function createGrid() {
            jQuery("#AccountingCodesGrid").jqGrid({

                datatype: 'json',
                url: sPage+'?method=getGridData',
                mtype: 'POST',
                ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
                serializeGridData: function (postData) {
                    return JSON.stringify(postData);
                },
                jsonReader: { repeatitems: false, root: "rows", page: "page", total: "total", records: "records" },

                //data: ColD,
                colNames: ColN,
                colModel: ColM,
                loadonce: true,
                pager: jQuery('#pager'),
                rowNum: 5,
                rowList: [5, 10, 20, 50],
                viewrecords: true
            })


        }
        jQuery("#AccountingCodesGrid").jqGrid('navGrid', '#Pager', { edit: false, add: false, del: false }, null, null, true, { multipleSearch: true });
        var height = $(window).height();


    });

the code behind
 **In page load..................................................................**

if (Request.QueryString["method"] == "getGridData")
            {
                Request.InputStream.Position = 0;
                StreamReader ipStRdr = new StreamReader(Request.InputStream);
                string json = ipStRdr.ReadToEnd();
                JavaScriptSerializer jser = new JavaScriptSerializer();
                Dictionary<string,> dict = jser.Deserialize<dictionary><string,>>(json);

                getGridData(int.Parse(dict["page"].ToString()), int.Parse(dict["rows"].ToString()), bool.Parse(dict["_search"].ToString()), dict["sord"].ToString());
                Response.End();
            }
            else if (Request.QueryString["method"] == "getGridHeadData")
            {
                getGridHeadData();
                Response.End();
            }

**Method to get data in json form----------------------------------------------------**
public void getGridData(int page, int rows, bool _search, string sord)
        {
            DataTable dtRecords = dtSource;// Data Table
            int recordsCount = dtRecords.Rows.Count;

            JqGridData objJqGrid = new JqGridData();
            objJqGrid.page = page;
            objJqGrid.total = ((recordsCount + rows - 1) / rows);
            objJqGrid.records = recordsCount;
            objJqGrid.rows = ConvertDT(dtRecords);

            List<string> liob = new List<string>();
            foreach (DataColumn column in dtRecords.Columns)
            {
                liob.Add(column.ColumnName);
            }
            objJqGrid.rowsHead = liob;

            List<object> colcontetn = new List<object>();
            foreach (var item in liob)
            {
                JqGridDataHeading obj = new JqGridDataHeading();
                obj.name = item.ToString();
                obj.index = item.ToString();
                colcontetn.Add(obj);
            }
            objJqGrid.rowsM = colcontetn;

            JavaScriptSerializer jser = new JavaScriptSerializer();
            Response.Write(jser.Serialize(objJqGrid));

        }