jQuery Context Menu Plugin

A context menu plugin for jQuery that features easy implementation, keyboard shortcuts, CSS styling, and control methods.

Contents

Overview

jQuery Context Menu is a context menu plugin for jQuery. It was designed to make implementing context menu functionality easy and requires minimal effort to configure.

There is another context menu for jQuery written by Chris Domigan. These two projects are completely unrelated and no source code was shared from Chris’ project.

Why reinvent the wheel? The goal of this plugin is to streamline the way actions are binded to menu items and to use 100% CSS for styling. Keyboard shortcuts were added for navigating the menu once it’s open, and there are five methods to allow you to control and clean-up context menus on the fly.

Features

Compatibility

This plugin requires jQuery 1.2.6 or above and has been tested to work in the following browsers:

*Opera 9.5 has an option to allow scripts to detect right-clicks, but it is disabled by default. Furthermore, Opera still doesn’t allow JavaScript to disable the browser’s default context menu which causes a usability conflict.

Demo

View a live demonstration of the context menu plugin.

Download

Current version: Version 1.0 (14 September 2008)

This plugin is provided to you as-is, at absolutely no cost. If you would like to support its development, feel free to contribute any amount you prefer via PayPal. As always, you are welcome to contribute code for bug fixes and feature enhancements as well. Either way, thanks for supporting our efforts!

Usage

Dependencies

jQuery Context Menu requires jQuery 1.2.6 or above (or jQuery 1.2 with the dimensions plugin).

Creating

First, create a list in your HTML that will be the markup for your context menu:

<ul id="myMenu" class="contextMenu">
    <li class="edit">
        <a href="#edit">Edit</a>
    </li>
    <li class="cut separator">
        <a href="#cut">Cut</a>
    </li>
    <li class="copy">
        <a href="#copy">Copy</a>
    </li>
    <li class="paste">
        <a href="#paste">Paste</a>
    </li>
    <li class="delete">
        <a href="#delete">Delete</a>
    </li>
    <li class="quit separator">
        <a href="#quit">Quit</a>
    </li>
</ul>

Actions are specified in the href attribute, preceeded by a # symbol. When selected, this is what will be passed back to the action parameter in the callback. You can add class attributes to the list items to assist with styling, but they have no functional meaning. Thus, class names do not have to correspond with actions.

Once you have created the markup for the context menu, bind it to one or more elements using JavaScript:

$(document).ready( function() {
   
    $("#selector").contextMenu({
        menu: ''myMenu''
    },
        function(action, el, pos) {
        alert(
            ''Action: '' + action + ''\n\n'' +
            ''Element ID: '' + $(el).attr(''id'') + ''\n\n'' +
            ''X: '' + pos.x + ''  Y: '' + pos.y + '' (relative to element)\n\n'' +
            ''X: '' + pos.docX + ''  Y: '' + pos.docY+ '' (relative to document)''
            );
    });
   
});

Make sure you change #selector to the appropriate jQuery selector that matches the element(s) you want to bind the context menu to. The selector can be any valid jQuery selector.

Methods

There are five methods you can use to control and clean-up the context menu after it has been instantiated.

