【问题标题】:jqGrid dynamic column bindingjqGrid动态列绑定
【发布时间】:2025-12-02 11:05:02
【问题描述】:

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

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

非常感谢您对此方向的任何意见。

【问题讨论】:

  • 你能分享整个代码吗? result.colData 的格式是什么?

标签: jquery jqgrid


【解决方案1】:

在 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);

这对我来说很好。

【讨论】:

  • 这是一个很酷的技巧,这肯定会奏效。这里唯一需要担心的是你需要有两个发布请求来绑定这个......一个用于获取列和获取网格数据。 . 感谢您的意见..
  • 不,您总是会收到一个发布请求...第一个请求是通过 ayax cal 获得的,当您浏览数据时,您会在 jsonstring 中使用列获取数据,它将使用“ someurl/getdata" 来获取数据......我也遇到了问题,一开始我有 2 个请求......但是使用这个解决方案,首先在 jsonstring 中获取数据,然后通过 url 你总是会得到一个请求。
  • 嗨,Bruno,你能分享一下整个代码吗,比如如何在后端生成coldata、colName、coleMode。
  • 嗨,拉克什。我目前没有时间将一些示例代码放到网上。但只需创建一个创建(以 json 格式)colnames、colmodel 和起始数据的函数。如果您在运行时了解所有内容,则可以轻松修改每列的 colmodel。
  • 对于 jqGrid 4.3.1,这个解决方案似乎不起作用。文档说:“如果您使用 jsonstring 获取数据 - 检索数据后,数据类型选项自动设置为本地 - 即(当前)分页将不起作用!”确实分页不起作用。我查看了 jqGrid 源代码,似乎当数据类型为“jsonstring”或“local”时,总记录设置为检索到的记录数。有什么建议吗?
【解决方案2】:

我的解决方案与 Teoman Shipahi 2015 年 8 月的出色回答有点像。

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

我想要做的是隐藏我的 jqGrid 中的一些 JSON 列,并根据这个特定的 JSON 字段是否是重要字段之一来设置一些列的宽度(在本例,SegmentName)。

这是我想出的:

$(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);
        }
    });
});

这是创建 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',
    });
}

希望这会有所帮助。

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      每次添加列时重新创建网格是否可行?您可以将数据存储在本地,每次只需卸载/重新创建网格,使用动态列模型。

      您可能还想查看一些动态显示/隐藏列的演示。根据您拥有的列数,您也许可以在您的应用程序中使用相同的概念。

      这有帮助吗?

      【讨论】:

        【解决方案5】:

        另一种解决方案;

         $("#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;
            }
        

        【讨论】:

          【解决方案6】:
          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;
          }
          

          【讨论】:

            【解决方案7】:

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

            【讨论】:

              【解决方案8】:

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

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

              为我工作!

              【讨论】:

                【解决方案9】:

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

                编辑:还要确保返回的“网格”设置之一是“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'
                    }
                });
                

                【讨论】:

                  【解决方案10】:
                  **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));
                  
                          }
                  

                  【讨论】:

                    【解决方案11】:

                    试试这个

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

                    【讨论】: