jqGrid - click, right click, onSelectRow
Asked Answered
N

2

7

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

Nosing answered 28/10, 2012 at 12:8 Comment(0)
S
10

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.

Starstarboard answered 28/10, 2012 at 12:58 Comment(4)
Very nice solution - works perfectly!! I don't think I would able to achieve that myself!! Thanks :) Just additional off-topic simple question...in line "var oldmultiselect = this.p.multiselect, result;". What means comma between "this.p.multiselect" and "result"? I have not bad JS knowledge, but can not recall how should that work? Does it used to set result = undefined?Nosing
@AlexDn: It defines two variables oldmultiselect and result and initializes the first one. JavaScript has no block level variables. So all the variables which are defined in the function body will be defined at the beginning of the function. If some variable will be defined later the real code will be definition in the fisrt line with initialization to undefined and assignment instead of definition later. So it's recommended to define all variables needed inside the function in the first statement var. Si I use var oldmultiselect = this.p.multiselect, result;.Starstarboard
@AlexDn: If one would follow the above rule one should define getEvents and orgContextmenu at the begin of my main code. I didn't follow the rule in the case only to be able to post the full fragment of code in my answer. In the real code I will be move definition of getEvents and orgContextmenu above and I would have in the corresponding statements no var, so I would have assignments instead of definition with initialization.Starstarboard
Thank you Oleg, you have very descriptive answers!!Nosing
N
0

Events are listed here: http://www.trirand.com/jqgridwiki/doku.php?id=wiki:events

There is an onRightClickRow event.

Also, using the plain jquery event object and which will tell you. http://api.jquery.com/event.which/

You must use 3rd parameter to onRowSelected and which or the type like you mentioned.

Nadya answered 28/10, 2012 at 12:26 Comment(3)
Right, but before onRightClickRow raised, onSelectRow raised and action performed, so to check "which" in onRightClickRow is too late :(Nosing
I tried it, but for both, left and right click, the event object (3d parameter in onSelectRow) has 0 value in "which" property :(Nosing
Can't you use type and context menu with an if statement then?Nadya

© 2022 - 2024 — McMap. All rights reserved.