jQgrid: multiple column row headers
Asked Answered
P

5

9

I am trying to extend my jQGrid to have multiple rows for the header.

It will look something like this

               -----------------------
Level 1 - >    | Application         |
               -----------------------  
Level 2 - >    |Code    | Name       |  
               -----------------------
               | 0002827| Mobile Phone1
               | 0202827| Mobile Phone2
               | 0042827| Mobile Phon3e
               | 0005827| Mobile Phone4
               | 0002627| Mobile Phon5e
               | 0002877| Mobile Phone6
               | 0002828| Mobile Phone7

I am wondering how to do this with jQGrid 3.8.2? Any ideas?

Pul answered 17/1, 2011 at 11:47 Comment(0)
K
12

The problem is really not so easy as it looks like at first glance. I tried to find a simple solution, but the best result which I found you can see here: enter image description here

The order of the headers (level 1 and level 2) is not as one would like to have. Other attempts like this or this are buggy because the sorting and column resizing works not more correct.

For the understanding: the grid moves the <thead> outside of the table and places it inside of separate which are placed above the table (see here for more information). It allows including some additional information like searching toolbar between the table header and the table body. Other places in the jqGrid code like column resizing and column sorting works incorrect if there are exist other headers (one more <tr> with <th> elements) over the main column headers. So only the inserting of additional column headers under the main columns headers (which looks not nice of course) not breaks the sorting and the resizing of columns.

UPDATED: See the answer which do provide the solution of the problem under some restrictions.

Kilter answered 18/4, 2011 at 23:52 Comment(5)
@Jonathan: In the next time I plan to examine sorting and resizing code of jqGrid more exactly and will try to fix the problem with the first row of the headers. I hope that including classes ("th.ui-th-column" instead of "th") in the lines like this will solve the problem.Kilter
@Jonathan: I found some places in the jqGrid source code which made the problems. Look at here. It is not yet the final version, but many things already are working in the Internet Explorer and Firefox (not yet in Chrome).Kilter
Thanks for your enthusiasm, great solution!Pul
@Jonathan: See the answer which do provide the solution of the problem under some restrictions.Kilter
@Oleg, I did some improvemnts in the way you do it. I added a blank row in the bottom.Hygro
D
7

I know this is a late answer but for future reference header grouping is now included in version 4.2.0 of jqGrid

Deangelis answered 25/10, 2011 at 9:40 Comment(1)
I actually stopped using JQGrid as it doesnt really fit well with MVC and instead coding things by hand. I did find it very useful for CRUD type things but thats it. Thanks for feedback info!Pul
J
2

Modified the original idea by Oleg and made it into a function that can make several "spanned" headers:

function head_groups(mygrid, settings){

    var colModel, header, config, ths;

    if (typeof mygrid == 'string') mygrid = $(mygrid);

    colModel = mygrid[0].p.colModel;
    ths = mygrid[0].grid.headers;
    header = mygrid.closest("div.ui-jqgrid-view").find("table.ui-jqgrid-htable > thead");

    if (!header.children("tr.head_group").length) {
        header.find("th").attr('rowspan', 2);
        header.append('<tr class="head_group"></tr>');
    }

    for (c in settings) {

        config = settings[c]; // caption, col, span

        for(var i=0; i<colModel.length; i++) {

            if (colModel[i].name == config.col) {
                for(var s=0; s<config.span; s++) {
                    $(ths[i+s].el).removeAttr('rowspan');
                }
                i +=s; // skip unnecessary cycles
                header.children("tr.head_group").append('<th class="ui-state-default ui-th-ltr" id="span_'+config.col+'" colspan="'+config.span+'" role="columnheader">'+config.caption+'</th>');
            }
        }
    }
}

Usage sample:

head_groups("table#results", [
    {caption: 'Test 1', col: 'num', span: 2},
    {caption: 'Result', col: 'sta', span: 3},
    {caption: 'Bla bla bla', col: 'bl2', span: 2}
]);

It also adds a class for the header row and IDs for the header cells for some styling or special functionality.

In fact this can be easily integrated in the jqGrid core :)

Jowers answered 30/6, 2011 at 22:47 Comment(0)
B
1

According to Help needed in Multiple column grouping (jQGrid 3.8.2), the jqGrid support team indicates:

This is currently not supported. Multiple column headers in a single column (subcolumns) are not currently a feature of jqGrid.

Brandes answered 15/4, 2011 at 16:22 Comment(3)
Thats true, I am aware of that. I am trying to find a way to achieve this. Even if its through some deviant method.Pul
If you do get it to work, you should consider submitting a patch to the jqGrid team, so the fix can be rolled into a future release.Brandes
Ha ha Justin, brother thats why im posting! +50 Points not enought? ;)Pul
H
0

I modified the code of Oleg to be able to show the grouping in the first row, basically I created a dummy third row and just deleted the text in the first row.

var x = 0;
insertColumnGroupHeader = function (mygrid, mergeSettingList) {
    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");
    $tr = $("<tr>");

    var currCaption = '';
    var currColumnName = '';
    var currSpan = 0;
    var currSkip = 0;
    tr = "<tr>";
    for (i = 0; i < colModel.length; i++) {
        $th = $(ths[i].el);
        cmi = colModel[i];

        if (currSkip === 0) {
            currColumnName = '';
            for (j = 0; j < mergeSettingList.length; j++) {
                if (mergeSettingList[j].col == cmi.name) {
                    currCaption = mergeSettingList[j].caption;
                    currColumnName = mergeSettingList[j].col;
                    currSpan = mergeSettingList[j].span;
                    currWidth = mergeSettingList[j].width;
                    break;
                }
            }
        }

        if (cmi.name !== currColumnName) {
            if (currSkip === 0) {
                $th.attr("rowspan", "2");
            } else {
                // Skip part of group
                denySelectionOnDoubleClick($th);
                currSkip--;
            }
        } else {
            denySelectionOnDoubleClick($th);

            tr += '<th class="ui-state-default ui-th-ltr" colspan="' + currSpan + '" role="columnheader">' + currCaption + '</th>';
            currSkip = currSpan - 1;
        }
    }
    tr += "</tr>";
    mygrid.closest("div.ui-jqgrid-view").find("table.ui-jqgrid-htable > thead").append(tr);

    $th = $(ths[0].el);
    tr = "<tr>";
    var html = $th.parent().html();
    tr += html;
    tr += "</tr>";

    mygrid.closest("div.ui-jqgrid-view").find("table.ui-jqgrid-htable > thead").append(tr);
    for (i = 0; i < colModel.length; i++) {
        $th = $(ths[i].el);
        cmi = colModel[i];
        $th.empty();
        $th.css({"padding-top": "0px", height: "0px", border: "0px"});
    }
}

Sample call.

var mergeParam = [
        {caption: ' ', col: 'ActionKey', span: 3},
        {caption: 'Planned', col: 'PlannedStartColKey', span: 5},
        {caption: 'Actual', col: 'ActualStartColKey', span: 12}
    ];
insertColumnGroupHeader2($(GridNames.Grid), mergeParam);
Hygro answered 21/10, 2013 at 12:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.