I was thrilled to find Cory LaViska’s jQuery Context Menu Plugin a few months ago. In very little time, I was able to integrate the context menu with the jQuery Treeview. I quickly had a really pretty user interface which took full advantage of limited real estate. And guess what. As promised, the plugin worked in Chrome, Safari 3, IE 6/7/8, Firefox 2/3 and Opera 9.5. Everything was perfect and I shipped to the Integration Environment.
One thing kept bugging though – right clicks aren’t the standard in a web environment. Sure, when one hovers over the treeview node, the mouse changed from an arrow to a pointer, but without help text most users will certainly left-click rather than right.
As I was already doubting the design decision, we did some Mac testing. The context menu worked in Firefox but not Safari. Damn. That’s when I started digging into the Madness of Javascript Mouse Events. Don’t tell, but it’s complicated. About as close as one can get to capture the right-click mouse event on all major browsers on Windows and Mac is this:
if (event.which == null)
/* IE case */
button= (event.button < 2) ? "LEFT" :
((event.button == 4) ? "MIDDLE" : "RIGHT");
else
/* All others */
button= (event.which < 2) ? "LEFT" :
((event.which == 2) ? "MIDDLE" : "RIGHT");
Yikes. The content menu code was simply checking if event.button == 2. No problem. Cory offers a jQuery Right Click Plugin which I’m sure works for windows but probably not the Mac either. (Please note I haven’t verified this.)
Anyway, I decided to address my UI design concern and the Safari Mac issue in one swoop. I decided to make the context menu respond to any mouse click event. This didn’t take much – especially after seeing how Bill Beckelman updated the library to recognize the left click.
First, I added an AnyClick option to the library defaults:
// Any click may trigger the dropdown and that's okay
// See Javascript Madness: Mouse Events – http: //unixpapa.com/js/mouse.html
if (o.anyClick == undefined) o.anyClick = false;
And then I trigger the context menu dropdown based on the following conditional:
if (evt.button == 2 || o.anyClick) {
Nothing tricky about that, right? Finally, I updated my menu setup to include the AnyClick value, if true:
$('.member').contextMenu({ menu: 'memberContextMenu', anyClick: true },
function (action, el, pos) {
…
Now the context menu works in “all” environments if you left, right or even middle click.
Download jQuery Context Menu Plugin for Any Click
*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.