【问题标题】:Is it possible to modify the colModel after data has loaded with jqgrid?使用jqgrid加载数据后是否可以修改colModel?
【发布时间】:2011-07-20 00:33:48
【问题描述】:

我有一个 jqGrid,我需要在加载数据之后更改模型,但在它被解析到网格之前。换句话说,我想我想在 loadComplete 处理程序中执行此操作。我看到了这种方法:Setting JqGrid's colName and colModel from JSON data,但是我已经编写了一堆网格,它们使用“使用 jqGrid 加载数据”方法,而不是那里使用的“预加载数据并将其传递给 jqGrid”,并且我希望避免重新编码,或者使这个与众不同。

(隐藏和显示隐藏的列也不实用。)

这可能吗?

更多细节:

基本上,在我看到数据之前,我不知道我需要哪些列。假设我按州显示流量:

Date      CA     WA     NY    MN
4/20      100    90     85    72
4/21       95    85     89    70

只有显示四个状态的空间,但数据中可能有更多(或者可能更少),所以我希望它们按流量顺序列出。现在,数据进来如下:

{
date : 4-20,
ca : 100,
wa : 90,
ny : 85,
mn : 72
hi : 56,
il : 30
},
{
date : 4-21,
ca : 95,
wa : 85, // note: for a given row, a column might be relatively lower
ny : 89, // than another. The column order is based on the overall
mn : 70
hi : 60,
il : 45
}

也可以是:

{
date : 4-20,
ny : 110,
hi : 95,
il : 90,
wa : 80
}

我尝试设置 state1、state2、state3、state4 等列,然后使用 jsonmap 重新映射它们,但没有成功。

loadonce = true,数据类型 = json

【问题讨论】:

  • 您能否更详细地描述您想要在 colModel 中进行哪些修改。有些修改很容易,有些则不那么容易,但有些修改如果不重新创建整个网格是不可能的。因此,要回答您的问题,您应该发布更多详细信息。如果您发布您使用的 jqGrid 示例,这可能会有所帮助。至少需要知道数据类型以及是否使用loadonce:true
  • @sprugman:这是一个很好的例子。现在我大致了解您的问题。是否有许多列包含相同类型(如示例中的整数)?
  • 是的,需要动态的列都具有相同的结构。
  • @sprugman:如果没人能解决你的问题,我明天会尝试提出一些解决方法。我觉得你的问题很有趣,所以我 +1,但今天我很忙。
  • 好的,谢谢奥列格。 (目前,我正在执行两个查询:一个只是获取状态(未按日期细分),然后我使用它来构建模型,并执行第二个查询,返回更多详细信息。)

标签: jqgrid


【解决方案1】:

我找到了一种似乎可行的方法。

我的解决方案的想法如下。您使用colModel 有许多隐藏列,其中包含虚拟名称,例如“cm0”、“cm1”、“cm2”……所有列都具有与您的情况相同的数据。为了更轻松地填充数据,我使用自 jqGrid 3.8.2 以来存在的列模板:

var mygrid=jQuery("#list"),
    cmIntTemplate = {
        width:50,
        sorttype:"int",
        formatter:"integer",
        align:"right",
        hidden:true
    },
    cm = [
        // here we define the first columns which we always has
        // the list can be empty or has some columns with
        // the properties other as the rest (without cmIntTemplate)
        {name:"date",label:"Date",key:true,width:100, fixed:true,
         formatter:'date',formatoptions:{srcformat:"m-d",newformat:"m/d"}}
    ], maxCol = 30, dummyColumnNamePrefix = "cm";

// Add dummy hidden columns. All the columns has the same template
for (i=0;i<maxCol;i++) {
    cm.push({name:dummyColumnNamePrefix+i,template:cmIntTemplate});
}

之后我以标准方式创建 jqGrid,但使用 jsonReader 使用 page as function

jsonReader: {
    repeatitems: false,
    page: function (obj) {
        // ------------------------
        // here I add the main code
        // ------------------------
        return obj.page;
    }
}

jsonReader.page 中的函数返回与默认jsonReader 相同的值,但我使用带函数的方式,因为该函数将在读取 JSON 数据的主要内容之前直接调用。在代码内部,我获取第一行数据并使用它的属性名称来填充相应列的jsonmap 属性并设置列名称。此外,我制作了一些显示所有 JSON 数据可见所需的虚拟列,并隐藏了其余的虚拟列。应该做的最后一件事是校正先前计算的网格宽度。所以网格看起来像这样:

