jqGrid列分组

4

我能否在jqGrid中像jQuery EasyUI库一样实现列分组?

您可以访问jQuery EasyUI 演示 网站,选择Datagrid然后从左侧菜单选择Column Group,了解我的意思。

谢谢您的帮助。

3个回答

10

你的问题并不新鲜。有很多次在trirand论坛或stackoverflow上也有对应的特性请求。我之前在一个类似的问题上给出了另一个答案

现在,阅读了你的问题后,我决定不去做一种支持所有jqGrid功能的完美解决方案(这太难了)。相反,我决定创建一种可以在许多情况下使用的解决方案,但是它有一些限制。

演示展示了我的第一个结果:

enter image description here

限制:

  • 不能调整网格的列大小。我在演示中使用cmTemplate: {resizable: false}参数来设置所有网格列中的resizable: false
  • sortable: true不被支持
  • showColhideColcolumnChooser目前不支持,但我相信可以很快解决这些问题。
  • 放置额外列标题的列应具有相同的宽度。如果列具有不同的宽度值,则将自动在列的总宽度之间进行分配。

另一方面,所有我的测试都没有遇到任何问题,包括其他常用选项,如shrinkToFit: falseautowidth: true或通过setGridWidth方法改变网格宽度(缩小或不缩小)。

现在先来说一下使用特性。我编写了函数insertColumnGroupHeader,我在上面的示例中使用:

insertColumnGroupHeader(grid, 'amount', 3, '<em>Information about the Price</em>');

它在从列“amount”开始的3个列上插入一个附加的HTML片段'关于价格的信息',并添加一个额外的列标题。因此使用非常简单,您当然可以使用任何文本,例如“关于价格的信息”作为附加的列标题。

函数insertColumnGroupHeader的代码如下:

var denySelectionOnDoubleClick = function ($el) {
        // see https://dev59.com/SXI95IYBdhLWcg3w1Bro#2132230
        if ($.browser.mozilla) {//Firefox
            $el.css('MozUserSelect', 'none');
        } else if ($.browser.msie) {//IE
            $el.bind('selectstart', function () {
                return false;
            });
        } else {//Opera, etc.
            $el.mousedown(function () {
                return false;
            });
        }
    },
    insertColumnGroupHeader = function (mygrid, startColumnName, numberOfColumns, titleText) {
        var i, cmi, skip = 0, $tr, colHeader, iCol, $th,
            colModel = mygrid[0].p.colModel,
            ths = mygrid[0].grid.headers,
            gview = mygrid.closest("div.ui-jqgrid-view"),
            thead = gview.find("table.ui-jqgrid-htable>thead");

        mygrid.prepend(thead);
        $tr = $("<tr>");
        for (i = 0; i < colModel.length; i++) {
            $th = $(ths[i].el);
            cmi = colModel[i];
            if (cmi.name !== startColumnName) {
                if (skip === 0) {
                    $th.attr("rowspan", "2");
                } else {
                    denySelectionOnDoubleClick($th);
                    $th.css({"padding-top": "2px", height: "19px"});
                    $tr.append(ths[i].el);
                    skip--;
                }
            } else {
                colHeader = $('<th class="ui-state-default ui-th-ltr" colspan="' + numberOfColumns +
                    '" style="height:19px;padding-top:1px;text-align:center" role="columnheader">' + titleText + '</th>');
                denySelectionOnDoubleClick($th);
                $th.before(colHeader);
                $tr.append(ths[i].el);
                skip = numberOfColumns - 1;
            }
        }
        mygrid.children("thead").append($tr[0]);
    };

此外,需要对jqGrid代码进行一些更改。您可以从这里下载修改后的版本(4.1.2版本的修改版)jquery.jqGrid.src.js。更改由两个块组成。首先,我更改了sortData函数的代码,即1874-1884行。

var thd= $("thead:first",ts.grid.hDiv).get(0);
$("tr th:eq("+ts.p.lastsort+") span.ui-grid-ico-sort",thd).addClass('ui-state-disabled');
$("tr th:eq("+ts.p.lastsort+")",thd).attr("aria-selected","false");
$("tr th:eq("+idxcol+") span.ui-icon-"+ts.p.sortorder,thd).removeClass('ui-state-disabled');
$("tr th:eq("+idxcol+")",thd).attr("aria-selected","true");
if(!ts.p.viewsortcols[0]) {
    if(ts.p.lastsort != idxcol) {
        $("tr th:eq("+ts.p.lastsort+") span.s-ico",thd).hide();
        $("tr th:eq("+idxcol+") span.s-ico",thd).show();
    }
}

转换为以下内容:

