Feature-rich Custom jQuery Context Menu Plugin - contextMenu

Feature-rich Custom jQuery Context Menu Plugin - contextMenu
File Size: 2.42 MB
Views Total:
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
   

contextMenu is a feature-rich and high performance jQuery plugin for replacing the default browser's right-click menu with a custom one.

Features:

  • Allows to append the context menu to any element.
  • Multilevel context menus.
  • Keyboard interaction.
  • Custom trigger events, not only right click.
  • Auto adjusts position and size to fit in viewport.
  • Dynamic menu creation.
  • Custom animations.

Basic usage:

1. Include the jQuery contextMenu's CSS file in the head section of the html document.

<link href="jquery.contextMenu.css" rel="stylesheet">

2. Create an element where you want to append the context menu to.

<span class="demo">Right Click Me</span>

3. Include jQuery library, jQuery UI Position and the jQuery contextMenu plugin's JavaScript at the bottom of the html document.

<script src="//code.jquery.com/jquery-1.12.1.min.js"></script>
<script src="dist/jquery.ui.position.js"></script>
<script src="dist/jquery.contextMenu.js"></script>

4. Create your custom menu items and bind the context menu to the element 'demo'.

$.contextMenu({
  selector: '.demo', 
  items: {
      "edit": {name: "Edit", icon: "edit"},
      "cut": {name: "Cut", icon: "cut"},
      "copy": {name: "Copy", icon: "copy"},
      "paste": {name: "Paste", icon: "paste"},
      "delete": {name: "Delete", icon: "delete"},
      ...
  }
});

5. Here's a full list of configuration options you can use to customize the context menu.

// selector of contextMenu trigger
selector: null,

// where to append the menu to
appendTo: null,

// method to trigger context menu ["right", "left", "hover"]
trigger: 'right',

// hide menu when mouse leaves trigger / menu elements
autoHide: false,

// ms to wait before showing a hover-triggered context menu
delay: 200,

// flag denoting if a second trigger should simply move (true) or rebuild (false) an open menu
// as long as the trigger happened on one of the trigger-element's child nodes
reposition: true,

// Default classname configuration to be able avoid conflicts in frameworks
classNames : {

  hover: 'context-menu-hover', // Item hover
  disabled: 'context-menu-disabled', // Item disabled
  visible: 'context-menu-visible', // Item visible
  notSelectable: 'context-menu-not-selectable', // Item not selectable

  icon: 'context-menu-icon',
  iconEdit: 'context-menu-icon-edit',
  iconCut: 'context-menu-icon-cut',
  iconCopy: 'context-menu-icon-copy',
  iconPaste: 'context-menu-icon-paste',
  iconDelete: 'context-menu-icon-delete',
  iconAdd: 'context-menu-icon-add',
  iconQuit: 'context-menu-icon-quit'
},

// determine position to show menu at
determinePosition: function ($menu) {
  // position to the lower middle of the trigger element
  if ($.ui && $.ui.position) {
      // .position() is provided as a jQuery UI utility
      // (...and it won't work on hidden elements)
      $menu.css('display', 'block').position({
          my: 'center top',
          at: 'center bottom',
          of: this,
          offset: '0 5',
          collision: 'fit'
      }).css('display', 'none');
  } else {
      // determine contextMenu position
      var offset = this.offset();
      offset.top += this.outerHeight();
      offset.left += this.outerWidth() / 2 - $menu.outerWidth() / 2;
      $menu.css(offset);
  }
},