MethodDescription
disableContextMenu() Disables the context menu on all matching elements
enableContextMenu() Re-enables the context menu on all matching elements
disableContextMenuItems(''#option1,#option2,...'') Disables the specified options on all matching elements. If null is passed, all elements will be disabled.
enableContextMenuItems(''#option1,#option2,...'') Enables the specified options on all matching elements. If null is passed, all elements will be enabled.
destroyContextMenu() Unbinds the context menu from all matching elements

As an example, to disable the context menu on a div with an ID of myDiv the code would look like this:

$("#myDiv").disableContextMenu();

Styling

The context menu relies 100% on CSS for styling. To give your users an aesthetically pleasing experience, you should either use the included stylesheet or create your own. Refer to jquery.contextMenu.css to make any changes in the styles.

Callback

The callback function fires if and only if a user makes a valid selection from the context menu. Three arguments are passed which you can use to control what happens when a user makes a selection:

ParamterDescription
action The action that corresponds to the menu item that was selected (I.E. the href attributes less the # symbol)
el The element object that triggered the context menu
pos.x Horizontal position of mouse cursor when menu was clicked (relative to the element)
pos.y Vertical position of mouse cursor when menu was clicked (relative to the element)
pos.docX Horizontal position of mouse cursor when menu was clicked (relative to the document)
pos.docY Vertical position of mouse cursor when menu was clicked (relative to the document)

See the example above for starter code.

Licensing & Terms of Use

This plugin is dual-licensed under the GNU General Public License and the MIT License and is copyright 2008 A Beautiful Site, LLC.

Comments

Does not for on my FF3.0.1 ... it works on IE7 ...

Hans on Sep 16th, 2008

@Hans: Do you happen to have the All-in-One mouse gestures plugin? If so, try disabling it - it seems to conflict with right-click events. A better plugin that doesn't conflict is Mouse Gestures Redox (https://addons.mozilla.org/en-US/firefox/addon/39).

Cory S.N. LaViska on Sep 16th, 2008

How i can find the option which allows scripts to detect right-clicks in Opera?

vladm on Sep 17th, 2008

@vladm: In Opera 9.5, Tools > Preferences > Advanced > Content > JavaScript Options.

Cory S.N. LaViska on Sep 17th, 2008

Do You plan fixing for well known IE5-6 bug, that makes visible select boxes "holes" if context menu (and any z-indexed div) overlaps them ? (Usually iframes are used to fix it)

Alexander on Sep 22nd, 2008

Nice work Cory! :)

James on Sep 22nd, 2008

This is great. It was easy to setup and use, the styling and functionality is almost what I need.

I'm using a Canvas tag and I need to present a different menu depending on where the user is in the tag. So I added in this functionality, you can specify a 'chooseMenu' function which gets given the coordinates structure and can return which menu to show.

Patch is here (http://www.xb95.com/contextMenu.diff) in case your interested. Caveat lector, of course, I'm pretty new to JS and jQuery. My changes work in my app but not certain if they are 'correct' or not. :)

Mark Smith on Sep 27th, 2008

This is great! It works like a champ!

I've only small issue: when context menu is displayed, it seems to disable onClick event handlers on the whole page. Did I anything wrong? How can I work around this?

Piotr Findeisen on Sep 30th, 2008

@Piotr: you're right, the plugin binds a click event to the document and then unbinds it when the menu is removed. You could work around this by creating an overlay that covers the entire screen and bind the click event to that. I'm really interested to see what people think would be the best way to handle this as, in your case and most likely others, the current behavior can cause interference.

Cory S.N. LaViska on Sep 30th, 2008

@Cory: you can take a look at jQuery Modals http://dev.iceburg.net/jquery/jqModal/ -- the implement overlay that doesn't interfere with my custom onClick events.

Piotr Findeisen on Sep 30th, 2008

@Cory: i've a patch that "works for me". There is still an issue with "destroyContextMenu" -- it unbinds to many handlers (example: I have <a> element with custom onClick event and context menu...)
Want me to post the patch here (99 lines or so)?

Piotr Findeisen on Oct 8th, 2008

Great idea, but doesnt work to well in my Safari (3)... need to click and right click several times before a menu pops up???

Paul on Oct 15th, 2008

I have a small problem - on IE7 I get actions like "ttp:/../../xx#cut". I can cut off the first part of the string in my application - but I probably is doing something wrong. I do not see this when running your demo - here action is "cut" etc.

Lisbeth on Oct 16th, 2008

@Paul: would you mind submitting some code, if possible? I have it running in a few apps and can't replicate the clicking issue in Safari 3.

@Lisbeth: Sounds like your href attribute is wrong. It should only be something like #cut, #copy, etc., not a full URL.

Cory S.N. LaViska on Oct 16th, 2008

Hello Cory,
what about sub-menus. Are they supported? Could you posible add a sub-menu example?

Martin on Oct 17th, 2008

@Martin: Submenus are not currently supported, but will be in the next version.

Cory S.N. LaViska on Oct 17th, 2008

Hello Cory,

Do you have a delay about the submenu feature ? :'-)
Because I need this feature to use your plugin.

I don't want speed you ^^

oxman on Oct 19th, 2008

Does this have to be bound? Can this be set to activate no matter where they right click on the site?

Rob on Oct 20th, 2008

#Rob: currently it has to be bound, but you raise a good point. It may be worthwhile considering a way to trigger the menu if the right click occurs period. You can probably add an event listener yourself to accomplish this without much difficulty.

Cory S.N. LaViska on Oct 20th, 2008

Good work, but I have some problems to detect witch item is clicked.

my html code is like this:
<ul id="items">
<li id="item1"><a href="#">Item 1</a>
<ul>
<li id="item1-1"><a href="#">Item 1.1</a></li>
</ul>
</li>
</ul>

So where I right click on item 1.1 and chose the menu i want to get the id of that item, in this case "item1-1". How can I do this?

Her is my JS:
$("#items").contextMenu({
menu: 'myMenu'
}, function(action, el, pos) {
alert(
'Action: ' + action + '\n\n' +
'Element ID: ' + $(el).attr('id') + '\n\n' +
'X: ' + pos.x + ' Y: ' + pos.y + ' (relative to element)\n\n' +
'X: ' + pos.docX + ' Y: ' + pos.docY+ ' (relative to document)'
);
});

odt on Oct 23rd, 2008

Hello Cory,
I try to use this plugin inside jquery.FileTree plugin to get menu to manipulate folders and files.
Generally it works, but menu shows up few centimeters from place of right-click.
I've added in jqueryFileTree.js folowing line :
$(t).find('LI A').contextMenu({
menu: 'myMenu'
}, function(action, el, pos) { alert('ok'); } );
under lines:
// Prevent A from triggering the # on non-click events
if( o.folderEvent.toLowerCase != 'click' ) $(t).find('LI A').bind('click', function() { return false; });
I've test it in firefox 3.0.3
Any ideas?

Lukasz on Oct 28th, 2008

@Lukasz: probably CSS. Do you have a link you could send?

Cory S.N. LaViska on Oct 28th, 2008

Hello Cory,
Thank you for your interest. It was CSS issue.
I had to div's like this:
<div id="container"><div id="file_list"></div></div>.
When I remove "position: relative" from #container style definition submenu shows up in right place.

Thanks

Lukasz on Oct 29th, 2008

Hi! Great menu!
Add please 'mouseButton' option, to allow user to set left button for menu opening instead of right button.

Thanks!

Yaroslav on Oct 29th, 2008

It goes without saying, but this stuff is awesome. I hadn't seen an example of how to integrate this with your grid. Do you have any examples?
Also, I modified the grid (crudely) to make it work with WCF json services. If you would like, I can send them to you, it works great.
Again, thanks.

Heath on Oct 29th, 2008

I have the same issue as Paul in Safari 3.1.2 on Leopard 10.5.5.
Exactly i have to click first with the right button and then the left button to see the context menu.
(no issues with http://www.trendskitchens.co.nz/jquery/contextmenu/)

Frank on Nov 1st, 2008

Cory, are the icons provided in the zip are distrubuted under the Creative Commons License too and did you yourself created them?
Regards from Germany,
Frank

Frank on Nov 1st, 2008

@Frank: I'm going to rework the way the context menu is binded to events which will hopefully solve that problem. It must be platform specific, as it doesn't happen in Safari 3.1.2 on Windows.

The icons are from the Silk Icons set: http://www.famfamfam.com/lab/icons/silk/

They are licensed under the Creative Commons Attribution 2.5 license.

Cory S.N. LaViska on Nov 1st, 2008

Right now the only callback is made on a click of a menu option. It would be nice to have another optional callback that could be made on the initial click so that menu options could be disabled or enabled based on the precise element clicked.

Greg on Nov 4th, 2008

I like how this is simple and uses pure CSS, one thing i changed for my purposes was I passed the evt, variable into my callback function.

So in the event you have child elements with children you can find exactly which element was selected via (e.target || e.srcElement).innerHTML where "e" is the new parameter. And i can just bind use the parent element in my selector.

Matt on Nov 10th, 2008

I needed a function to modify the contents of the menu depending on what I clicked on, so using I added a third parameter (a function) and send the source element to it.

This solution might help comment #29.

line 20 changed to:
contextMenu: function(o, callback, callfront) {

line 40 added:
if (callfront) callfront( $(srcElement) );

Jeff on Nov 11th, 2008

How could we make the contextmenu appear onhover and not by clicking.

andrewb on Nov 19th, 2008

@andrewb: You'd have to modify the current version of the plugin to do this. Look for this ability in the next release :)

Cory S.N. LaViska on Nov 20th, 2008

a couple of things:
- make this plugin dependent on your Right-click Plugin - this would allow rightclick event delegation, not just for this plugin either.
- remove internal hover event binding, they can be done with CSS...maybe not in ie6 tho, but you can always restyle the menu and css :hover on the anchor tags if needed.

thanks,
Leon

Leon Sorokin on Nov 21st, 2008

very nice plugin but it is considered good practise to try and take up only one namespace in jQuery.fn

adam j. sontag on Nov 24th, 2008

in Line 68: (e.pageY) ? y = e.pageY : x = e.clientY + d.scrollTop;

seems to be a typo: x = e.clientY has to be y = e.clientY

Or am I wrong?

uprocka on Nov 26th, 2008

I'm a complete CSS newbie. How do you make the context menu display with a drop shadow?

anonymous on Dec 5th, 2008

The demo seems not to work on Safari 3.2.1 (Leopard)

Marco on Dec 11th, 2008

FYI, I posted my code for adding this to the jQuery File Tree in comment #149 on this page:
http://abeautifulsite.net/notebook.php?article=58#comments

This adds one context menu to folders and a different one to files as each has different actions.

Tyler on Dec 11th, 2008

i'm trying to run a this script but not work ie7 and opera. i'm not tested under Firefox.

Sedat Kumcu on Dec 11th, 2008

I just found another bug. When pressing up the last option will set to hover even if it is disabled.

The line around Line 91
if( $(menu).find('LI.hover').size() == 0 ) $(menu).find('LI:last').addClass('hover');

should be
if( $(menu).find('LI.hover').size() == 0 ) $(menu).find('LI:not(.disabled):last').addClass('hover');

Kikuchyo on Dec 13th, 2008

Thank you SOOOOOO.... much for this script. It was 99.9% of what I wanted. I also wanted the ability to disable RIGHT mouse click on the body without disrupting RIGHT mouse click on the elements which I attached your right click menu.

The solution was to place:

$(document).bind("contextmenu",function(e){return false;});

right befor your javascript code. This prevents anyone from RIGHT mouseing and stealing source code, but the menus still work....

Thanks again!
Neal

Neal on Dec 19th, 2008

Any idea when support for nested menus would be added?

Thank you very much.

Robin on Dec 19th, 2008

Couple more small issues when inside a "overflow:auto" DIV. Need to sense how close to the right hand side of the div and how close to the bottom of the div and perhaps show the context menu where it will be in full view.

Off right side example: http://qwebmedia.com/jing/neal/2008-12-20_0753.png

Off bottom example: http://qwebmedia.com/jing/neal/2008-12-20_0754.png

Neal Chapman on Dec 20th, 2008

ODT:
==============
my html code is like this:
<ul id="items">
<li id="item1"><a href="#">Item 1</a>
<ul>
<li id="item1-1"><a href="#">Item 1.1</a></li>
</ul>
</li>
</ul>

==============

The issue is event bubble, as you have right clicked, there are two events generated--one from the children and the other from the parent.
However since the event order is:
children--->parent
the event will then bubble down to the parent, thus the children menu will be hidden and ignored.
To solve it:
in
$(this).mouseup( function(e) {
var srcElement = $j(this);
..................
return false; //add this! to prevent event bubble
}

HYL on Dec 31st, 2008

This thing worked so smoothly i frankly felt guilty for using it.

It's an awessome tool!

Smart design.

Simply elegant.

Mihai Stancu on Jan 13th, 2009

Not working at all in Safari 3.2.1 on OS X 10.5.6: Nothing happens when I control-click [right-click equivalent] on any of the menus in the demo. I don't even get the default Safari contextual menu.

Works OK in Firefox 3, although the menu only appears on mouse-up, not on mouse-down as I'd expect (maybe that's the Windows behavior? But on a Mac it feels subtly wrong.)

Jens Alfke on Jan 17th, 2009

/* UL - menu block */
/* LI - menu item */
/* rcMenu - menu name r(ight)c(lick)Menu */
/* menu block formating for menu and submenus */
/* parent menu-item describes sub-menu behaviour */

/* default behaviour */
ul.rcMenu,
ul.rcMenu li > ul
{
position: absolute; /* to preserve page layout */
z-index: 99999; /* to be over the top */
border: solid 1px #777; /* border design */
background: #eee; /* for design */
padding: 0px; /* for design */
margin: 0px; /* for design */
display: none; /* hidden by default */
top: 0px; /* lineup to parent element */
width: 100px; /* width = left */
left: 100px; /* offset from parent with the same width*/
}

ul.rcMenu li.separator { /* for separator */
border-top: solid 1px #777; /* border design */
}

ul.rcMenu li {
line-height: 20px; /* height pictire regardless */
list-style: none; /* hide enumeration - ths will be a menu */
padding: 0px; /* for design */
margin: 0px; /* for design */
position: relative; /* most interesting patr */
/* offset from menu block makes positin relative from */
/* parent element: parent-menu-item */
}

ul.rcMenu li A /* links in menu */
{
color: #333; /* color */
text-decoration: none; /* no animation no underscore ... normal text */
background-position: 6px ;
background-repeat: no-repeat;
outline: none;
padding: 1px 5px;
padding-left: 28px;
display: block; /* necessary to ocupate whole LI element from menu */
}


/* selection behaviour */
ul.rcMenu li:hover > ul /* over menu-item with child sub-menu */
{ display: block; } /* makes sub-menu visible */

ul.rcMenu li:hover, /* selected menu-item design */
ul.rcMenu li:hover > ul li:hover /* the same design for sub-menu-items */
{
background-color: #777; /* background - selected */
color: #000; /* if menu-item is just a text - not link */
}

ul.rcMenu li a:hover { color: #fff; } /* selected-menu-link */
ul.rcMenu li:hover > a { color: #fff; } /* selected-sub-menu-link */

ul.rcMenu li.disabled {
display: none; /* disabled === hidden */
}


/**********************************************************************************************/

/*
Adding Icons

You can add icons to the context menu by adding
classes to the respective li element(s)
*/

ul.rcMenu li.edit A { background-image: url(images/page_white_edit.png); }
ul.rcMenu li.cut A { background-image: url(images/cut.png); }
ul.rcMenu li.copy A { background-image: url(images/page_white_copy.png); }
ul.rcMenu li.paste A { background-image: url(images/page_white_paste.png); }
ul.rcMenu li.delete A { background-image: url(images/page_white_delete.png); }
ul.rcMenu li.quit A { background-image: url(images/door.png); }

rcMenu on Jan 20th, 2009

// This software is modification of
// jQuery Context Menu Plugin
// from http://abeautifulsite.net/notebook/80
// modifications:
// - deleted keyboard navigation
// - deleted java script menu animation / navigation /
// - css based menu animation / navigation /
// - submenu suport

if(jQuery)( function() {
$.extend($.fn, {

rcMenu: function(o, callback) {
// Defaults
if( o.menu == undefined ) return false;
if( o.inSpeed == undefined ) o.inSpeed = 150;
if( o.outSpeed == undefined ) o.outSpeed = 75;
// 0 needs to be -1 for expected results (no fade)
if( o.inSpeed == 0 ) o.inSpeed = -1;
if( o.outSpeed == 0 ) o.outSpeed = -1;
// Loop each context menu
$(this).each( function() {
var el = $(this);
var offset = $(el).offset();
// Add rcMenu class
$('#' + o.menu).addClass('rcMenu');
// Simulate a true right click
$(this).mousedown( function(e) {
var evt = e;
$(this).mouseup( function(e) {
var srcElement = $(this);
$(this).unbind('mouseup');
if( evt.button == 2 ) {
// Hide context menus that may be showing
$(".rcMenu").hide();
// Get this context menu
var menu = $('#' + o.menu);

if( $(el).hasClass('disabled') ) return false;

// Detect mouse position
var d = {}, x, y;
if( self.innerHeight ) {
d.pageYOffset = self.pageYOffset;
d.pageXOffset = self.pageXOffset;
d.innerHeight = self.innerHeight;
d.innerWidth = self.innerWidth;
} else if( document.documentElement &&
document.documentElement.clientHeight ) {
d.pageYOffset = document.documentElement.scrollTop;
d.pageXOffset = document.documentElement.scrollLeft;
d.innerHeight = document.documentElement.clientHeight;
d.innerWidth = document.documentElement.clientWidth;
} else if( document.body ) {
d.pageYOffset = document.body.scrollTop;
d.pageXOffset = document.body.scrollLeft;
d.innerHeight = document.body.clientHeight;
d.innerWidth = document.body.clientWidth;
}
(e.pageX) ? x = e.pageX : x = e.clientX + d.scrollLeft;
(e.pageY) ? y = e.pageY : x = e.clientY + d.scrollTop;

// Show the menu
$(document).unbind('click');
$(menu).css({ top: y, left: x }).fadeIn(o.inSpeed);

// When items are selected
$('#' + o.menu).find('A').unbind('click');
$('#' + o.menu).find('LI A').click( function() {
$(document).unbind('click').unbind('keypress');
$(".rcMenu").hide();
// Callback
if( callback ) callback( $(this).attr('href').substr(1), $(srcElement), {x: x - offset.left, y: y - offset.top, docX: x, docY: y} );
return false;
});

// Hide bindings
setTimeout( function() { // Delay for Mozilla
$(document).click( function() {
$(document).unbind('click').unbind('keypress');
$(menu).fadeOut(o.outSpeed);
return false;
});
}, 0);
}
});
});

// Disable text selection
if( $.browser.mozilla ) {
$('#' + o.menu).each( function() { $(this).css({ 'MozUserSelect' : 'none' }); });
} else if( $.browser.msie ) {
$('#' + o.menu).each( function() { $(this).bind('selectstart.disableTextSelect', function() { return false; }); });
} else {
$('#' + o.menu).each(function() { $(this).bind('mousedown.disableTextSelect', function() { return false; }); });
}
// Disable browser context menu (requires both selectors to work in IE/Safari + FF/Chrome)
$(el).add('UL.rcMenu').bind('contextmenu', function() { return false; });

});
return $(this);
},

// Disable context menu items on the fly
disablercMenuItems: function(o) {
if( o == undefined ) {
// Disable all
$(this).find('LI').addClass('disabled');
return( $(this) );
}
$(this).each( function() {
if( o != undefined ) {
var d = o.split(',');
for( var i = 0; i < d.length; i++ ) {
$(this).find('A[href="' + d[i] + '"]').parent().addClass('disabled');

}
}
});
return( $(this) );
},

// Enable context menu items on the fly
enablercMenuItems: function(o) {
if( o == undefined ) {
// Enable all
$(this).find('LI.disabled').removeClass('disabled');
return( $(this) );
}
$(this).each( function() {
if( o != undefined ) {
var d = o.split(',');
for( var i = 0; i < d.length; i++ ) {
$(this).find('A[href="' + d[i] + '"]').parent().removeClass('disabled');

}
}
});
return( $(this) );
},

// Disable context menu(s)
disablercMenu: function() {
$(this).each( function() {
$(this).addClass('disabled');
});
return( $(this) );
},

// Enable context menu(s)
enablercMenu: function() {
$(this).each( function() {
$(this).removeClass('disabled');
});
return( $(this) );
},

// Destroy context menu(s)
destroyrcMenu: function() {
// Destroy specified context menus
$(this).each( function() {
// Disable action
$(this).unbind('mousedown').unbind('mouseup');
});
return( $(this) );
}

});
})(jQuery);

rcMenu on Jan 20th, 2009

this source above works with SubMenus with latest jquery - 1.3


"contextMenu" is replaced with "rcMenu"
becouse hase some modifications

rcMenu on Jan 20th, 2009

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">;

<html xmlns="http://www.w3.org/1999/xhtml">;

<head>
<title>jQuery Context Menu Plugin Demo</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

<style type="text/css">
BODY,
HTML {
padding: 0px;
margin: 0px;
}
BODY {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
background: #FFF;
padding: 15px;
}

H1 {
font-family: Georgia, serif;
font-size: 20px;
font-weight: normal;
}

H2 {
font-family: Georgia, serif;
font-size: 16px;
font-weight: normal;
margin: 0px 0px 10px 0px;
}

#myDiv {
width: 150px;
border: solid 1px #2AA7DE;
background: #6CC8EF;
padding: 1em .5em;
margin: 1em;
float: left;
}

#myList {
margin: 1em;
float: left;
}

#myList UL {
padding: 0px;
margin: 0em 1em;
}

#myList LI {
width: 100px;
border: solid 1px #CCC;
background: #EEE;
padding: 2px 5px;
margin: 10px 0px;
list-style: none;
}

#options {
clear: left;
}

#options INPUT {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
width: 150px;
}

</style>


<script src="http://code.jquery.com/jquery-latest.js"></script>;
<script src="jquery.rcMenu.js" type="text/javascript"></script>
<link href="jquery.rcMenu.css" rel="stylesheet" type="text/css"/>

<script type="text/javascript">

$(document).ready( function () {

// Show menu when #myDiv is clicked
$("#myDiv").rcMenu
( { menu: 'myMenu'},
function(action, el, pos) {
alert(
'Action: ' + action + '\n\n' +
'Element ID: ' + $(el).attr('id') + '\n\n' +
'Element Tag Name: ' + $(el).get(0).tagName + '\n\n' +
'X: ' + pos.x + ' Y: ' + pos.y + ' (relative to element)\n\n' +
'X: ' + pos.docX + ' Y: ' + pos.docY+ ' (relative to document)'
);
});

// Show menu when a list item is clicked
$("#myList UL LI").rcMenu({
menu: 'myMenu'
}, function(action, el, pos) {
alert(
'Action: ' + action + '\n\n' +
'Element text: ' + $(el).text() + '\n\n' +
'X: ' + pos.x + ' Y: ' + pos.y + ' (relative to element)\n\n' +
'X: ' + pos.docX + ' Y: ' + pos.docY+ ' (relative to document)'
);
});

// Disable menus
$("#disableMenus").click( function() {
$('#myDiv').disablercMenu();
$(this).attr('disabled', true);
$("#enableMenus").attr('disabled', false);
});

// Enable menus
$("#enableMenus").click( function() {
$('#myDiv, #myList UL LI').enablercMenu();
$(this).attr('disabled', true);
$("#disableMenus").attr('disabled', false);
});

// Disable cut/copy
$("#disableItems").click( function() {
$('#myMenu').disablercMenuItems('#cut,#copy');
$(this).attr('disabled', true);
$("#enableItems").attr('disabled', false);

});

// Enable cut/copy
$("#enableItems").click( function() {
$('#myMenu').enablercMenuItems('#cut,#copy');
$(this).attr('disabled', true);
$("#disableItems").attr('disabled', false);
});

});

</script>
</head>

<body>

<h1>jQuery Context Menu Plugin Demo</h1>
<p>
This plugin lets you add context menu functionality to your web applications.
</p>

<p>
<strong>Tip:</strong> Try using your keyboard to make a selection.
</p>

<p>
<a href="/notebook.php?article=69">Back to the project page</a>
</p>

<h2>Demo</h2>

<div id="myDiv">
Right click for the standard context menu
</div>

<div id="myList">
<ul>
<li class="hover">Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
<li>Item 5</li>
<li>Item 6</li>
</ul>
</div>


<div id="options">
<p>
<input type="button" id="disableItems" value="Disable Cut/Copy" />
<input type="button" id="enableItems" value="Enable Cut/Copy" disabled="disabled" />
</p>

<p>
<input type="button" id="disableMenus" value="Disable Context Menus" />
<input type="button" id="enableMenus" value="Enable Context Menus" disabled="disabled" />
</p>
</div>

<ul id="myMenu" class="rcMenu">
<li class="edit"><a href="#edit">Edit</a></li>
<li id="cut" class="cut separator"><a href="#cut">Cut</a></li>
<li class="copy"><a href="#copy">Copy</a></li>
<li class="paste"><a href="#paste">Paste</a></li>
<li class="delete"><a href="#delete">Delete</a></li>
<li><a href="#fff">ata</a>
<ul>
<li><a href="#Cat">Cat</a></li>
<li><a href="#Rabbit">Rabbit</a></li>
<li><a href="#Dingo">Dingo</a></li>
</ul>
</li>
<li class="quit separator"><a href="#quit">Quit</a></li>
</ul>


<div id="ttrtt">
<ol>
<li class="hover">Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ol>
</div>

</body>
</html>

rcMenu on Jan 20th, 2009

it is not licensed BUT works

rcMenu on Jan 20th, 2009

Very nice looking plug-in. Haven't had the chance to check out the code yet, however there is a change that I think should be made in this version :)

When disabling the various links in the menu they grey out, as they should, however when you click on them the menu closes. It's not a biggie as most people would be smart enough NOT to click them, but I am sure we have all dealt with idiot clients ;)

Jono on Jan 20th, 2009

Your plugin contextMenu is really very nice but I have a problem when the page scroll (using an other jquery plugin). In this case the menu loses the correct position. Could you help me, please?
Daniele

Daniele on Jan 21st, 2009

Very nice. When used in a xhtml file, there was no CSS styling or JS events. I changed all the tags to lowercase (ex: LI - > li ) in your code and it worked.

Sacha on Feb 1st, 2009

Hello all:

I need some help. I want to use the jqueryContextMenu plugin and the jqueryFileTree plugin (http://abeautifulsite.net/notebook.php?article=58), running on the same page. Enabling them separately, both works fine, but if I enable both at same time (in document.ready function) it only works the fileTree. Do you know what could be happening?

Thanks in advance:

Carlos.

Carlos on Feb 5th, 2009

Cory, I am a novice in jQuery, but
1. want to hear if it is right to use $(document).unbind("click") in your plugin? Click even might be binded by other plugin or just someone's JS code and your plug-in just disable those bindings. Please comment...
2. the code on line 73
// Hover events
$(menu).find('A').mouseover( function() {
$(menu).find('li.hover').removeClass('hover');
$(this).parent().addClass('hover1');
}).mouseout( function() {
$(menu).find('li.hover').removeClass('hover');
});
I had to switch to this one:
// Hover events
$(menu).find("A").hover(
function(){ $(this).parent().addClass("hover"); },
function(){ $(this).parent().removeClass("hover"); }
);
cuz .mouseout does not work in Google Chrome v1.0.154.48; jQuery 1.3.1

Sergey on Feb 15th, 2009

nice plugin!

I have a question/request:

I have a list of items, some can be, say, "copy/pasted", others not. Yet i would like to use one single menu markup.
I would like to know how i can disable/enable options on-the-fly, just before the context menu is to be shown, so that it only shows the actions allowed for that item.

Is that possible?

pixeline on Feb 16th, 2009

hi Cory!
Firefox is reporting an error in line 155:
o.split is not a function
/js/jquery_plugins/jquery.contextMenu/jquery.contextMenu.js
Line 155

i'm using jquery 1.3.1. possible that would be the cause?

pixeline on Feb 16th, 2009

Because I need popup menu for left click, so I did,
======================
contextMenu: function(o,callback) {
// Defaults
if( o.isContextMenu == undefined){o.isContextMenu=true;}
if( o.menu == undefined ) return false;
if( o.inSpeed == undefined ) o.inSpeed = 150;
if( o.outSpeed == undefined ) o.outSpeed = 75;
// 0 needs to be -1 for expected results (no fade)
if( o.inSpeed == 0 ) o.inSpeed = -1;
if( o.outSpeed == 0 ) o.outSpeed = -1;
// Loop each context menu
$(this).each( function() {
var el = $(this);
var offset = $(el).offset();
// Add contextMenu class
$('#' + o.menu).addClass('contextMenu');
// Simulate a true right click
$(this).mousedown( function(e) {
var evt = e;
$(this).mouseup( function(e) {
var srcElement = $(this);
$(this).unbind('mouseup');
var buttonID=1;
if(o.isContextMenu){
buttonID=2;
}else{
buttonID=0;
}
if( evt.button == buttonID ) {
======================

Seungil Han on Feb 25th, 2009

Hey, thanks a lot for this plugin! Is there a way to prevent it from closing after an item has been clicked?

Alex on Feb 28th, 2009

Hi,
I love your script.

but there is only one thing buggin' me and that is it doesn't support multi levels.

could you implement that into your script or tell me how can I do that?

thanks for your awesome script!

Eric on Mar 3rd, 2009

Very nice! Clean appearance and easy to integrate.

Ingo Jobling on Mar 4th, 2009

Awesome, just tested and it does exactly what it should ;-)

I have - as mentioned above - added an additional callback handler for "oncontext" and pass the menu itself in, for e.g. disable items:

contextMenu: function(o, callback, contextCallback) {

// Invoke the Callback when the ContextMenu is about to show,
// and pass in the source element and also the related contextmenu itself.
if (contextCallback) contextCallback($(srcElement), menu);

...an handler for this could be:
function(el, menu) {
var firstTd = el.find('td:first');
var disabled = firstTd.attr('abbr');

if (disabled == 'd') {
menu.disableContextMenuItems('#edit');
} else {
menu.enableContextMenuItems('#edit');
}
}

Peter Bucher on Mar 12th, 2009

Thanks for a fantastic plugin!

For those who may be looking for a way to change the vertical position of the menu, the css code can be changed as follows:

.contextMenu {
position: absolute;
width: 140px;
z-index: 99999;
padding: 0px;
margin: 0px;
display: none;
}

.contextMenu LI {
list-style: none;
padding: 0px;
margin: 0px;
border: solid 1px #CCC;
background: #EEE;

position:relative;
top:-60px;
}

Any way this could be worked into the js as an option, instead?

Thanks again

Ken Wishart on Mar 12th, 2009

First of all: Thank you sooo much. Really an awesome plugin.

@Peter Bucher - thank you for the tip with the callback. That helped me out of trouble.

Björn Ahlers on Mar 14th, 2009

thank for this great library!

if you want to add the menu code dynamically via javascript, you might have a problem with Internet Explorer, as the href gets automatically expanded.

if you use jquery >1.3 you can use eg the following code in the function around line 116 to make it work anyway:

var href_array, action;
$(document).unbind('click').unbind('keypress');
$(".contextMenu").hide();
// get the action (support ie, that normalizes the hrefs
if (!$.support.hrefNormalized) {
href_array = $(this).attr('href').split('#');
action = href_array[1];
} else {
action = $(this).attr('href').substr(1);
}
// Callback
if( callback ) callback( action, $(srcElement), {x: x - offset.left, y: y - offset.top, docX: x, docY: y} );
return false;

hope this helps anybody

Tim on Mar 16th, 2009

Thanks for the plugin. Unfortunately it does not work on Safari 3.2.1 (OS X 10.5.6). It works on Firefox 3 on OS X, Windows, and on IE 6, and IE 7.

Is there a fix for this out there anyone knows of?

Bill Snapper on Mar 20th, 2009

Hey there,

First of all thanks heaps; great little plugin.

I had this working and made some recent changes lately. I'm now adding several context menus (several UL objects) at the same time as I add other divs. For some reason, I can't get these to pop. The link between the clicked div and the UL seems to be made because the "display:" style changes from "display:none" to "display:block" when I right click on the given div. Any suggestions? Testing on FF3.

Ta!

Paul

Paul Georges on Mar 24th, 2009

Hi, I have the same problem like odt

I need to find witch item is clicked

I tried the return false to restrict the bubble but nothing

<ul id="items">
<li id="item1"><a href="#">Item 1</a>
<ul>
<li id="item1-1"><a href="#">Item 1.1</a></li>
</ul>
</li>
</ul>

Ricardo on Mar 26th, 2009

how I can run a diferent action
ex:
<a href="#xajax_SearchContent">Item 1</a>

does not work:
$(document).ready( function() {
// Show menu when #myDiv is clicked
$('#content_pallets tr').contextMenu({
menu: 'myMenu'
},
function(action, el, pos) {
action( el.attr('nid'), el.attr('nline') );
}
);

});

Alexi Torres on Apr 2nd, 2009

Hi! Thanks for elegant solution! One dumb question though: how do I make links work? I mean i want the link below to simply launch page.html

<ul id="cm1" class="contextMenu">
<li><a href="page.html">View Dashboard</a></li>
</ul>

Ivan on Apr 3rd, 2009

Hi! Thanks for the plugin it holds exactly what i need but i have serious problems with you including this line: $(document).unbind("click")

Your plugin just unbind all my click events on my page. That is just not right. Could you please post a solution to this. I am a novice in jqeury.

Paul van Steenoven on Apr 7th, 2009

It would be good to have 'return false;' added on line 129 (at the end of the 'if( evt.button == 2 )' section), so that the right-click event doesn't bubble down through the DOM.

Then you can have special context menus show up for clicks on elements that are nested within elements that already have context menus defined.

alf on Apr 8th, 2009

I like the plugin, but dislike the way it unbinds all click events. I was running this with another jQuery plugin (jsTree) and this totally b0rked it.

I've managed to fix the problem (for my circumstances) by changing the plugin a bit - details can be found here: http://www.timgittos.com/jquery-context-menu-unbind-click-fix

Tim on Apr 9th, 2009

@alf

Thanks, thanks, thanks.

I had the same problem.

vinacha on Apr 16th, 2009

Hey! i add RTL support!, you just have to add `dir="rtl"` to the menu ul(<ul id="myMenu" class="contextMenu" dir="ltr">).
Yours,
Almog Baku, Israel.

-- Found: --
$(menu).css({ top: y, left: x }).fadeIn(o.inSpeed);

-- Replace with: --
//RTL SUPPORT BY Almog Baku
if($(menu).attr('dir')=='rtl')
$(menu).css({ top: y, left: x-$(menu).width() }).fadeIn(o.inSpeed);
else
$(menu).css({ top: y, left: x }).fadeIn(o.inSpeed);

Almog Baku on Apr 18th, 2009

Just the answer for Ivan's question...

You need to change 'return false' to 'return true' in this piece of code:

if (callback) callback($(this).attr('href').substr(1), $(srcElement), { x: x - offset.left, y: y - offset.top, docX: x, docY: y });
return false;

... or probably adding 'return true;' in the end of your callback function would do the trick as well.

Cris on Apr 23rd, 2009

Hi there,

First of all great plugin!!

But I have a question. How can I make this work if I have serveral:
<a href="#" class="rightclick_menu">Link 1</a>
<a href="#" class="rightclick_menu">Link 2</a>

So not id's, but classes.

Tnx in advance

Wim

Wim on Apr 26th, 2009

Hi Cory!

Menu works fine. :)
One small issue. If item that has to display context menu is at the bottom of the page the page increase his size instead o showing the menu upper.

Maze on Apr 28th, 2009

Hi there, i get a message $(el).offset is not a function, is it because am using jquery with prototype and changed the jquery variable to $j?

Veeru on Apr 29th, 2009

Hi,
Is there a tip to run this great and useful jquery script with jquery 1.3.x ?

Fred on May 3rd, 2009

Hi, I am having the same issue as others are having about detecting which item is clicked. How do I prevent bubble the event from children to prevent when I have following block:

<li>Item1
<ul>
<li>Item 1.1
<ul>
<li>Item 1.1.1</li>
<li>Item 1.1.2</li>
</ul>
</li>
<li>Item 1.2
</li>
<li>Item 1.3
</li>
</ul>
</li>

Hitesh on May 3rd, 2009

Hi there,


Second time I say it, see my previous post, but again GREAT PLUGIN!!!
My previous question can be deleted, I didn't look good ;-).

I altered the plugin a bit because I want to use 1 menu and not several and secondly I don't want to disable but hide menuitems.
Because a few people asked how to do it in posts above, I post my code below. Please keep in mind that I am a newby to JQUERY, so if you have feedback for me to make it better, please let me know at
wim.sellesATfouroaks.nl

This need to be in the HTML-file:
<script>
$(document).ready( function() {
$("#selector").contextMenu({
menu : 'myMenu',
preHideItems : true,
ids : '#cut,#edit' // do NOT seperate them with space like this '#cut, #edit'
},
function(action, el, pos) {
alert(
''Action: '' + action + ''\n\n'' +
''Element ID: '' + $(el).attr(''id'') + ''\n\n'' +
''X: '' + pos.x + '' Y: '' + pos.y + '' (relative to element)\n\n'' +
''X: '' + pos.docX + '' Y: '' + pos.docY+ '' (relative to document)''
);
});

});
</script>

The menu:
<ul id="myMenu" class="contextMenu">
<li id="edit">
<a href="#" rel="#edit">Edit</a>
</li>
<li id="cut separator">
<a href="#" rel="#cut">Cut</a>
</li>
<li id="copy">
<a href="#" rel="#copy">Copy</a>
</li>
<li id="paste">
<a href="#" rel="#paste">Paste</a>
</li>
<li id="delete">
<a href="#" rel="#delete">Delete</a>
</li>
<li id="quit separator">
<a href="#" rel="#quit">Quit</a>
</li>
</ul>

The JS-file:
// jQuery Context Menu Plugin
//
// Version 1.00
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
//
// Visit http://abeautifulsite.net/notebook/80 for usage and more information
//
// Terms of Use
//
// This software is licensed under a Creative Commons License and is copyrighted
// (C)2008 by Cory S.N. LaViska.
//
// For details, visit http://creativecommons.org/licenses/by/3.0/us/
//
// Modified 11NOV08 By Bill Beckelman to include option to use left mouse button instead.
//
// Modified 06MAY09 By Wim Selles to predefine which menuoptions should be shown or not

if (jQuery) (function() {
$.extend($.fn, {

contextMenu: function(o, callback) {
// Defaults
if (o.menu == undefined) return false;
if (o.inSpeed == undefined) o.inSpeed = 150;
if (o.outSpeed == undefined) o.outSpeed = 75;
if (o.leftButton == undefined) o.leftButton = false;
if (o.preHideItems == undefined) o.preHideItems = false; // NEW 06MAY09 BY WIM SELLES
// 0 needs to be -1 for expected results (no fade)
if (o.inSpeed == 0) o.inSpeed = -1;
if (o.outSpeed == 0) o.outSpeed = -1;
// Loop each context menu
$(this).each(function() {
var el = $(this);
var offset = $(el).offset();
// Add contextMenu class
$('#' + o.menu).addClass('contextMenu');
// Simulate a true right click
$(this).mousedown(function(e) {
var evt = e;
$(this).mouseup(function(e) {
var srcElement = $(this);
$(this).unbind('mouseup');
if (evt.button == 2 || o.leftButton == true) {
// Hide context menus that may be showing
$(".contextMenu").hide();
// Get this context menu
var menu = $('#' + o.menu);

if ($(el).hasClass('disabled')) return false;

// Detect mouse position
var d = {}, x, y;
if (self.innerHeight) {
d.pageYOffset = self.pageYOffset;
d.pageXOffset = self.pageXOffset;
d.innerHeight = self.innerHeight;
d.innerWidth = self.innerWidth;
} else if (document.documentElement &&
document.documentElement.clientHeight) {
d.pageYOffset = document.documentElement.scrollTop;
d.pageXOffset = document.documentElement.scrollLeft;
d.innerHeight = document.documentElement.clientHeight;
d.innerWidth = document.documentElement.clientWidth;
} else if (document.body) {
d.pageYOffset = document.body.scrollTop;
d.pageXOffset = document.body.scrollLeft;
d.innerHeight = document.body.clientHeight;
d.innerWidth = document.body.clientWidth;
}
(e.pageX) ? x = e.pageX : x = e.clientX + d.scrollLeft;
(e.pageY) ? y = e.pageY : x = e.clientY + d.scrollTop;

/*********************************
* NEW 06MAY09 BY WIM SELLES
*/
// Before hidding option(s), find out if there are allready hidden option(s) and show them
$(".contextMenu").children('li').show();
// Before menu is shown, check if preHideItems is true..
if (o.preHideItems = true){
// .. then get the ids and split them..
var ids = o.ids;
var d = ids.split(',');
// .. then count the ammount of ids and find all the "LI" ids and hide them
for (var i = 0; i < d.length; i++) {
$().find('LI' + d[i] + '').hide();
}
}
/*********************************
* END OF NEW 06MAY09 BY WIM SELLES
*/

// Show the menu
$(document).unbind('click');
$(menu).css({ top: y, left: x }).fadeIn(o.inSpeed);
// Hover events
$(menu).find('A').mouseover(function() {
$(menu).find('LI.hover').removeClass('hover');
$(this).parent().addClass('hover');
}).mouseout(function() {
$(menu).find('LI.hover').removeClass('hover');
});

// Keyboard
$(document).keypress(function(e) {
switch (e.keyCode) {
case 38: // up
if ($(menu).find('LI.hover').size() == 0) {
$(menu).find('LI:last').addClass('hover');
} else {
$(menu).find('LI.hover').removeClass('hover').prevAll('LI:not(.disabled)').eq(0).addClass('hover');
if ($(menu).find('LI.hover').size() == 0) $(menu).find('LI:last').addClass('hover');
}
break;
case 40: // down
if ($(menu).find('LI.hover').size() == 0) {
$(menu).find('LI:first').addClass('hover');
} else {
$(menu).find('LI.hover').removeClass('hover').nextAll('LI:not(.disabled)').eq(0).addClass('hover');
if ($(menu).find('LI.hover').size() == 0) $(menu).find('LI:first').addClass('hover');
}
break;
case 13: // enter
$(menu).find('LI.hover A').trigger('click');
break;
case 27: // esc
$(document).trigger('click');
break
}
});

// When items are selected
$('#' + o.menu).find('A').unbind('click');
$('#' + o.menu).find('LI:not(.disabled) A').click(function() {
$(document).unbind('click').unbind('keypress');
$(".contextMenu").hide();

/*********************************
* NEW 06MAY09 BY WIM SELLES
*/
// After the menu is shown, check if preHideItems is true..
if (o.preHideItems = true){
// .. then get the ids and split them..
var ids = o.ids;
var d = ids.split(',');
// .. then count the ammount of ids and find all the "LI" ids and show them
for (var i = 0; i < d.length; i++) {
$().find('LI' + d[i] + '').show();
}
}
/*********************************
* END OF NEW 06MAY09 BY WIM SELLES
*/

// Callback
/*if (callback) callback($(this).attr('href').substr(1), $(srcElement), { x: x - offset.left, y: y - offset.top, docX: x, docY: y });
return false;*/

/*********************************
* NEW 06MAY09 BY WIM SELLES
*/
// Altered the callback for my own usage
if (callback) callback($(this).attr('rel').substr(1), $(srcElement), { x: x - offset.left, y: y - offset.top, docX: x, docY: y });
if($(this).attr('href') =='#'){
return false;
}else{
return true;
}
/*********************************
* END OF NEW 06MAY09 BY WIM SELLES
*/

});

// Hide bindings
setTimeout(function() { // Delay for Mozilla
$(document).click(function() {
$(document).unbind('click').unbind('keypress');
$(menu).fadeOut(o.outSpeed);
return false;
});
}, 0);
}
});
});

// Disable text selection
if ($.browser.mozilla) {
$('#' + o.menu).each(function() { $(this).css({ 'MozUserSelect': 'none' }); });
} else if ($.browser.msie) {
$('#' + o.menu).each(function() { $(this).bind('selectstart.disableTextSelect', function() { return false; }); });
} else {
$('#' + o.menu).each(function() { $(this).bind('mousedown.disableTextSelect', function() { return false; }); });
}
// Disable browser context menu (requires both selectors to work in IE/Safari + FF/Chrome)
$(el).add('UL.contextMenu').bind('contextmenu', function() { return false; });

});
return $(this);
},

// Disable context menu items on the fly
disableContextMenuItems: function(o) {
if (o == undefined) {
// Disable all
$(this).find('LI').addClass('disabled');
return ($(this));
}
$(this).each(function() {
if (o != undefined) {
var d = o.split(',');
for (var i = 0; i < d.length; i++) {
$(this).find('A[href="' + d[i] + '"]').parent().addClass('disabled');

}
}
});
return ($(this));
},

// Enable context menu items on the fly
enableContextMenuItems: function(o) {
if (o == undefined) {
// Enable all
$(this).find('LI.disabled').removeClass('disabled');
return ($(this));
}
$(this).each(function() {
if (o != undefined) {
var d = o.split(',');
for (var i = 0; i < d.length; i++) {
$(this).find('A[href="' + d[i] + '"]').parent().removeClass('disabled');

}
}
});
return ($(this));
},

// Disable context menu(s)
disableContextMenu: function() {
$(this).each(function() {
$(this).addClass('disabled');
});
return ($(this));
},

// Enable context menu(s)
enableContextMenu: function() {
$(this).each(function() {
$(this).removeClass('disabled');
});
return ($(this));
},

// Destroy context menu(s)
destroyContextMenu: function() {
// Destroy specified context menus
$(this).each(function() {
// Disable action
$(this).unbind('mousedown').unbind('mouseup');
});
return ($(this));
}

});
})(jQuery);

Wim Selles on May 6th, 2009

just found out the right click for context menu may not work on some macbook trackpads. to fix this: Go into System Preferences and
select [x] For secondary clicks, place two fingers on the trackpad then click the button

cheers,

sze

sze on May 7th, 2009

Excillent Job bro... very nice

Faheem on May 10th, 2009

Hi Cory,
Is there a way to make the text, width, height for the context menu options, a fixed width and height length? If the text size is increased, the context menu text goes out of bounds

sze on May 11th, 2009

hey cory, found a fix for the context menu width issue.
replaced width:120px; with width: auto;

sze on May 12th, 2009

I"m having problems making this work - it looks very cool tho. I'm echoing data from mysql in php, and want to have a link with context menu. Here is how I'm calling my context menu:
echo("<a href=\"#myMenu\">$variable</a>");

I've got the same document ready code you have above, but when I click on my link, all I see is the regular windows context menu. The js is loaded (I see this in Firebug) but I must be setting my link up incorrectly - can anyone help? Tx

Kathy on May 19th, 2009

I should add I'm using jquery-1.2.6.min, with tablesorter, trying to get one table cell to contain a link that I'll click to bring up more data...

Kathy on May 19th, 2009

Hi, anybody can modify this code:
$(function() { $('#<%= textdiv.ClientID %>').contextMenu('#myMenu1');

To:
$(function() { $('#<%= textdiv.ClientID %>').contextMenu('#myMenu1','#myMenu2');

It means, merge two <ul id=myMenu1> and <ul id=myMenu2> to one Menu.

Thanks,

LinhVN on May 21st, 2009

I needed to change line 115 to use a reg exp to get the action to be the same in both ie and fire fox:

if( callback ) callback( $(this).attr('href').replace(/^.*#/, ''), $(srcElement), {x: x - offset.left, y: y - offset.top, docX: x, docY: y} );


expression: .substr(1) changed to .replace(/^.*#/, '')

Okku

Okku Touronen on May 25th, 2009

Hi,

Does this context menu script support nested item list? Is this also compatible withjquery 1.3.2?

Good job! Thanks!

Clement on Jun 4th, 2009

@Clement: There is currently no support for sub-menus. It is compatible with 1.3.2.

Cory S.N. LaViska on Jun 4th, 2009

Thanks Cory!

Clement on Jun 4th, 2009

This is great. It was easy to setup and use, the styling and functionality

Sajid Latif on Jun 5th, 2009

Is there a way to make this context menu work with "live" event binding way instead simply bind / unbind?
I want to add to a grid new rows and they should also have a context menu.
Thanks!

Ral on Jun 10th, 2009

Seems have a problem binding to an element inside an iframe. If the iframe is not height enough, some options get chopped off. On the other hand, the menu is hidden initially, automatically resize iframe does not count it in. Thanks in advance.

Tony on Jun 17th, 2009

It rocks Cory.

There is a solution to make it working with other libraries (Prototype) that can be helpful to people who needs both libraries because is working on a complex dashboard or a desktop, like me. There is:

var $j = jQuery.noConflict();

Add this line at the top of jquery.contextMenu.js file and then rename all matches for the dollar function ($) to $j (in this case). So at your script too.

I made a little change to display mode of the menu because I have no scroll-bars on the document so this change lets the menu appears in the screen in case is called at right-bottom corner. It is:

Replace the line (with noConflict): $j(menu).css({ top: y, left: x }).fadeIn(o.inSpeed);
To: var xmenu = parseInt($j(menu).css("width"));
var ymenu = parseInt($j(menu).css("height"));
if(x+xmenu > d.innerWidth) x = x-xmenu;
if(y+ymenu > d.innerHeight) y = y-ymenu;
$j(menu).css("top",y);
$j(menu).css("left",x);


Waiting for a new version. Sub-menu's option looks cool. :)

litzerATmsnDOTcom

Litzer on Jun 20th, 2009

Adding return false in mouseup did not stop event bubbling. Have a link inside a <td> and tried to bind them to different menu.
Only the menu for <td> is shown. Any suggestions? Thanks.

Tony on Jun 22nd, 2009

Like others I needed to make an adjustment to the menu position, because the <ul> list element was not in the root of the HTML document. Two lines could be added after the //show menu to get the menu to position correctly:

// Double check position
menuOffset = $(menu).offset();
if(menuOffset.left != x || menuOffset.top != y) {
$(menu).css({ top: y - Math.round(menuOffset.top - y), left: x - Math.round(menuOffset.left - x)});
}


Kind regards

Arnoud

Arnoud ten Hoedt on Jun 26th, 2009

Add a comment

Name*

Email*

Never, ever sold or spammed :)

Homepage

Comment*

Sorry, plain text only :(