【问题标题】:Custom aggregation/grouping in jqGridjqGrid中的自定义聚合/分组
【发布时间】:2011-05-09 19:43:13
【问题描述】:

概述

我需要以某种方式自定义 jqGrid 插件,通过巧妙的技巧、hack 或插件修改,以支持以下类型的聚合/分组。

我将非常感谢 jqGrid 社区关于如何实现这一点的一些想法。

详情

聚合/分组的工作方式如下。

最初向用户显示的数据网格如下所示,按照“第 1 列”进行分组。注意超链接(例如“+5”);这些超链接表示“折叠”的行,其中这些行中的所有数据对于所有列的值都相同,但带有超链接的列除外。

例如,通过单击“+5”链接,表格会展开以显示之前折叠为 1 的 5 行(替换包含“+5”链接的折叠行)。请注意,现在展开的行在第 2 列中都有唯一值,该列之前有“+5”链接。

关于如何实现这一点的任何想法?这可以与任何其他网格插件一起使用吗?

【问题讨论】:

  • 您描述点击“+5”链接后可以展开网格行。以后是否可以将行折叠回来?我在您的建议中看到没有执行此操作的界面。
  • 没有。一旦行展开,它们就不能再次折叠。谢谢。
  • 你想如何处理交叉口?例如,您可以在一个列中有一组 5 个常见值,而在另一列中有 5 个。如果第一组中有 3 行出现在第二组中,你会显示什么?
  • @peteorpeter 对于第一个问题:如屏幕截图所示,一行可以有多个分组(即“+3”和“+2”在一行中)。对于第二个问题:结果集被分组在一个特定的列上,该列仅包含该列的唯一行;有了这个约束,所有其他列都被分组/折叠。
  • @Jack B. 那么根据您处理列的 order 是否会有不同的分组模式?例如,如果您从左到右,最左边的列将“纯粹”对所有具有共同值的行进行分组。当您查看下一列时,您已经折叠了行。当您从左到右进行分组时,为每列设置的值会越来越小。这是可取的吗?似乎它可能具有误导性 - 计数不会反映整个列的共性,而是值的共性尚未按前一列分组

标签: javascript jquery jquery-ui jquery-plugins jqgrid


【解决方案1】:

jqGrid 不直接支持你需要的这种分组,所以必须实现某种手动分组。

分组本身应该在服务器上完成,服务器响应应该包含扩展行和折叠行。我不太明白一组扩展链接应该如何工作,所以我描述了如何通过每行一个链接来实现分组。另一方面,我决定实现之前展开的行的折叠。我这样做是针对 JSON 数据中包含的其他信息。

让我们服务器生成以下 JSON 数据:

