ContextMenu

ContextMenu is a highly customizable, compact context menu script written with CSS, XHTML, and the MooTools JavaScript framework. ContextMenu allows you to offer stylish, functional context menus on your website.

Download Debut Article Example Usage

 

Plugin Code (Version 1.0)

var ContextMenu = new Class({

	//implements
	Implements: [Options,Events],

	//options
	options: {
		actions: {},
		menu: 'contextmenu',
		stopEvent: true,
		targets: 'body',
		trigger: 'contextmenu',
		offsets: { x:0, y:0 },
		onShow: $empty,
		onHide: $empty,
		onClick: $empty,
		fadeSpeed: 200
	},
	
	//initialization
	initialize: function(options) {
		//set options
		this.setOptions(options)
		
		//option diffs menu
		this.menu = $(this.options.menu);
		this.targets = $$(this.options.targets);
		
		//fx
		this.fx = new Fx.Tween(this.menu, { property: 'opacity', duration:this.options.fadeSpeed });
		
		//hide and begin the listener
		this.hide().startListener();
		
		//hide the menu
		this.menu.setStyles({ 'position':'absolute','top':'-900000px', 'display':'block' });
	},
	
	//get things started
	startListener: function() {
		/* all elements */
		this.targets.each(function(el) {
			/* show the menu */
			el.addEvent(this.options.trigger,function(e) {
				//enabled?
				if(!this.options.disabled) {
					//prevent default, if told to
					if(this.options.stopEvent) { e.stop(); }
					//record this as the trigger
					this.options.element = $(el);
					//position the menu
					this.menu.setStyles({
						top: (e.page.y + this.options.offsets.y),
						left: (e.page.x + this.options.offsets.x),
						position: 'absolute',
						'z-index': '2000'
					});
					//show the menu
					this.show();
				}
			}.bind(this));
		},this);
		
		/* menu items */
		this.menu.getElements('a').each(function(item) {
			item.addEvent('click',function(e) {
				if(!item.hasClass('disabled')) {
					this.execute(item.get('href').split('#')[1],$(this.options.element));
					this.fireEvent('click',[item,e]);
				}
			}.bind(this));
		},this);
		
		//hide on body click
		$(document.body).addEvent('click', function() {
			this.hide();
		}.bind(this));
	},
	
	//show menu
	show: function(trigger) {
		//this.menu.fade('in');
		this.fx.start(1);
		this.fireEvent('show');
		this.shown = true;
		return this;
	},
	
	//hide the menu
	hide: function(trigger) {
		if(this.shown)
		{
			this.fx.start(0);
			//this.menu.fade('out');
			this.fireEvent('hide');
			this.shown = false;
		}
		return this;
	},
	
	//disable an item
	disableItem: function(item) {
		this.menu.getElements('a[href$=' + item + ']').addClass('disabled');
		return this;
	},
	
	//enable an item
	enableItem: function(item) {
		this.menu.getElements('a[href$=' + item + ']').removeClass('disabled');
		return this;
	},
	
	//diable the entire menu
	disable: function() {
		this.options.disabled = true;
		return this;
	},
	
	//enable the entire menu
	enable: function() {
		this.options.disabled = false;
		return this;
	},
	
	//execute an action
	execute: function(action,element) {
		if(this.options.actions[action]) {
			this.options.actions[action](element,this);
		}
		return this;
	}
	
});

/* example usage */
window.addEvent('domready', function() {

	//create a context menu
	var context = new ContextMenu({
		targets: 'a', //menu only available on links
		menu: 'contextmenu',
		actions: {
			copy: function(element,ref) { //copy action changes the element's color to green and disables the menu
				element.setStyle('color','#090');
				ref.disable();
			}
		},
		offsets: { x:2, y:2 }
	});
});

XHTML Menu Format

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

Options & Events

  • actions: (defaults to {}) a collection of actions (functions) to be executed when a corresponding menu item is clicked. Each action is given the element targetted and a menu reference.
  • menu: the ID of the element that represents the menu XHTML
  • stopEvent: (defaults to true) do you want the element's default action to be stopped when the menu is triggered to display?
  • targets: (defaults to document.body) element(s) that should show the menu when triggered
  • trigger: (defaults to 'contextmenu') event that triggers the menu to display
  • offsets: (defaults to 0,0) an {x,y} object with corresponding x and y offsets
  • onShow: a function to execute when the menu is shown
  • onHide: a function to execute when the menu is hidden
  • onClick: a function to execute when a menu item is clicked

Methods

disable

context.disable();
  • Disables the menu until the menu is enabled
  • Returns the context menu

enable

context.enable();
  • Enables the menu after it has been disabled
  • Returns the context menu

disableItem

context.disableItem('copy');
  • Disables an individual menu item
  • Accepts the name of the menu item to be disabled
  • Returns the context menu

enableItem

context.enableItem('copy');
  • Enables an individual menu item
  • Accepts the name of the menu item to be enabled
  • Returns the context menu

Code Revisions & Bug Fixes

  • A Safari menu bug was fixed for 1.0.