Disabling Browser Context Menu When Using Grid Context Menu

I’ve seen several examples on this site of how to disable the browser context menu for FireFox, etc; but none of these are working on the current version of FireFox that I am using:

Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3

The examples I have seen involve the use of DHTMLxEvent in the following ways:

To disable browser context menu for the entire body of the document:

dhtmlxEvent(document.body,"contextmenu",function(e){ (e||event).cancelBubble=true; return false; });

To disable browser context menu for the grid object:

dhtmlxEvent(gridhandle.entBox,"contextmenu",function(e){ (e||event).cancelBubble=true; return false; });

I’ve tried both of the above with no luck. The browser context menu pops up regardless; and it obscures my custom context menu.

Another possibility that I have tried, which works for disabling the browser context menu; but also disables the custom DHTMLxMenu context menu is:

function OnContextMenuEvent() {return false;} window.oncontectmenu=OnContextMenuEvent();

Here is some of my code, so you can reconstruct this, in case it doesn’t happen on your end:

/**
 * Class: ClientInsurance
 *
 * Purpose: Construct the ClientInsurance object
 * 
 * @param insuranceGrid_id		- id of the grid to which to bind the client insurance grid
 * @param blankProviderString	- string to use for the dynamically created blank provider row
 * @param clientId				- id of the client being edited
 */
function ClientInsurance(insuranceGrid_id, blankProviderString, clientId) {
	this.insurancegrid_id		= insuranceGrid_id;
	this.insurancegrid			= null;
	this.blankProviderString	= blankProviderString;
	this.clientId				= clientId;
	this.dhtmlxMenuIconPath		= 'dhtmlx_build91111/dhtmlxMenu/imgs/';
	this.dhtmlxImgUrl			= 'dhtmlx_build91111/imgs/';
	
	this.contextMenu			= null;
}

/**
 * INITIALIZE THE ClientInsurance OBJECT
 *
 * Purpose: This function instantiates the client insurance grid and context menu.
 */
ClientInsurance.prototype.init=function() {

	this.initClientInsuranceGrid();				// INITIALIZE THE CLIENT INSURANCE GRID
	this.initClientInsuranceGridContextMenu();	// INITIALIZE THE RIGHT-CLICK MENU
}
/**
 * INITIALIZE THE GRID CONTAINING THE INSURANCE SELECTIONS FOR THE CLIENT
 *
 * Purpose: This function instantiates and configures the client insurance grid
 */
ClientInsurance.prototype.initClientInsuranceGrid=function() {
	
	this.insurancegrid = new dhtmlXGridObject(this.insurancegrid_id);
	newId = 0;	// sentinal for new rows
	this.insurancegrid.imgURL = this.dhtmlxImgUrl; 
	this.insurancegrid.setSkin("light");
	this.insurancegrid.init();
	dhtmlxEvent(this.insurancegrid,"contextmenu",function(e){
		(e||event).cancelBubble=true;
		return false;
	});
	this.insurancegrid.enableLightMouseNavigation(false);
	this.insurancegrid.loadXML('clientEdit.do?action=getInsuranceXML&cid=' + this.clientId);
	this.insurancegrid.parentObject = this;
	// WHEN A CELL IS EDITED, ADD A BLANK ROW BELOW TO ALLOW FOR ADDITIONAL PROVIDERS
	this.insurancegrid.attachEvent("onEditCell", function(stage,rId,cInd,nValue,oValue){
		if(cInd == 0 && oValue == this.parentObject.blankProviderString) {
			console.debug('blank provider row used, creating new row');
			this.addRow("new_" + newId++ ,this.parentObject.blankProviderString + ",,");
		}
		return nValue;
	});
}
/**
 * INITIALIZE THE RIGHT-CLICK CONTEXT MENU FOR THE CLIENT INSURANCE GRID
 *
 * Purpose: This function instantiates and configures the context menu for the
 *			client insurance grid.
 */