{
  "total": 1,
  "page": 1,
  "records": 15,
  "rows" : [
    {"id":"1", "collapseTo":{"id":"6","colName":"column2"}, "expandTo":null, "column1":"534345345", "column2":"3523423423", "column3":"8563564", "column4":"75683", "column5":"4756436", "column6":"87689768", "column7":"8755"},
    {"id":"2", "collapseTo":{"id":"6","colName":"column2"}, "expandTo":null, "column1":"534345345", "column2":"545345343", "column3":"8563564", "column4":"75683", "column5":"4756436", "column6":"7689768", "column7":"8755"},
    {"id":"3", "collapseTo":{"id":"6","colName":"column2"}, "expandTo":null, "column1":"534345345", "column2":"4234235", "column3":"8563564", "column4":"75683", "column5":"4756436", "column6":"7689768", "column7":"8755"},
    {"id":"4", "collapseTo":{"id":"6","colName":"column2"}, "expandTo":null, "column1":"534345345", "column2":"3242323", "column3":"8563564", "column4":"75683", "column5":"4756436", "column6":"7689768", "column7":"8755"},
    {"id":"5", "collapseTo":{"id":"6","colName":"column2"}, "expandTo":null, "column1":"534345345", "column2":"6453334", "column3":"8563564", "column4":"75683", "column5":"4756436", "column6":"7689768", "column7":"8755"},
    {"id":"6", "collapseTo":null, "expandTo":{"column2":["1","2","3","4","5"]}, "column1":"534345345", "column2":"+5", "column3":"8563564", "column4":"75683", "column5":"4756436", "column6":"7689768", "column7":"8755"},
    {"id":"7", "collapseTo":{"id":"9","colName":"column4"}, "expandTo":null, "column1":"763484", "column2":"773845358", "column3":"7657565663", "column4":"87546598", "column5":"75675634", "column6":"89058", "column7":"3453463"},
    {"id":"8", "collapseTo":{"id":"9","colName":"column4"}, "expandTo":null, "column1":"763484", "column2":"773845358", "column3":"7657565663", "column4":"98976989", "column5":"75675634", "column6":"89058", "column7":"3453463"},
    {"id":"9", "collapseTo":null, "expandTo":{"column4":["7","8"]}, "column1":"763484", "column2":"773845358", "column3":"7657565663", "column4":"+2", "column5":"75675634", "column6":"89058", "column7":"3453463"},
    {"id":"10", "collapseTo":{"id":"17","colName":"column6"}, "expandTo":null, "column1":"5378756", "column2":"75675473", "column3":"264523", "column4":"423543", "column5":"34534534", "column6":"909424", "column7":"9768768"},
    {"id":"11", "collapseTo":{"id":"17","colName":"column6"}, "expandTo":null, "column1":"5378756", "column2":"75675473", "column3":"264523", "column4":"423543", "column5":"34534534", "column6":"22934920", "column7":"9768768"},
    {"id":"12", "collapseTo":{"id":"17","colName":"column6"}, "expandTo":null, "column1":"5378756", "column2":"75675473", "column3":"264523", "column4":"423543", "column5":"34534534", "column6":"124376325", "column7":"9768768"},
    {"id":"13", "collapseTo":{"id":"17","colName":"column6"}, "expandTo":null, "column1":"5378756", "column2":"75675473", "column3":"264523", "column4":"423543", "column5":"34534534", "column6":"36727845", "column7":"9768768"},
    {"id":"14", "collapseTo":{"id":"17","colName":"column6"}, "expandTo":null, "column1":"5378756", "column2":"75675473", "column3":"264523", "column4":"423543", "column5":"34534534", "column6":"6856345", "column7":"9768768"},
    {"id":"15", "collapseTo":{"id":"17","colName":"column6"}, "expandTo":null, "column1":"5378756", "column2":"75675473", "column3":"264523", "column4":"423543", "column5":"34534534", "column6":"43536366", "column7":"9768768"},
    {"id":"16", "collapseTo":{"id":"17","colName":"column6"}, "expandTo":null, "column1":"5378756", "column2":"75675473", "column3":"264523", "column4":"423543", "column5":"34534534", "column6":"76543686", "column7":"9768768"},
    {"id":"17", "collapseTo":null, "expandTo":{"column6":["10","11","12","13","14","15","16"]}, "column1":"5378756", "column2":"75675473", "column3":"264523", "column4":"423543", "column5":"34534534", "column6":"+7", "column7":"9768768"}
  ]
}

可以使用隐藏列来保存附加信息。我使用而不是 jQuery.data,它可以更有效地保存信息。具有分组链接的行在 JSON 数据中包含 "expandTo":{"column2":["1","2","3","4","5"]} 等信息。其他行包含"expandTo":null。在loadComplete 内部,我们可以隐藏所有具有"expandTo":null 的行。在其他行中,我们会将某些列的包含转换为链接。例如,如果expandTo 具有{"column2":["1","2","3","4","5"]},那么我们应该将项目从“column2”列转换为链接。作为链接上的单击操作,我们将隐藏该行并使数组["1","2","3","4","5"] 中的所有行可见。

演示这个的演示你可以找到here。单击链接后,将展开分组。双击展开的行会折叠行并退出先前状态的网格。

对应的代码是:

var grid = $("#list"),
    myExpanding = function(e) {
        var myData = $(this).data("expandTo"), i, l;
        if (myData && typeof(myData.length) !== "undefined" && myData.length>0) {
            for (i=0,l=myData.length; i<l; i++) {
                $("#"+myData[i]).show();
            }
            $(this).closest("tr").hide();
        }
        e.preventDefault();
    }, cmNameToIndex = {};

