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>