Jqgrid - grouping row level data
Asked Answered
T

3

15

With jqgrid, is it possible to group the row level data as in the attached image? Basically I wanted to split the data for a particular row into multiple rows from certain columns onwards..

Example

enter image description here

Thrilling answered 30/8, 2012 at 15:41 Comment(8)
Do you want that the column "Module" will be collapsed (hide) if the user would click on any image on the previous small column and then the column will be expanded (shown) if the user would click on an image of the small column at the next time?Dyspeptic
Oleg: Thanks a lot for the response. Do you mean by having a plus sign and then user expands it to show the subgrid(child rows) data? That was one idea but our users wanted something like this. Can we achieve what is shown in the attachment for jqgrid? Basic requirement is to be able to show grouped data together and each child data as split rows for the same grouped rowThrilling
My question was because I don't understand you question. Could you explain exactly which behavior of the grid you want to implement? You posted just a picture, but not explained how it should be interpreted. Do you want just display the data in grid like it is on the picture or you need to implement some behaviors on clicking on some places inside of grid? What means the red box with two columns? What means the small column with the icons as a box (square)?Dyspeptic
Oleg: For suppose I have 4 rows of data(green box) with different columns to be displayed in the grid. Among those 4 rows some columns (in the above diagram - area, country, location, device are same for four rows but remaining column data is different). I was just asking if we can display this data as in the image like grouping same data in a single row but splitting the non-grouped rows into different rows. The red box indicates the individual column level data for each of the grouped rowsThrilling
I have added another example to better understand my requirement. Say for example if you have different places in a state and you want to display the country, state in a single row but the data for each state will have different places which need to be displayed in different rows for that grouped row (in this case for each state).Thrilling
Oleg: Could you also please take a look at my other question here? Thanks a lot..Thrilling
I think I have an idea how one could implement the grid which you need. The idea is to use rowspan attribute on the "country" and "state" cells. I will try to prepare the corresponding demo later (probably tomorrow). I recommend you to read the answer which uses colspan instead. I think that one can set rowspan in the same way to create the grid like you as need.Dyspeptic
You still don't commented my answer which I posted 4 days before. Do you read it?Dyspeptic
D
17

I suggest you to use cellattr to set rowspan attribute on some cells or set style="display:none" to hide another unneeded cells. The idea is the same as with colspan from the answer.

As the result you can create the following grid (see the demo)

enter image description here

or another one (see another demo)

enter image description here

The problem with the grids is in another jqGrid features like sorting, paging, hovering and selection. Some from the features one can implement with additional efforts, but another one are more difficult to implement.

The code which I used in the demo is the following:

var mydata = [
        { id: "1", country: "USA", state: "Texas",      city: "Houston",       attraction: "NASA",               zip: "77058", attr: {country: {rowspan: "5"},    state: {rowspan: "5"}} },
        { id: "2", country: "USA", state: "Texas",      city: "Austin",        attraction: "6th street",         zip: "78704", attr: {country: {display: "none"}, state: {display: "none"}} },
        { id: "3", country: "USA", state: "Texas",      city: "Arlinton",      attraction: "Cowboys Stadium",    zip: "76011", attr: {country: {display: "none"}, state: {display: "none"}} },
        { id: "4", country: "USA", state: "Texas",      city: "Plano",         attraction: "XYZ place",          zip: "54643", attr: {country: {display: "none"}, state: {display: "none"}} },
        { id: "5", country: "USA", state: "Texas",      city: "Dallas",        attraction: "Reunion tower",      zip: "12323", attr: {country: {display: "none"}, state: {display: "none"}} },
        { id: "6", country: "USA", state: "California", city: "Los Angeles",   attraction: "Hollywood",          zip: "65456", attr: {country: {rowspan: "4"},    state: {rowspan: "4"}} },
        { id: "7", country: "USA", state: "California", city: "San Francisco", attraction: "Golden Gate bridge", zip: "94129", attr: {country: {display: "none"}, state: {display: "none"}} },
        { id: "8", country: "USA", state: "California", city: "San Diego",     attraction: "See world",          zip: "56653", attr: {country: {display: "none"}, state: {display: "none"}} },
        { id: "9", country: "USA", state: "California", city: "Anaheim",       attraction: "Disneyworld",        zip: "92802", attr: {country: {display: "none"}, state: {display: "none"}} }
    ],
    arrtSetting = function (rowId, val, rawObject, cm) {
        var attr = rawObject.attr[cm.name], result;
        if (attr.rowspan) {
            result = ' rowspan=' + '"' + attr.rowspan + '"';
        } else if (attr.display) {
            result = ' style="display:' + attr.display + '"';
        }
        return result;
    };

$("#list").jqGrid({
    datatype: 'local',
    data: mydata,
    colNames: ['Country', 'State', 'City', 'Attraction', 'Zip code'],
    colModel: [
        { name: 'country', width: 70, align: 'center', cellattr: arrtSetting },
        { name: 'state', width: 80, align: 'center', cellattr: arrtSetting },
        { name: 'city', width: 90 },
        { name: 'attraction', width: 120 },
        { name: 'zip', index: 'tax', width: 60, align: 'right' }
    ],
    cmTemplate: {sortable: false},
    rowNum: 100,
    gridview: true,
    hoverrows: false,
    autoencode: true,
    ignoreCase: true,
    viewrecords: true,
    height: '100%',
    caption: 'Grid with rowSpan attributes',
    beforeSelectRow: function () {
        return false;
    }
});

