jqgrid: several questions - matrix display

2019-01-25 01:07发布

问题:

I have data of matrix stored in table as below tables:

  • MatrixDimensions - MatrixId, NoOfRows, NoOfCol
  • MatrixValues - MatrixId, RowNo, ColNo, Value

How can I make jqGrid to take no. of rows & columns dynamically and also display the serialized data in matrix? Is there a direct way or will I have to implement for loops to upload the data in matrix?

Can I display rows as columns and columns as rows (so having column headers vertically aligned)?

Can I enable only inline editing and disable form based editing?

回答1:

I just wrote the answer to another question where I described how to create the grid with dynamic number of columns (number of rows is always dynamic in jqGrid). It seems to me this way you can display any matrix. In you case you can probably make the code simpler because you can use generic column names like "1", "2", etc. (or "Col. 1", "Col. 2", etc.) and so on.

I modified the code so that it uses array of arrays (matrix) instead of the array on objects with named properties. So jqGrid will looks like this:

or this:

depending on the input JSON data.

The full demo can be found here. The full JavaScript code of the demo you can find below:

var mygrid=jQuery("#list"),
    cmTxtTemplate = {
        width:40,
        align:"center",
        sortable:false,
        hidden:true
    }, currentTemplate = cmTxtTemplate, i,
    cm = [], maxCol = 30, dummyColumnNamePrefix = "", //"Col. ",
    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,width) {
        // restore the original value of shrinkToFit
        mygrid.jqGrid('setGridParam',{shrinkToFit:orgShrinkToFit});
        mygrid.jqGrid('setGridWidth',width);
    },
    dummyTestRegex = new RegExp(dummyColumnNamePrefix+"(\\d)+"),
    counter = 1;

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

mygrid.jqGrid({
    url:'Matrix1.json',
    datatype: "json",
    // colNames will be set based on the properties for JSON input
    colModel:cm,
    height:"auto",
    rownumbers:true,
    loadonce:true,
    gridview: true,
    rowNum: 1000,
    sortname:"",
    jsonReader: {
        cell: "",
        id: function (obj) {
            return "id"+counter++;
        },
        page: function (obj) {
            var rows = obj.rows, colModel = mygrid[0].p.colModel,
                cmi, width = 0, iFirstDummy, cols, orgShrinkToFit,
                showColNames = [], hideColNames = [];

            if (typeof(rows) === "undefined" || !(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
            cols = rows[0].length;

            // fill the list of unused columns
            for(i=0;i<colModel.length;i++) {
                cmi = colModel[i];
                if (i<iFirstDummy+cols) {
                    cmi.width = currentTemplate.width;
                    showColNames.push(cmi.name);
                } else {
                    hideColNames.push(cmi.name);
                }
            }
            mygrid.jqGrid('showCol',showColNames);
            mygrid.jqGrid('hideCol',hideColNames);
            setGridWidthAndRestoreShrinkToFit(orgShrinkToFit,
                cols*currentTemplate.width);

            return obj.page;
        }
    }
});
$("#readJson1").click(function() {
    mygrid.jqGrid('setGridParam',
                  {datatype:'json',page:1,url:'Matrix1.json'})
          .trigger('reloadGrid');
});
$("#readJson2").click(function() {
    mygrid.jqGrid('setGridParam',
                  {datatype:'json',page:1,url:'Matrix2.json'})
          .trigger('reloadGrid');
});

The simplest way to transpose the matrix (reflect it over its main diagonal) is on the server. If you can't do this, you can create and fill the transposed matrix inside of page function (see my code above) and just replace the row part of the obj with the transposed matrix.