或者像这样

取决于 JSON 输入数据。

page函数的代码如下:

page: function (obj) {
    var rows = obj.rows, colModel = mygrid[0].p.colModel,
        cmi, iFirstDummy, firstRow, prop,
        orgShrinkToFit, isFound,
        showColNames = [], hideColNames = [];

    if (typeof(rows) === "undefined" || !$.isArray(rows) || rows.length === 0) {
        // something wrong need return
        return obj.page;
    }

    // find the index of the first dummy column
    // in the colModel. If we use rownumbers:true,
    // multiselect:true or subGrid:true additional
    // columns will be inserted at the begining
    // of the colModel
    iFirstDummy = -1;
    for(i=0;i<colModel.length;i++) {
        cmi = colModel[i];
        if (dummyTestRegex.test(cmi.name)) {
            iFirstDummy = i;
            break;
        }
    }
    if (iFirstDummy === -1) {
        // something wrong need return
        return obj.page;
    }

    orgShrinkToFit = clearShrinkToFit();

    // we get the first row of the JSON data
    firstRow = rows[0];
    for (prop in firstRow) {
        if (firstRow.hasOwnProperty(prop)) {
            // we will use the properties name of the first row
            // as the names of the column headers of the grid

            // find column index having prop as the name
            isFound = false;
            for(i=0;i<colModel.length;i++) {
                cmi = colModel[i];
                if (cmi.name === prop) {
                    isFound = true;
                    showColNames.push(prop);
                    break;
                }
            }
            if(!isFound) {
                // labels defines the column names
                cmi = colModel[iFirstDummy];
                showColNames.push(cmi.name);
                mygrid.jqGrid('setLabel',cmi.name,prop);

                // because of bug in jqGrid with calculation of width
                // we have to reset the width
                cmi.width = cmIntTemplate.width;

                // we set jsonmap which jqGrid will use instead
                // of dummy column names to read all row data
                cmi.jsonmap = prop;
                iFirstDummy++;
            }
        }
    }

    // fill the list of unused columns
    for(i=0;i<colModel.length;i++) {
        cmi = colModel[i];
        if ($.inArray(cmi.name, showColNames) === -1 && dummyTestRegex.test(cmi.name)) {
            hideColNames.push(cmi.name);
        }
    }
    mygrid.jqGrid('showCol',showColNames);
    mygrid.jqGrid('hideCol',hideColNames);

    setGridWidthAndRestoreShrinkToFit(orgShrinkToFit);

    return obj.page;
}

page 函数内部,我使用了小的辅助函数

var clearShrinkToFit = function() {
        // save the original value of shrinkToFit
        var orgShrinkToFit = mygrid.jqGrid('getGridParam','shrinkToFit');
        // set shrinkToFit:false to prevent shrinking
        // the grid columns after its showing or hiding
        mygrid.jqGrid('setGridParam',{shrinkToFit:false});
        return orgShrinkToFit;
    },
    setGridWidthAndRestoreShrinkToFit = function(orgShrinkToFit) {
        // calculate the new grid width
        var width=0, i=0, headers=mygrid[0].grid.headers, l=headers.length;
        for (;i<l; i++) {
            var th = headers[i].el;
            if (th.style.display !== "none") {
                width += $(th).outerWidth();
            }
        }

        // restore the original value of shrinkToFit
        mygrid.jqGrid('setGridParam',{shrinkToFit:orgShrinkToFit});

        // set the grid width
        mygrid.jqGrid('setGridWidth',width);
    },
    dummyTestRegex = new RegExp(dummyColumnNamePrefix+"(\\d)+");

你可以看到here的工作演示。

更新Another answerthe demo 展示了如何创建具有另一种输入数据格式的网格:[[]、[]、...](数组数组)-矩阵。

【讨论】:

  • @sprugman:不客气!在我发现你的问题很有趣之前我是怎么说的,所以我必须实施。 :-)
  • @sprugman:我回答了另一个非常接近的问题并创建了相应的演示,这是我为您创建的演示的修改。我认为这对您来说可能也很有趣。请参阅我的回答的已更新部分。
  • @sprugman:我对演示的代码进行了一些改进,并替换了我在答案中发布的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-11
  • 1970-01-01
  • 2012-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多