18


I love jqGrid but sometimes things seem more complicated than they should be.
What I would like to achieve is to have a checkbox on each row so that a user can choose which rows are going to be submitted/processed.
I need, though, to block some checkboxes cause the user has no authorization on that particular row, maybe.

I've tried to set multiselect: true and then I've tried to hide the checkbox:

loadComplete: function (data) {
    if (data.rows.length > 0) {
        for (var i = 0; i < data.rows.length; i++) {
            if (data.rows[i].cell[7] == 'false') {
                $("#jqg_OrdersGrid_" + data.rows[i].id).css("visibility", "hidden");
            }
        }
    }
},

and it works well but, still, .jqGrid('getGridParam', 'selarrrow') give me the selected rows, even if they haven't been checked.
Is there any other way to have checkboxes which are enabled/disabled and a way to know which ones have been checked?

thanks

LeftyX
  • 35,328
  • 21
  • 132
  • 193

5 Answers5

31

I would suggest you to disable some checkboxed from the be selectable with respect of "disabled" attribute. To make full implementation you will need

  1. set "disabled" inside of loadComplete event handle
  2. additionally prevent selection of disabled rows inside beforeSelectRow event handle
  3. to have support of "select all" checkbox in the header of the multiselect column implement onSelectAll event handle which fix selection of disabled rows.

The corresponding demo can you see here. The most important part of the code is here:

