Extra lightweight plugin (4kB) for dynamically creating complex context menus in bootstrap3
<script src="https://code.jquery.com/jquery-2.2.4.min.js" <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">... and include plugin:
<script src="bootstrap-contextmenu.js"></script> <link rel="stylesheet" type="text/css" href="bootstrap-contextmenu.css">
<div class="list-group menu1"> <div class="list-group-item">Right click on me</div> <div class="list-group-item">Right click on me</div> </div> <script type="text/javascript"> const menu = Object.create(contextMenu) menu.init('.menu1 .list-group-item' , [ { type : 'header', text : 'header in context menu', }, { type : 'item', text : 'hello' }, { type : 'item', text : 'world' }, { type : 'divider' }, { type : 'item', text : 'other item under divider' } ]) </script>
If you wanna display other options conditionally to clicked item (for example based on data-attributes or id), You can use callbacks in options:
<div class="list-group menu2"> <div class="list-group-item" data-id="1">Right click on me</div> <div class="list-group-item" data-id="2">Right click on me</div> </div> <script type="text/javascript"> const menu2 = Object.create(contextMenu) menu2.init('.menu2 .list-group-item' , [ { type : 'item', text : function(e) { let element = $(e.currentTarget) return 'This item has data-id="'+element.data('id')+'"' }, }, { type : 'item', text : function(e) { let element = $(e.currentTarget) if(element.data('id') == 1) { return 'I am active!' } return 'I am not active' }, href : 'http://www.google.pl', attr : { class : function(e) { let element = $(e.currentTarget) if(element.data('id') == 1) { return 'active' } } } }, { type : 'item', text : 'this item should be visible only if target element has data-id = 2', display : function(e) { let element = $(e.currentTarget) if(element.data('id') == 2) { return true } return false } }, { type : 'submenu', text : 'submenu example', items : [ { type : 'item', text : 'submenu item 1', }, { type : 'item', text : function() { return 'random number '+ Math.ceil(Math.random()*1000) } }, { type : 'submenu', text : 'next level submenu', items : [ { type : 'item', text : 'subsubmenu item 1', }, { type : 'item', text : function() { return 'random number '+ Math.ceil(Math.random()*1000) } }, ] } ] } ]) </script>
Initialization requires 2 steps:
Create object from contextMenu
object, and call init()
function, which has two parameters:
selector
and items
selector
string - any selector compatible with loaded version of jquery
options
array - array of options determines how to render context menu
<script type="text/javascript"> const menuObject = Object.create(contextMenu) menuObject.init(selector, options) </script>
type
string - determines type of bootstrap dropdown element. Available values: item
, header
, divider
, submenu (recursive)
<script type="text/javascript"> const menuObject = Object.create(contextMenu) menuObject.init(selector, [ { type : 'header', text : 'menu header' }, { type : 'item', text : 'menu item' } ]) </script>
text
string|callback - text displayed inside HTML <a>
tag.
You can also inject HTML here if you wanna display icon or someyhing else.
<script type="text/javascript"> const menuObject = Object.create(contextMenu) menuObject.init(selector, [ { type : 'item', text : 'Some text here' }, { type : 'item', text : function(e) { let element = $(e.currentTarget) return element.text() } } ]) </script>
display
boolean|callback default true - if you wanna dynamically decide which element should have some extra options, or display other options based on some conditions, You can use this option as callback.
<script type="text/javascript"> const menuObject = Object.create(contextMenu) menuObject.init(selector, [ { type : 'item', text : 'Some text here' }, { type : 'item', text : 'extra option', display : function(e) { let element = $(e.currentTarget) if(element.hasClass('super-extra-element') === true) { return true } return false } } ]) </script>
html
string|callback - If you want render <li>
element by yourself - You can use this option
type
as 'item'<script type="text/javascript"> const menuObject = Object.create(contextMenu) menuObject.init(selector, [ { type : 'item', html : '<li><a>menu item</a></li>' }, { type : 'item', html : function(e) { let element = $(e.currentTarget) return '<li><a>'+element.text()+'</a></li>' } } ]) </script>
href
string|callback default: javascript:void(0)
- value of href property inside link
<script type="text/javascript"> const menuObject = Object.create(contextMenu) menuObject.init(selector, [ { type : 'item', text : 'link to google', href : 'http://www.google.pl' }, { type : 'item', text : 'open selected file', href : function(e) { let element = $(e.currentTarget) return '/files/preview/'+element.data('id') } } ]) </script>
attr
object - list of attributes (eg. 'class', 'id', 'title', ...) which should be rendered inside <li>
tag. Each of attribute can be string or callback.
<script type="text/javascript"> const menuObject = Object.create(contextMenu) menuObject.init(selector, [ { type : 'item', text : 'hello world', attr : { title : 'some helper text', class : 'active' } }, { type : 'item', text : 'attributes as callbacks', attr : { class : function(e) { let element = $(e.currentTarget) if(element.data('my_data') == 'super') { return 'active' } } } } ]) </script>
submenu
is recursice extra type of item
- You can add large amount of submenus, but remember: More items, menu is less readable, and less handy - this is context menu - You should place here only most common options.<script type="text/javascript"> const menuObject = Object.create(contextMenu) menuObject.init(selector, [ { type : 'item', text : 'typical item' }, { type : 'submenu', text : 'submenu example', items : [ { 'type' : 'item', 'text' : 'submenu item 1' }, { 'type' : 'item', 'text' : 'submenu item 2' }, ] } ]) </script>