// position menu
position: function (opt, x, y) {
  var offset;
  // determine contextMenu position
  if (!x && !y) {
      opt.determinePosition.call(this, opt.$menu);
      return;
  } else if (x === 'maintain' && y === 'maintain') {
// selector of contextMenu trigger
selector: null,
// where to append the menu to
appendTo: null,
// method to trigger context menu ["right", "left", "hover"]
trigger: 'right',
// hide menu when mouse leaves trigger / menu elements
autoHide: false,
// ms to wait before showing a hover-triggered context menu
delay: 200,
// flag denoting if a second trigger should simply move (true) or rebuild (false) an open menu
// as long as the trigger happened on one of the trigger-element's child nodes
reposition: true,

// Default classname configuration to be able avoid conflicts in frameworks
classNames : {

    hover: 'context-menu-hover', // Item hover
    disabled: 'context-menu-disabled', // Item disabled
    visible: 'context-menu-visible', // Item visible
    notSelectable: 'context-menu-not-selectable', // Item not selectable

    icon: 'context-menu-icon',
    iconEdit: 'context-menu-icon-edit',
    iconCut: 'context-menu-icon-cut',
    iconCopy: 'context-menu-icon-copy',
    iconPaste: 'context-menu-icon-paste',
    iconDelete: 'context-menu-icon-delete',
    iconAdd: 'context-menu-icon-add',
    iconQuit: 'context-menu-icon-quit'
},

// determine position to show menu at
determinePosition: function ($menu) {
    // position to the lower middle of the trigger element
    if ($.ui && $.ui.position) {
        // .position() is provided as a jQuery UI utility
        // (...and it won't work on hidden elements)
        $menu.css('display', 'block').position({
            my: 'center top',
            at: 'center bottom',
            of: this,
            offset: '0 5',
            collision: 'fit'
        }).css('display', 'none');
    } else {
        // determine contextMenu position
        var offset = this.offset();
        offset.top += this.outerHeight();
        offset.left += this.outerWidth() / 2 - $menu.outerWidth() / 2;
        $menu.css(offset);
    }
},
// position menu
position: function (opt, x, y) {
    var offset;
    // determine contextMenu position
    if (!x && !y) {
        opt.determinePosition.call(this, opt.$menu);
        return;
    } else if (x === 'maintain' && y === 'maintain') {
        // x and y must not be changed (after re-show on command click)
        offset = opt.$menu.position();
    } else {
        // x and y are given (by mouse event)
        offset = {top: y, left: x};
    }

    // correct offset if viewport demands it
    var bottom = $win.scrollTop() + $win.height(),
        right = $win.scrollLeft() + $win.width(),
        height = opt.$menu.outerHeight(),
        width = opt.$menu.outerWidth();

    if (offset.top + height > bottom) {
        offset.top -= height;
    }

    if (offset.top < 0) {
        offset.top = 0;
    }

    if (offset.left + width > right) {
        offset.left -= width;
    }

    if (offset.left < 0) {
        offset.left = 0;
    }

    opt.$menu.css(offset);
},
// position the sub-menu
positionSubmenu: function ($menu) {
    if ($.ui && $.ui.position) {
        // .position() is provided as a jQuery UI utility
        // (...and it won't work on hidden elements)
        $menu.css('display', 'block').position({
            my: 'left top',
            at: 'right top',
            of: this,
            collision: 'flipfit fit'
        }).css('display', '');
    } else {
        // determine contextMenu position
        var offset = {
            top: 0,
            left: this.outerWidth()
        };
        $menu.css(offset);
    }
},
// offset to add to zIndex
zIndex: 1,
// show hide animation settings
animation: {
    duration: 50,
    show: 'slideDown',
    hide: 'slideUp'
},
// events
events: {
    show: $.noop,
    hide: $.noop
},
// default callback
callback: null,
// list of contextMenu items
items: {}

6. API events.

  • contextmenu: Trigger context menu to be shown for a trigger object.
  • prevcommand: Select / highlight the previous possible command
  • nextcommand: Select / highlight the next possible command
  • contextmenu:hide: Hide the menu
  • contextmenu:focus: React to a command item being focused
  • contextmenu:blur: Available on each context menu item.
  • keydown: Available on each context menu item.

Change log:

v2.6.0 (2017-09-09)

  • Fixed Dev dependency ended up in normal dependencies.

v2.5.0 (2017-07-16)

  • Callback function now supplies original event
  • Ability to define touchstart as trigger

v2.4.5 (2017-05-06)

  • ContextMenu appears with wrong position 
  • Check if given selected value is a 0, if it is a zero so return it as is
  • Events are never trigger when opening a contextMenu right after the other 
  • Accesskey jQuery Modal Dialog not working
  • Fix submenu hover not always staying active if hovering over a submenu item

v2.4.4 (2017-03-15)

  • Fixed: trigger is sometimes called on undefined objects because of typecheck on null. 

v2.4.3 (2017-02-28)

  • Changed the inline style causes a Content Security Policy violation if style-src 'unsafe-inline' is not defined in the policy. 
  • Added SauceLabs tests for common browsers.

v2.4.2 (2017-01-02)

  • Fixed: Focus not set on content editable element when right clicking the second time
  • Fixed: selectableSubMenu broke disabling click menu

v2.4.1 (2016-12-10)

  • Quick fix for error in visible check
  • Added Selectable Sub Menus
  • Fixed The contextmenu shows even if all items are set to visible:false

2016-10-26

  • v2.3.1

2016-06-18

  • Small fix for hover color of input item.

2016-05-25

  • added more options

This awesome jQuery plugin is developed by swisnl. For more Advanced Usages, please check the demo page or visit the official website.