在使用jqgrid加载数据后是否可以修改colModel?

时间:2011-03-21 21:17:21

标签: jqgrid

我有一个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,datatype = json

1 个答案:

答案 0 :(得分:7)

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

我的解决方案的想法如下。您使用具有许多隐藏列的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数据,并隐藏其余的虚拟列。应该做的最后一件事是校正先前计算的网格宽度。所以网格看起来像这样:

enter image description here

或者像这样

enter image description here

取决于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 answer the demo显示了如何创建具有其他输入数据格式的网格:[[],[],...](数组数组) - 矩阵。