var grid = $("#list10"), i;
grid.jqGrid({
    //...
    loadComplete: function() {
        // we make all even rows "protected", so that will be not selectable
        var cbs = $("tr.jqgrow > td > input.cbox:even", grid[0]);
        cbs.attr("disabled", "disabled");
    },
    beforeSelectRow: function(rowid, e) {
        var cbsdis = $("tr#"+rowid+".jqgrow > td > input.cbox:disabled", grid[0]);
        if (cbsdis.length === 0) {
            return true;    // allow select the row
        } else {
            return false;   // not allow select the row
        }
    },
    onSelectAll: function(aRowids,status) {
        if (status) {
            // uncheck "protected" rows
            var cbs = $("tr.jqgrow > td > input.cbox:disabled", grid[0]);
            cbs.removeAttr("checked");

            //modify the selarrrow parameter
            grid[0].p.selarrrow = grid.find("tr.jqgrow:has(td > input.cbox:checked)")
                .map(function() { return this.id; }) // convert to set of ids
                .get(); // convert to instance of Array
        }
    }
);

UPDATED: Free jqGrid supports hasMultiselectCheckBox callback, which can be used to create multiselect checkboxes not for all rows of jqGrid. One can use rowattr to disable some rows additionally. As the result one will get the described above functionality in more simple way. It's recommended to use multiPageSelection: true option additionally for free jqGrid with local data (datatype: "local" or loadonce: true). The option multiPageSelection: true will hold the array selarrrow on paging. It allows "pre-select" some rows by filling the corresponding ids inselarrrow. See UPDATED part of the answer and the answer with the demo for additional information.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • 3
    Thanks Oleg. Always professional in your answers ;-) I love the fact that your code is completed with custom examples. Actually, I still would like to be able to select the row cause for me the fact the row is checked has nothing to do with the selection. I've find a work-around.I'll show you some code. – LeftyX Mar 10 '11 at 14:27
  • I've replied to my question but I won't accept it. It's not fair. Try to see what you think and they I'll accept yours. – LeftyX Mar 10 '11 at 14:34
  • @LeftyX: You code looks OK. Any kind of optimizations could be not needed if in your grids will be a few rows. – Oleg Mar 10 '11 at 14:55
  • For me, `onSelectAll` still seems to select the row (even w/ the `beforeSelectRow`), though `beforeSelectRow` does seem to prevent the row from being selected on click. – Ron Garrity Feb 08 '12 at 18:34
  • @RonGarrity: In which web browser you test [the demo](http://www.ok-soft-gmbh.com/jqGrid/DataToMultiSelect2Blocked.htm) and be able select disabled rows? – Oleg Feb 08 '12 at 19:40
  • @Oleg Can you tell I'm working on grids again Dr.? Thank you! – Stephen Patten Feb 21 '13 at 20:58
  • @StephenPatten: You are welcome! Sorry, but I didn't understand your question. – Oleg Feb 21 '13 at 21:04
  • @Oleg I have no new questions yet :) I'm finding that you've answered everything so far. Take care Dr. – Stephen Patten Feb 21 '13 at 21:56
  • @Oleg Once again you have helped me greatly :) – will824 Jan 22 '14 at 17:03
  • My version of jQGrid also required me to add `cbs.closest('tr').removeClass('ui-state-highlight');` to the onSelectAll function. – AaronSieb Jan 12 '15 at 16:57
  • @AaronSieb @RonGarrity I have implemented what I consider a little cleaner version of the `onAllSelect` function. See https://jsfiddle.net/ndnckw1t/ – Ben May 31 '15 at 16:06
  • @Ben: Sorry, but the answer is *very old*. jqGrid have now many other features and I know JavaScript much better as 4 years before. Moreover there are many reasons why the rows could be "protected". In many cases one it would be just god to disable the whole rows of the grid. One can do this by adding `rowattr` which set `ui-state-disabled` class and setting `pointer-events: none;` additionally. See http://jsfiddle.net/OlegKi/aagxejj5/42/ created for [the answer](http://stackoverflow.com/a/30365450/315935). I'm not sure which scenario use you, but probably it could help. – Oleg May 31 '15 at 16:44
  • @Oleg Awesome. Thanks! I'll use the other answer as a reference to improve the next time I do this task. – Ben May 31 '15 at 19:53
  • Worked for me but i have to add `cbs.parent().parent().removeClass("ui-state-highlight");` to un-highlight the rows. – Dot_NET Pro Aug 21 '19 at 11:43
  • 1
    @Dot_NETPro: Please write always which fork and version of jqGrid you use. The answer is written 8 years ago and worked for current version of jqGrid at the time. Later introduced features can required to adjust the old code. For example, if one uses `idPrefix` option, introduced later, then `$("tr#"+rowid+...` from `beforeSelectRow` will not work. One have to add `idPrefix`. If you use [free jqGrid](https://github.com/free-jqgrid/jqGrid) then you should use `hasMultiselectCheckBox` which will prevent creating unneeded checkboxes instead of making DOM modification every time. – Oleg Aug 21 '19 at 11:52
5

Great answer from Oleg, I would also add code to deselect disabled rows, complete onSelectAll function below.

onSelectAll: function(aRowids,status) {
    if (status) {
        // uncheck "protected" rows
        var cbs = $("tr.jqgrow > td > input.cbox:disabled", grid[0]);
        cbs.removeAttr("checked");

        //modify the selarrrow parameter
        grid[0].p.selarrrow = grid.find("tr.jqgrow:has(td > input.cbox:checked)")
            .map(function() { return this.id; }) // convert to set of ids
            .get(); // convert to instance of Array

        //deselect disabled rows
        grid.find("tr.jqgrow:has(td > input.cbox:disabled)")
            .attr('aria-selected', 'false')
            .removeClass('ui-state-highlight');
    }
}
3

For people (like me) that end up on this answer after searching on Google, there is a very easy solution to this problem since jqGrid 4.0.0.

It's enough to add the css-class 'ui-state-disabled' to the row that you don't want to be selected. See The changelog of jqGrid 4.0.0. And you could still combine that with hiding or disabling the checkbox.

    var $jqgrid = $("#jqgridselector");         
    //loop through all rows
    $(".jqgrow", $jqgrid).each(function (index, row) {
        var $row = $(row);
        if ($row === condition) {
            //Find the checkbox of the row and set it disabled
            $row.find("input:checkbox").attr("disabled", "disabled");
            //add class ui-state-disabled, because thats how jqGrid knows not to take them into account for selection
            $row.addClass("ui-state-disabled");
            //I overwrite the opactity of the ui-state-disabled class to make the row look 'normal'
            $row.css("opacity", 1);
            }
        });
cverb
  • 645
  • 6
  • 20
3

I've found a work-around. During the loadComplete event I disable the SelectAll checkbox: I don't need it. I also hide the checkbox and disable it.

loadComplete: function (data) {
    $("#cb_OrdersGrid").css("visibility", "hidden");
    if (data.rows.length > 0) {
        for (var i = 0; i < data.rows.length; i++) {
            if (data.rows[i].cell[7] == 'false') {
                $("#jqg_OrdersGrid_" + data.rows[i].id).css("visibility", "hidden");
                $("#jqg_OrdersGrid_" + data.rows[i].id).attr("disabled", true);
            }
        }
    }
}

Now, when I want to submit my data I loop through the selected rows and check if they've been disabled and put those which are enabled in a new array.

var selectedRows = myGrid.jqGrid('getGridParam', 'selarrrow');
var checkedRows = [];
var selectionLoop = 0;
for (var x = 0; x < selectedRows.length; x++) {
    var isDisabled = $('#jqg_OrdersGrid_' + selectedRows[x]).is(':disabled');
    if (!isDisabled) {
        checkedRows[selectionLoop] = selectedRows[x];
        selectionLoop++;
    }
}

What I've achieved now is to be able to select a row conditionally being able to check it or not.
I know the code is not optimized (forgive me Oleg) but I'll do it later.

LeftyX
  • 35,328
  • 21
  • 132
  • 193
2

I'm using jqGrid 4.4.4 and I had to tweak LetfyX loadComplete just a little.

            loadComplete: function(data) {
                for (var i = 0; i < data.rows.length; i++) {
                    var rowData = data.rows[i];
                    if (rowData.cell[6] != null) {//update this to have your own check
                        var checkbox = $("#jqg_list_" + rowData.i);//update this with your own grid name
                        checkbox.css("visibility", "hidden");
                        checkbox.attr("disabled", true);
                    }
                }
            }
jhilden
  • 12,207
  • 5
  • 53
  • 76