grid.jqGrid({
    datatype:'json',
    url:'CustomGrouping.json',
    colNames:[//'Expand To',
        'Column 1','Column 2','Column 3','Column 4','Column 5','Column 6','Column 7'],
    colModel:[
        //{name:'expandTo', width:1, hidden:true},
        {name:'column1'},
        {name:'column2'},
        {name:'column3'},
        {name:'column4'},
        {name:'column5'},
        {name:'column6'},
        {name:'column7'}
    ],
    cmTemplate:{width:85,align:'center',sortable:false},
    rowNum:10000,
    gridview:true,
    jsonReader:{repeatitems: false},
    loadComplete: function(data) {
        var i=0, rows = data.rows, l = rows.length, cm = grid[0].p.colModel, rowid,
            idToItem = {}, item;
        // The ids of the rows which has in the first column (expandTo) the information
        // about rows which should be expanded will be saved in the nonHiddenRows array.
        // For the rows the expandingInfo[rowid]
        for(; i<l; i++) {
            item = rows[i];
            idToItem[item.id] = item;
        }
        // fill cmNameToIndex to find easier the column index by column name
        cmNameToIndex = {};
        for (i=0,l=cm.length;i<l;i++){
            cmNameToIndex[cm[i].name] = i;
        }
        $("tr.jqgrow",this).each(function(){
            var tr=$(this), colName, linkInfo, td, rowid = this.id, item = idToItem[rowid];
            //if ($.inArray(rowid,nonHiddenRows) !== -1) {
            if (item && item.expandTo) {
                //tr.show();
                linkInfo = item.expandTo;
                for (colName in linkInfo) {
                    if (linkInfo.hasOwnProperty(colName)) {
                        i = cmNameToIndex[colName];
                        td = $("td:nth-child("+(i+1)+")",this);
                        td.wrapInner($('<a>',
                                       {
                                         href:"#",
                                         click:myExpanding,
                                       }).data("expandTo",linkInfo[colName]));
                    }
                }
            } else {
                tr.hide();
            }
            if (item && item.collapseTo) {
                tr.data("collapseTo",item.collapseTo)
            }
        });
    },
    ondblClickRow: function(rowid, iRow, iCol, e) {
        var tr = $("#"+rowid), tr1 = $(e.target,grid[0].rows).closest("tr.jqgrow"),
            collapse = tr.data("collapseTo"), i, ids, l;
        if (collapse && collapse.id && collapse.colName) {
            i = cmNameToIndex[collapse.colName];
            tr = $("#"+collapse.id);
            ids = $("a", tr[0].cells[i]).data("expandTo");
            if (ids && ids.length) {
                tr.show();
                for(i=0,l=ids.length; i<l; i++) {
                    $("#"+ids[i]).hide();
                }
            }
        }
    },
    height: '100%'
});

【讨论】:

  • 非常感谢您的回答。我现在正在审查它,但它看起来非常非常好,包括你的演示。
  • @Jack B.:不客气!我在 JSON 中选择了结构 expandTo,以便它可以将更多信息保存为一个分组 column2column4 例如)。我的回答仅显示了如何实现您的要求的主要思想。我希望您可以根据自己的环境轻松修改它。
  • 我们必须对多行进行这项工作,但这个答案引导我们朝着正确的方向前进。谢谢!
  • @Jack B.:我想象在一列中扩展多个链接:如果您单击链接,一些以前隐藏的行将可见。新可见行中的一些也可能有链接。要实现该行为,您应该像我的示例中那样从服务器发布隐藏行。唯一的区别是,在开始时,一些内部有链接的行最初会被隐藏。唯一的问题是,如果行中有两个链接,则扩展行的顺序是免费的。因此可能需要包含更多(或更多)隐藏行。
  • @Jack B.:您还可以考虑以更紧凑的形式从服务器发送数据,并使用addRowData 添加行扩展(在click 事件处理程序中)。在这种情况下,除了expandTo 中当前使用的 id 之外,您还应该包括 expanding 列的值。通过这种方式,您可以从根本上减少服务器响应的大小。
猜你喜欢
  • 1970-01-01
  • 2016-06-29
  • 2011-12-27
  • 1970-01-01
  • 2012-09-15
  • 2018-10-19
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多