I used in the above code additional attr property placed together with the input data. It's just an example. I wanted to make the implementation of cellattr function more simple. You can use the same idea and to place the information needed for cellattr in any other format.

Dyspeptic answered 6/9, 2012 at 6:17 Comment(7)
Oleg: Excellent! Thanks a lot, you are always helpful. This is definitely helpful. I am just wondering if we would be able to implement other grid features like pagination, sorting. Also I am planning to implement dynamic colmodel, not sure how this would work in that case. Could you please take a look at my other question here. I have been out so could n't reply or mark it as answered, sorry about that :(Thrilling
Oleg: Could you please take a look at my question here when you get a chance. Thanks in advance...Thrilling
@varaprakash: I read the question, but don't understand the problem. Which kind of wrapping you need and how the wrapping problem has any relation with the dynamic loading of the colModel? Why the JSON response contain results part with the data, but you use datatype: 'json' and the data will be ignored. The main problem is: which kind of wrapping you need?Dyspeptic
Thanks a lot for the reply. I am trying to implement dynamic colmodel using the approach I have mentioned in the question. In the ajax response I was trying to send the colmodel and data so that I can avoid another call from jqgrid to load the data. But as you said if I use datatype: json it is ignoring the data. But if I use datatype: local, will I be able to use other features like pagination, sorting etc? Regarding wrapping, if the data exceeds column width, it is not automatically wrapping so I wanted to send cellatr function in the colmodel and that does n't work. Thanks..Thrilling
@janina: I wrote in my answer that the above code is not oriented on sorting, paging, hovering and selection features of jqGrid.Dyspeptic
can you tell me what should I do?Messina
@janina: It's not easy because the rowspan value will depend not only from the data itself, but from the page size and from the position of the row on the page.Dyspeptic
B
5

This is my solution for JSON data:

var prevCellVal = { cellId: undefined, value: undefined };

$("#list").jqGrid({
    url: 'your WS url'
    datatype: 'json',
    mtype: "POST",
    ajaxGridOptions: {
        contentType: "application/json"
    },
    colNames: ['Country', 'State', 'City', 'Attraction', 'Zip code'],
    colModel: [
        { name: 'country', width: 70, align: 'center', 
            cellattr: function (rowId, val, rawObject, cm, rdata) {
                        var result;

                        if (prevCellVal.value == val) {
                            result = ' style="display: none" rowspanid="' + prevCellVal.cellId + '"';
                        }
                        else {
                            var cellId = this.id + '_row_' + rowId + '_' + cm.name;

                            result = ' rowspan="1" id="' + cellId + '"';
                            prevCellVal = { cellId: cellId, value: val };
                        }

                        return result;
                    }
        },
        { name: 'state', width: 80, align: 'center' },
        { name: 'city', width: 90 },
        { name: 'attraction', width: 120 },
        { name: 'zip', index: 'tax', width: 60, align: 'right' }
    ],
    cmTemplate: {sortable: false},
    rowNum: 100,
    gridview: true,
    hoverrows: false,
    autoencode: true,
    ignoreCase: true,
    viewrecords: true,
    height: '100%',
    caption: 'Grid with rowSpan attributes',
    beforeSelectRow: function () {
        return false;
    },
    gridComplete: function () {
        var grid = this;

        $('td[rowspan="1"]', grid).each(function () {
            var spans = $('td[rowspanid="' + this.id + '"]', grid).length + 1;

            if (spans > 1) {
                $(this).attr('rowspan', spans);
            }
        });
    }
});

This example is for a single column, but with few corrections it can be used also for multiple columns.

Brooch answered 20/9, 2012 at 9:18 Comment(0)
S
0

Hey there "pistipanko"

I have made a change in your solution, i think it worked better.

cellattr: function(rowId, val, rawObject, cm, rdata) {
                        var result;
                        var cellId = this.id + '_row_' + rawObject[3] + grid.getGridParam('page');

                        if (prevCellVal.cellId == cellId) {
                            result = ' style="display: none"';
                        }
                        else {
                            result = ' rowspan="' + rawObject[6] + '"';
                            prevCellVal = { cellId: cellId, value: rawObject[3] };
                        }

                        return result;
                    }

I am making the grouping with the value of another collumn that's why the rawObject[3] And i am using a rowspan value returned from the application in the rawObject[6]

Works great.

Hope it helps :)

Shaker answered 25/10, 2012 at 18:48 Comment(2)
You're right, I've edited my solution too for my needs, simularly like you did, it's just an examle.Brooch
Yeah :) did you noticed that i put the page number in the cellid? i did it so the grouping is repeated, if it's contants go into another page :)Shaker

© 2022 - 2024 — McMap. All rights reserved.