var previousSelectedTh = ts.grid.headers[ts.p.lastsort].el,
    newSelectedTh = ts.grid.headers[idxcol].el;
$("span.ui-grid-ico-sort",previousSelectedTh).addClass('ui-state-disabled');
$(previousSelectedTh).attr("aria-selected","false");
$("span.ui-icon-"+ts.p.sortorder,newSelectedTh).removeClass('ui-state-disabled');
$(newSelectedTh).attr("aria-selected","true");
if(!ts.p.viewsortcols[0]) {
    if(ts.p.lastsort != idxcol) {
        $("span.s-ico",previousSelectedTh).hide();
        $("span.s-ico",newSelectedTh).show();
    }
}

接下来我定义了getColumnHeaderIndex函数,如下所示

var getColumnHeaderIndex = function (th) {
    var i, headers = ts.grid.headers, ci = $.jgrid.getCellIndex(th);
    for (i = 0; i < headers.length; i++) {
        if (th === headers[i].el) {
            ci = i;
            break;
        }
    }
    return ci;
};

并更改了 grid.base.js 的第 21722185 行。

var ci = $.jgrid.getCellIndex(this);
to
var ci = getColumnHeaderIndex(this);

就是这些内容。上述描述的更改不应对原始jqGrid代码产生负面影响,并且可以像往常一样使用。我将在下一次在trirand论坛上发布我的建议。

更新:另一个版本的演示允许调整除标题列外的所有列的大小。 在该版本中,所有放置额外列标题的列必须具有相同的宽度。 列的宽度没有自动分配。您必须手动设置相同的列宽。

更新2:我想通知一些进展,创建更高级的多标题jqGrid版本。 首先,wildraid发布了非常有趣的解决方案。在此处查看他的演示。 顺便说一句,如果使用我建议的修补程序(请参见上文)与方法jqGrid,则演示中的排序图标问题将得到解决。 在此处查看确认演示。

之后,我更多地研究了减少使用rowSpan来增加列高的多列方法中的限制。 这是我的当前中间结果:新演示。 新演示已经在Internet Explorer 9/8、Firefox和Opera中良好工作。 在基于Webkit的浏览器(Google Chrome和Safari)中,它仍具有上述限制(具有多标题的列标题必须具有相同大小且不可调整大小)。 演示在WebKit-based Web浏览器中外观良好并具有限制。 尽管如此,您可以看到排序时间的进展。

我计划根据演示文稿答案,增加可调整大小的区域高度以调整列的大小。当然,还将支持使用多个标题在列标题上。ColumnChooser或showCol/hideCol也将得到支持。现在最让我感兴趣的是找到一种清晰的方法如何在Webkit浏览器(Google Chrome和Safari)中使用rowSpan实现多行列标头。也许其他人会找到解决方案?这就是为什么我决定在这里分享未完成的结果的主要原因。

更新3:jqGrid代码的更改已包含在jqGrid的主代码中(请参见此处)。我改进了在此处描述的解决方案,制作成了这些这些演示文稿。第二个演示文稿将增加网格宽度,如果列宽将增加。我个人喜欢这种行为。

更新4:您可以在此处看到演示文稿的下一个版本。它具有布尔选项(参数useColSpanStyle),定义是否应使用colspan。参数的false值将得到以下结果


1
@Jonathan:很高兴听到这个消息!我的当前演示不是完美的,但已经迈出了解决问题的一步。因为你之前也有同样的问题,所以我想告诉你答案。 - Oleg
哇!我没有想到这是如此困难。厉害的代码!谢谢 Oleg,它完美地运行了 :) - Lorenzo
1
@Lorenzo:在“更新3”部分中,您可以看到所讨论主题的一些进展。现在很清楚,下一个版本的jqGrid将以某种方式支持多行列标题。我会继续向您通报这个情况。 - Oleg
@ Oleg,我只能说“哇”,这个答案太棒了,谢谢您。 - Stephen Patten
是否有任何解决方案可以按组列显示 showCol、隐藏 hideCol 或使用 columnChooser? - kozla13
显示剩余6条评论

0

随着jqGrid的后续版本,Oleg的解决方案已经成为官方版本 :)

我正在v4.4.4上测试它,但应该适用于所有4.x版本

它支持排序,即使文档中说不支持(他们真的应该更新API参考)

在这里查看官方参考

这不是Oleg的第一个官方版本,你一定很自豪吧!


0

相关:jqGrid没有子网格的分组?

仅为了视觉效果,您可以通过在加载网格数据后调用方法来编辑jqgrid的HTML输出来实现此目的。您可以通过"jqgh_"前缀加上jgrid的colName值来访问列标题。在您拥有一组元素之后,您可以修改它们。

显然不是最好的方法,但可能有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接