ClientInsurance.prototype.initClientInsuranceGridContextMenu=function() {
	this.contextMenu = new dhtmlXMenuObject();
    this.contextMenu.renderAsContextMenu();
//	this.contextMenu.addContextZone(this.insurancegrid_id);
    this.contextMenu.setIconsPath(this.dhtmlxMenuIconPath);
	this.contextMenu.addNewChild(this.contextMenu.topId, 0, "delete", "Delete", false );
    this.contextMenu.addNewChild(this.contextMenu.topId, 1, "new", "Add New Provider", false);
	this.insurancegrid.enableContextMenu(this.contextMenu);
	this.contextMenu.parentGrid = this.insurancegrid;
	this.contextMenu.parentObject = this;
	// handle clicks on the menu items
    this.contextMenu.attachEvent("onClick", function(id, zoneId, casState) {
    	var data = this.parentGrid.contextID.split("_");

    	rid = data[0];
   	 		
   	 	// delete option selected
   	 	if(id == 'delete') {
			//var rid = insurancegrid.getSelectedRowId();
			alert("current row selection is: " + rid);

			// don't allow the user to delete the "blank" row
			if(this.parentGrid.cells(rid, 0).getValue() != this.parentObject.blankProviderString) {
				this.parentGrid.deleteRow(rid);
			}
		}
	});
}

Here are the relevant pieces of the html document which call the javascript:

<div id="insuranceGrid" style="overflow:hidden;height: 120px;width: 600px;" ></div>

<script type="text/javascript">
var clientInsurance = new ClientInsurance('insuranceGrid', '-- select a provider --', '244454711');
clientInsurance.init();
</script>

This may be related to specific of FF on Macintosh, because the same code works on ff-windows

Are you using two button mouse or MacKey-Click combination for context menu showing ?

Thanks for the quick turnaround time. I am using a standard multitouch touchpad, on a macbook pro laptop (the version manufactured in late 2008). In order to right click on this touchpad, you touch with two fingers.

I didn’t realize that this event was handled differently by the browsers.

I have also heard from one of the other developers that right-clicking on an attached mouse on a macbook pro is having the same issue. So it looks like the issue is not isolated to the touchpad; but also happens with a standard mouse.

If this use-case is really critical , we can provide some kind of test page for further investigation

As fast soluiton , in addition to already existing code block, you can try to add the next one

dhtmlxEvent(document.body,"mouseup",function(e){ (e||event).cancelBubble=true; return false; });

blocking both mouseup and contextmenu events must prevent native menu nearly in all use-cases, still it possible that drivers of your touchpad doesn’t generate browser events at all ( as it occurs for Ctrl-Click ) and reaction can’t be blocked.

that right-clicking on an attached mouse on a macbook pro is having the same issue
It maybe related to the specific OS version, because on local Mac mouse-right-clicks are generating contextmenu event and can be blocked ( Ctrl-Click, on other hand, can’t be blocked and always show a native menu )

I tried the following code on the Mac version of FireFox as well as the Windows version.

	dhtmlxEvent(document.body,"contextmenu",function(e){
		(e||event).cancelBubble=true;
		return false;
	});
	dhtmlxEvent(document.body,"mouseup",function(e){
		(e||event).cancelBubble=true;
		return false;
	});

The windows version works okay in regards to right-clicking the grid. The custom context menu comes up and browser context menu is hidden. I did notice that the browser context menu is still coming up when I click on other parts of the body; I would have expected that passing document.body to the dhtmlxEvent object would eliminate the event for the entire body of the page.

I don’t need the context menu eliminated for the entire body of the page; but I figured it worth pointing out that I was seeing this kind of behavior.

On the Mac version of FireFox, however, I wasn’t seeing any change in behavior. In every case the browser menu would come up, even with the fix described above. I suppose the Mac events are created somewhat differently from those on Windows.

For our application, the most important thing is that it run well on Windows; but it would be nice to have it working in OSX as well. Anything you guys can do to make this work better in OSX would be greatly appreciated.

I’ll be happy to provide you with any samples you need, or test it from here; to see if it works okay in the Mac environment.

Re earlier comment that “I did notice that the browser context menu is still coming up when I click on other parts of the body”…

This is because the document body may not fill the entire window. Those parts of the window that extend beyond the area of the document body won’t have the context menu suppressed. This is easily demonstrated by adding a series of
tags at the end of the HTML body. Sure enough, the context menu is more suppressed — until the end of the body is again reached.