Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jqGrid - click, right click, onSelectRow

In jqGrid, Is there a "built-in" way to know what mouse button was clicked, before row selection?

Currently we have jqGrid with some actions bind on "onSelectRow" event of jqGrid. The problem is that when user right click on that row, onSelectRow event raised to and action performed. What I need, is to ignore "onSelectRow" when user right click on a row.

EDIT: I know there exists onRightClickRow event, but it raised after onSelectRow and action already performed.

I found that I can know what button clicked by "type" of event object. When it's click, the type is "click" when it's right click, the type is "contextmenu"....Does exists the additional way, or I must check type to know what button is clicked?

Thanks

like image 773
Alex Dn Avatar asked Oct 28 '12 12:10

Alex Dn


1 Answers

It's good question! The reason of such behavior is the following. jqGrid register an event handler for the event contextmenu on the whole grid <table> element with the following code (see here)

.bind('contextmenu', function(e) {
    td = e.target;
    ptr = $(td,ts.rows).closest("tr.jqgrow");
    if($(ptr).length === 0 ){return;}
    if(!ts.p.multiselect) { $(ts).jqGrid("setSelection",ptr[0].id,true,e);  }
    ri = ptr[0].rowIndex;
    ci = $.jgrid.getCellIndex(td);
    $(ts).triggerHandler("jqGridRightClickRow", [$(ptr).attr("id"),ri,ci,e]);
    if ($.isFunction(this.p.onRightClickRow)) {
        ts.p.onRightClickRow.call(ts,$(ptr).attr("id"),ri,ci, e);
    }
});

How one can see from the code it calls setSelection method and calls onRightClickRow callback and trigger jqGridRightClickRow event. So if you don't need the selection of rows and if you don't use onRightClickRow and jqGridRightClickRow you can just unbind the event handler:

$("#list").unbind("contextmenu");

If you do want use onRightClickRow callback or if you don't sure whether you need to use jqGridRightClickRow somewhere you can "subclass" the event handler. The implementation is depend a little from the version of jQuery which you use. Starting with jQuery 1.8 one should use a little another call to get the current events registered on the DOM element. The corresponding code could be about the following:

//$grid.unbind('contextmenu');

var getEvents = $._data($grid[0], "events"); // $grid.data("events") in jQuery ver<1.8
if (getEvents && getEvents.contextmenu && getEvents.contextmenu.length === 1) {
    var orgContextmenu = getEvents.contextmenu[0].handler;
    $grid.unbind('contextmenu', orgContextmenu);
    $grid.bind('contextmenu', function(e) {
        var oldmultiselect = this.p.multiselect, result;
        this.p.multiselect = true; // set multiselect to prevent selection
        result = orgContextmenu.call(this, e);
        this.p.multiselect = oldmultiselect; // restore multiselect
        return result;
    });
}

The demo demonstrate the above code live.

like image 73
Oleg Avatar answered Sep 28 '22 07:09

Oleg