I am using some functionality I found over here: http://www.trendskitchens.co.nz/jquery/contextmenu/
It gets me started making a nice Context Menu. My purpose was to get this context menu to "Pop" on right OR left click. But I might not ALWAYS want to bind the left click, so I need to be able to always do right click, and when I want, make the left click work too with a bit of code.
First, to test you will need jQuery for the demo, I am using 1.8.2
Here is the source of the plugin:
/*
* ContextMenu - jQuery plugin for right-click context menus
*
* Author: Chris Domigan
* Contributors: Dan G. Switzer, II
* Parts of this plugin are inspired by Joern Zaefferer's Tooltip plugin
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Version: r2
* Date: 16 July 2007
*
* For documentation visit http://www.trendskitchens.co.nz/jquery/contextmenu/
*
*/
(function($) {
var menu, shadow, trigger, content, hash, currentTarget;
var defaults = {
menuStyle: {
listStyle: 'none',
padding: '1px',
margin: '0px',
backgroundColor: '#fff',
border: '1px solid #999',
width: '100px'
},
itemStyle: {
margin: '0px',
color: '#000',
display: 'block',
cursor: 'default',
padding: '3px',
border: '1px solid #fff',
backgroundColor: 'transparent'
},
itemHoverStyle: {
border: '1px solid #0a246a',
backgroundColor: '#b6bdd2'
},
eventPosX: 'pageX',
eventPosY: 'pageY',
shadow : true,
onContextMenu: null,
onShowMenu: null
};
$.fn.contextMenu = function(id, options) {
if (!menu) { // Create singleton menu
menu = $('<div id="jqContextMenu"></div>')
.hide()
.css({position:'absolute', zIndex:'500'})
.appendTo('body')
.bind('click', function(e) {
e.stopPropagation();
});
}
if (!shadow) {
shadow = $('<div></div>')
.css({backgroundColor:'#000',position:'absolute',opacity:0.2,zIndex:499})
.appendTo('body')
.hide();
}
hash = hash || [];
hash.push({
id : id,
menuStyle: $.extend({}, defaults.menuStyle, options.menuStyle || {}),
itemStyle: $.extend({}, defaults.itemStyle, options.itemStyle || {}),
itemHoverStyle: $.extend({}, defaults.itemHoverStyle, options.itemHoverStyle || {}),
bindings: options.bindings || {},
shadow: options.shadow || options.shadow === false ? options.shadow : defaults.shadow,
onContextMenu: options.onContextMenu || defaults.onContextMenu,
onShowMenu: options.onShowMenu || defaults.onShowMenu,
eventPosX: options.eventPosX || defaults.eventPosX,
eventPosY: options.eventPosY || defaults.eventPosY
});
var index = hash.length - 1;
$(this).bind('contextmenu', function(e) {
// Check if onContextMenu() defined
var bShowContext = (!!hash[index].onContextMenu) ? hash[index].onContextMenu(e) : true;
if (bShowContext) display(index, this, e, options);
return false;
});
return this;
};
function display(index, trigger, e, options) {
var cur = hash[index];
content = $('#'+cur.id).find('ul:first').clone(true);
content.css(cur.menuStyle).find('li').css(cur.itemStyle).hover(
function() {
$(this).css(cur.itemHoverStyle);
},
function(){
$(this).css(cur.itemStyle);
}
).find('img').css({verticalAlign:'middle',paddingRight:'2px'});
// Send the content to the menu
menu.html(content);
// if there's an onShowMenu, run it now -- must run after content has been added
// if you try to alter the content variable before the menu.html(), IE6 has issues
// updating the content
if (!!cur.onShowMenu) menu = cur.onShowMenu(e, menu);
$.each(cur.bindings, function(id, func) {
$('#'+id, menu).bind('click', function(e) {
hide();
func(trigger, currentTarget);
});
});
menu.css({'left':e[cur.eventPosX],'top':e[cur.eventPosY]}).show();
if (cur.shadow) shadow.css({width:menu.width(),height:menu.height(),left:e.pageX+2,top:e.pageY+2}).show();
$(document).one('click', hide);
}
function hide() {
menu.hide();
shadow.hide();
}
// Apply defaults
$.contextMenu = {
defaults : function(userDefaults) {
$.each(userDefaults, function(i, val) {
if (typeof val == 'object' && defaults[i]) {
$.extend(defaults[i], val);
}
else defaults[i] = val;
});
}
};
})(jQuery);
$(function() {
$('div.contextMenu').hide();
});
And the Source of my Page:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><!-- InstanceBegin template="/Templates/Workflow.dwt.php" codeOutsideHTMLIsLocked="false" -->
<head>
<script type="text/javascript" src="../jQuery/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="../../Common/clientscript.js"></script>
<script type="text/javascript" src="jquery.actions.js"></script>
<script>
$(document).ready(function() {
/// Replace the intrinsic Context Menu with MINE
$('span.infoholder').contextMenu('myMenu',{
onContextMenu: function(e)
{
iDataID = $(e.target).attr('id').replace("menu_","");
iGroupID = $(e.target).attr('name');
}
});
/// Get the Left Click to behave as the right click...
$("span.infoholder").click(function(event) {
alert("I am in " + event.which);
// on right click
if (event.which == "1")
{
// prevent left click from being interpreted by the browser:
$("#"+$(event.target).attr("id")).trigger({
type: 'click',
which: 3
});
}
});
});
</script>
</head>
<body>
<div class="contextMenu" id="myMenu">
<li>Test 1</li>
<li>Test 2</li>
</div>
<span class="infoholder" id="menu_34675" name="1" style="border:solid 1px grey; padding: 2px 5px 2px 5px; background-color:#d9f7ff;">Actions </span><br/><br/>
<span class="infoholder" id="menu_34735" name="1" style="border:solid 1px grey; padding: 2px 5px 2px 5px; background-color:#d9f7ff;">Actions </span><br/><br/>
</body>
</html>
There is a bit missing from this, but the source here gives us an good sample to get started on the problem. Which again is "How to get the left click to invoke the custom context menu of this plugin"
Here is the answer, BIND it to the click in the plugin Javascript
Just add the 'contextmenu to the items binding to: