jqGrid 列组 [英] jqGrid Column Group

查看:20
本文介绍了jqGrid 列组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以像 jQuery EasyUI 库那样在 jqGrid 中实现列组吗?

您可以通过 jQuery EasyUI ,但我相信可以快速解决问题.

  • 将放置额外列标题的列应具有相同的宽度.如果列具有不同的宽度值,则列的总宽度将在列之间自动划分.
  • 另一方面,在我的所有测试中,使用其他流行选项(如 shr​​inkToFit: falseautowidth: true 或更改网格宽度),一切正常setGridWidth 方法(有或没有缩小).

    现在首先介绍该功能的使用.我写了函数 insertColumnGroupHeader 我在上面的例子中用作

    insertColumnGroupHeader(grid, 'amount', 3, '<em>关于价格的信息</em>');

    它会在以金额"列开头的 3 列中插入带有 HTML 片段价格信息"的附加列标题.所以用法很简单.您当然可以使用任何文本,例如价格信息"作为附加列标题.

    函数insertColumnGroupHeader代码如下:

    var denySelectionOnDoubleClick = function ($el) {//见 https://stackoverflow.com/questions/2132172/disable-text-highlighting-on-double-click-in-jquery/2132230#2132230if ($.browser.mozilla) {//火狐$el.css('MozUserSelect', 'none');} else if ($.browser.msie) {//IE$el.bind('selectstart', function () {返回假;});} else {//歌剧等$el.mousedown(函数 () {返回假;});}},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) {如果(跳过=== 0){$th.attr("rowspan", "2");} 别的 {拒绝SelectionOnDoubleClick($th);$th.css({"padding-top": "2px", height: "19px"});$tr.append(ths[i].el);跳过 - ;}} 别的 {colHeader = $('<th class="ui-state-default ui-th-ltr" colspan="' + numberOfColumns +'" style="height:19px;padding-top:1px;text-align:center" role="columnheader">'+ titleText + '</th>');拒绝SelectionOnDoubleClick($th);$th.before(colHeader);$tr.append(ths[i].el);跳过 = numberOfColumns - 1;}}mygrid.children("thead").append($tr[0]);};

    此外,还需要对 jqGrid 代码进行一些更改.可以从这里.更改包括两个块.首先我更改了 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");如果(!ts.p.viewsortcols[0]){如果(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");如果(!ts.p.viewsortcols[0]){如果(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 = 我;休息;}}返回 ci;};

    并更改了行 21722185 的 <代码>grid.base.js 来自

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

    var ci = getColumnHeaderIndex(this);

    就是这样.上述更改应该不会对原始 jqGrid 代码产生负面影响,并且可以照常使用.下次我会在 trirand 论坛发表我的建议.

    更新:另一个版本演示的允许调整除具有标题的列之外的所有列的大小.在该版本中,将放置附加列标题的所有列必须具有相同的宽度.列的宽度不会在列之间自动划分.您必须手动设置相同的列宽.

    UDPATED 2:我想告知在创建更高级的多头 jqGrid 版本方面的一些进展.首先 wildraid 张贴 非常有趣的解决方案.查看他的演示这里.顺便说一句,如果使用 jqGrid 方法和我建议的修复程序(见上文),演​​示中的排序图标问题将得到解决.参考这里demo作为构象.

    在那之后,我在减少使用 rowSpan 来增加列高度的多列方法中的限制更多.这是我当前的中间结果:新的演示.新的演示在 Internet Explorer 9/8、Firefox 和 Opera 中已经非常出色了.在基于 Webkit 的浏览器(Google Chrome 和 Safari)中,它仍然具有上面列出的限制(具有多标题的列标题必须具有相同的大小并且不可调整大小).演示看起来不错有限制,在 Webkit 中看起来不错-基于网络浏览器.不过,您可以看到排序时间的进度.

    我计划根据 演示来自 答案.当然,也将支持在列标题上使用许多标题.也将支持 ColumnChooser 或 showCol/hideCol.现在对我来说最有趣的是找到一种清晰的方法,如何在基于 Webkit 的浏览器(Google Chrome 和 Safari)中使用 rowSpan 实现多行列标题.可能其他人会找到解决方法?这是我决定在这里分享未完成结果的主要原因.

    更新 3:包含 jqGrid 代码的更改(参见 here) 在 jqGrid 的主代码中.我将这里描述的解决方案改进为 this这个 演示.如果要增加列宽,则第二个演示会增加网格宽度.我个人喜欢这种行为.

    更新 4:下一个版本的演示你可以看到 这里.它有一个布尔选项(参数useColSpanStyle),它定义是否应该使用colspan.使用 false 参数值的结果将是 关注.

    can I implement a column group in jqGrid like the jQuery EasyUI library does?

    You can figure out what I mean by going on the jQuery EasyUI demo web site, and choose Datagrid then Column Group from the left menu.

    Thanks for helping

    解决方案

    Your question is not new. Many times the corresponding feature request was asked in trirand forum or on the stackoverflow. I give another answer on the close question some time before.

    Now after reading of your question I do decided don't make a perfect solution supporting all jqGrid features (which is too difficult at once). Instead of that I decide to create a solution which can be already used in many cases, but which has some restrictions.

    The demo shows my first results:

    The restrictions:

    • the columns of the grid can not be resized. I use in the demo cmTemplate: {resizable: false} parameter to set resizable: false in all grid columns.
    • sortable: true is not supported
    • showCol, hideCol or columnChooser are not currently supported, but I am sure that one can quickly fix the problems.
    • columns over which one will place an additional column header should has the same width. If the columns have different width values the total width of the column will be divided between the columns automatically.

    On the other side everything work without any problem in all my tests with other popular options like shrinkToFit: false, autowidth: true or changing of the grid width with respect of setGridWidth method (with or without shrinking).

    Now first about the usage of the feature. I wrote function insertColumnGroupHeader which I use in the above example as

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

    It inserts an additional column header with the HTML fragment 'Information about the Price' over 3 columns starting with the column 'amount'. So the usage is pretty simple. You can of course use just any text like 'Information about the Price' as the additional column header.

    The function insertColumnGroupHeader has the following code:

    var denySelectionOnDoubleClick = function ($el) {
            // see https://stackoverflow.com/questions/2132172/disable-text-highlighting-on-double-click-in-jquery/2132230#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]);
        };
    

    Additionally it was required to make some changes in the jqGrid code. You can download the modified version (the modification of the 4.1.2 version) of jquery.jqGrid.src.js from here. The changes consist from two blocks. First I changed the code of sortData function, the lines 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();
        }
    }
    

    to the following:

    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();
        }
    }
    

    Next I defined getColumnHeaderIndex function as the following

    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;
    };
    

    and changed the lines 2172 and 2185 of grid.base.js from

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

    to

    var ci = getColumnHeaderIndex(this);
    

    It's all. The above described changes should have no negative influence on the original jqGrid code and can be used as usual. I will publish my suggestion in the next time on trirand forum.

    UPDATED: Another version of the demo allows resizing of all columns excepting the columns having the headers. In the version all the columns over which one will place an additional column header have to have the same width. The width of the columns not divided between the columns automatically. You have to set the same column width manually.

    UDPATED 2: I want to inform about some progress in creating more advanced version of multiheader jqGrid. First wildraid posted very interesting solution. See his demo here. By the way if one use with the method jqGrid with the fixes which I suggested (see above) the problem with sorting icons in the demo will be solved. See here the demo as the conformation.

    After that I works a little more abut reducing restrictions in my multicolumn approach which use rowSpan to increase the height of the columns. Here is my current intermediate result: the new demo. The new demo work already very good in Internet Explorer 9/8, Firefox and Opera. In Webkit-based browsers (Google Chrome and Safari) it has still the above listed restriction (column headers which has multiheaders have to have the same size and be not resizable). The demo looks good has the restrictions and it looks good in Webkit-based web browsers. Nevertheless you can see progress in the sort time.

    I plan to increase the height of the resizable area used to resize the columns based on the demo from the answer. Of cause the usage of many headers over column headers will be also supported. ColumnChooser or showCol/hideCol will be supported too. The most interesting for me now is to finding a clear way how to implement multirows column headers using rowSpan in Webkit-based browsers (Google Chrome and Safari). Probably somebody else will find a solution way? It is the main reason why I decide to share not completed results here.

    UPDATE 3: The changes in the code of jqGrid are included (see here) in the main code of jqGrid. I improved the solution which I described here to this and this demos. The second demo increase the grid width if the column width will be increased. I personally like the behavior.

    UPDATE 4: The next version of the demo you can see here. It has an boolean option (the parameter useColSpanStyle) which which defines whether colspan should be used or not. With false value of the parameter the results will be the following.

    这篇关于jqGrid 列组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