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

varaprakash
  • 487
  • 4
  • 12
  • 30
  • 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? – Oleg Aug 30 '12 at 21:35
  • 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 row – varaprakash Aug 30 '12 at 22:15
  • 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)? – Oleg Aug 30 '12 at 22:26
  • [Oleg](http://stackoverflow.com/users/315935/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 rows – varaprakash Sep 05 '12 at 17:11
  • 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). – varaprakash Sep 05 '12 at 17:30
  • Oleg: Could you also please take a look at my other question [here](http://stackoverflow.com/questions/12206260/jqgrid-auto-wrapping-for-dynamic-column-binding)? Thanks a lot.. – varaprakash Sep 05 '12 at 17:32
  • 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](http://stackoverflow.com/a/5625959/315935) which uses `colspan` instead. I think that one can set `rowspan` in the same way to create the grid like you as need. – Oleg Sep 05 '12 at 18:24
  • You still don't commented my answer which I posted 4 days before. Do you read it? – Oleg Sep 10 '12 at 05:15

3 Answers3

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.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • 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](http://stackoverflow.com/questions/12206260/jqgrid-auto-wrapping-for-dynamic-column-binding). I have been out so could n't reply or mark it as answered, sorry about that :( – varaprakash Sep 10 '12 at 15:34
  • [Oleg](http://stackoverflow.com/users/315935/oleg): Could you please take a look at my question [here](http://stackoverflow.com/questions/12206260/jqgrid-auto-wrapping-for-dynamic-column-binding) when you get a chance. Thanks in advance... – varaprakash Sep 14 '12 at 16:08
  • @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? – Oleg Sep 14 '12 at 16:16
  • 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.. – varaprakash Sep 14 '12 at 20:58
  • @janina: I wrote in my answer that the above code is not oriented on sorting, paging, hovering and selection features of jqGrid. – Oleg Mar 19 '14 at 06:36
  • can you tell me what should I do? – Mir Gulam Sarwar Mar 19 '14 at 06:51
  • @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. – Oleg Mar 19 '14 at 07:01
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.

pistipanko
  • 745
  • 5
  • 9
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 :)

Zorkind
  • 607
  • 12
  • 21
  • You're right, I've edited my solution too for my needs, simularly like you did, it's just an examle. – pistipanko Oct 26 '12 at 10:44
  • 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 :) – Zorkind Oct 29 '12 at 15:39