Updates the plugin so that it can support multiple instances.
Multiple instances need to be applied to different elements in the DOM otherwise multiple menus will be called for each click/right click. e.g. jQuery(document).ContextMenu(url); would work for any form on a page. Using this would mean that multiple instances couldn't be used though jQuery('#content form').eq(0).ContextMenu(url); jQuery('#content form').eq(3).ContextMenu(url); Using the above 2 menus will be created for the first and 4th forms on the page. Any of forms won't response to menu clicks. jQuery(docuemnt).ContextMenu(url); jQuery('#content form').eq(0).ContextMenu(url); With the above any form on the page will respond to menu clicks but the first form will send 2 requests for the context menu.
This commit is contained in:
parent
2b640f76ec
commit
a510f0a85f
|
@ -1,212 +1,217 @@
|
|||
(function($) {
|
||||
var observingContextMenuClick;
|
||||
var url;
|
||||
var lastSelected;
|
||||
var menu;
|
||||
var menuId = 'context-menu';
|
||||
var selectorName = 'hascontextmenu';
|
||||
var contextMenuSelectionClass = 'context-menu-selection';
|
||||
var reverseXClass = 'reverse-x';
|
||||
var reverseYClass = 'reverse-y';
|
||||
var ContextMenuClass = function(el, options) {
|
||||
var element = el;
|
||||
var opts = options;
|
||||
var observingContextMenuClick;
|
||||
var lastSelected = null;
|
||||
var menu;
|
||||
var menuId = 'context-menu';
|
||||
var selectorName = 'hascontextmenu';
|
||||
var contextMenuSelectionClass = 'context-menu-selection';
|
||||
var reverseXClass = 'reverse-x';
|
||||
var reverseYClass = 'reverse-y';
|
||||
|
||||
var methods = {
|
||||
createMenu: function() {
|
||||
if(!menu) {
|
||||
$('#wrapper').append('<div id="' + menuId + '" style="display:none"></div>');
|
||||
menu = $('#' + menuId);
|
||||
}
|
||||
},
|
||||
click: function(e) {
|
||||
var target = $(e.target);
|
||||
var methods = {
|
||||
createMenu: function() {
|
||||
if(!menu) {
|
||||
$('#wrapper').append('<div id="' + menuId + '" style="display:none"></div>');
|
||||
menu = $('#' + menuId);
|
||||
}
|
||||
},
|
||||
click: function(e) {
|
||||
var target = $(e.target);
|
||||
|
||||
if(target.is('a')) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(e.which) {
|
||||
case 1:
|
||||
if(e.type === 'click') {
|
||||
methods.hideMenu();
|
||||
methods.leftClick(e);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
if(e.type === 'contextmenu') {
|
||||
methods.hideMenu();
|
||||
methods.rightClick(e);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if(target.is('a')) {
|
||||
return;
|
||||
}
|
||||
},
|
||||
leftClick: function(e) {
|
||||
var target = $(e.target);
|
||||
var tr = target.parents('tr');
|
||||
if((tr.size() > 0) && tr.hasClass(selectorName))
|
||||
{
|
||||
// a row was clicked, check if the click was on checkbox
|
||||
if(target.is('input'))
|
||||
}
|
||||
|
||||
switch(e.which) {
|
||||
case 1:
|
||||
if(e.type === 'click') {
|
||||
methods.hideMenu();
|
||||
methods.leftClick(e);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
if(e.type === 'contextmenu') {
|
||||
methods.hideMenu();
|
||||
methods.rightClick(e);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
},
|
||||
leftClick: function(e) {
|
||||
var target = $(e.target);
|
||||
var tr = target.parents('tr');
|
||||
if((tr.size() > 0) && tr.hasClass(selectorName))
|
||||
{
|
||||
// a checkbox may be clicked
|
||||
if (target.is(':checked')) {
|
||||
tr.addClass(contextMenuSelectionClass);
|
||||
} else {
|
||||
tr.removeClass(contextMenuSelectionClass);
|
||||
// a row was clicked, check if the click was on checkbox
|
||||
if(target.is('input'))
|
||||
{
|
||||
// a checkbox may be clicked
|
||||
if (target.is(':checked')) {
|
||||
tr.addClass(contextMenuSelectionClass);
|
||||
} else {
|
||||
tr.removeClass(contextMenuSelectionClass);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.ctrlKey || e.metaKey)
|
||||
{
|
||||
methods.toggleSelection(tr);
|
||||
}
|
||||
else if (e.shiftKey)
|
||||
{
|
||||
if (lastSelected !== null)
|
||||
{
|
||||
var toggling = false;
|
||||
var rows = $(selectorName);
|
||||
for (i = 0; i < rows.length; i++)
|
||||
{
|
||||
if (toggling || rows[i] == tr)
|
||||
{
|
||||
methods.addSelection(rows[i]);
|
||||
}
|
||||
if (rows[i] == tr || rows[i] == lastSelected)
|
||||
{
|
||||
toggling = !toggling;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
methods.addSelection(tr);
|
||||
}
|
||||
} else {
|
||||
methods.unselectAll();
|
||||
methods.addSelection(tr);
|
||||
}
|
||||
lastSelected = tr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e.ctrlKey || e.metaKey)
|
||||
{
|
||||
methods.toggleSelection(tr);
|
||||
}
|
||||
else if (e.shiftKey)
|
||||
{
|
||||
if (lastSelected !== null)
|
||||
{
|
||||
var toggling = false;
|
||||
var rows = $(selectorName);
|
||||
for (i = 0; i < rows.length; i++)
|
||||
{
|
||||
if (toggling || rows[i] == tr)
|
||||
{
|
||||
methods.addSelection(rows[i]);
|
||||
}
|
||||
if (rows[i] == tr || rows[i] == lastSelected)
|
||||
{
|
||||
toggling = !toggling;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
methods.addSelection(tr);
|
||||
}
|
||||
// click is outside the rows
|
||||
if (target.is('a') === false) {
|
||||
this.unselectAll();
|
||||
} else {
|
||||
methods.unselectAll();
|
||||
methods.addSelection(tr);
|
||||
if (target.hasClass('disabled') || target.hasClass('submenu')) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
rightClick: function(e) {
|
||||
var target = $(e.target);
|
||||
var tr = target.parents('tr');
|
||||
|
||||
if((tr.size() === 0) || !(tr.hasClass(selectorName))) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
if(!methods.isSelected(tr)) {
|
||||
methods.unselectAll();
|
||||
methods.addSelection(tr);
|
||||
lastSelected = tr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// click is outside the rows
|
||||
if (target.is('a') === false) {
|
||||
this.unselectAll();
|
||||
methods.showMenu(e);
|
||||
},
|
||||
unselectAll: function() {
|
||||
var rows = $('.' + contextMenuSelectionClass);
|
||||
rows.each(function() {
|
||||
methods.removeSelection($(this));
|
||||
});
|
||||
},
|
||||
hideMenu: function() {
|
||||
menu.hide();
|
||||
},
|
||||
showMenu: function(e) {
|
||||
var target = $(e.target);
|
||||
var params = target.parents('form').serialize();
|
||||
|
||||
var mouseX = e.pageX;
|
||||
var mouseY = e.pageY;
|
||||
var renderX = mouseX;
|
||||
var renderY = mouseY;
|
||||
|
||||
$.ajax({
|
||||
url: opts.url,
|
||||
data: params,
|
||||
success: function(response, success) {
|
||||
menu.html(response);
|
||||
|
||||
var maxWidth = mouseX + (2 * menu.width());
|
||||
var maxHeight = mouseY + menu.height();
|
||||
|
||||
if(maxWidth > $(window).width()) {
|
||||
renderX -= menu.width();
|
||||
menu.addClass(reverseXClass);
|
||||
} else {
|
||||
menu.removeClass(reverseXClass);
|
||||
}
|
||||
|
||||
if(maxHeight > $(window).height()) {
|
||||
renderY =+ menu.height();
|
||||
menu.addClass(reverseYClass);
|
||||
} else {
|
||||
menu.removeClass(reverseYClass);
|
||||
}
|
||||
|
||||
if(renderX <= 0) {
|
||||
renderX = 1;
|
||||
}
|
||||
if(renderY <= 0) {
|
||||
renderY = 1;
|
||||
}
|
||||
|
||||
menu.css('top', renderY).css('left', renderX);
|
||||
menu.show();
|
||||
}
|
||||
});
|
||||
},
|
||||
addSelection: function(element) {
|
||||
element.addClass(contextMenuSelectionClass);
|
||||
methods.checkSelectionBox(element, true);
|
||||
},
|
||||
isSelected: function(element) {
|
||||
return element.hasClass(contextMenuSelectionClass);
|
||||
},
|
||||
toggleSelection: function(element) {
|
||||
if(methods.isSelected(element)) {
|
||||
methods.removeSelection(element);
|
||||
} else {
|
||||
if (target.hasClass('disabled') || target.hasClass('submenu')) {
|
||||
e.preventDefault();
|
||||
}
|
||||
methods.addSelection(element);
|
||||
}
|
||||
},
|
||||
removeSelection: function(element) {
|
||||
element.removeClass(contextMenuSelectionClass);
|
||||
methods.checkSelectionBox(element, false);
|
||||
},
|
||||
checkSelectionBox: function(element, checked) {
|
||||
var inputs = element.find('input');
|
||||
inputs.each(function() {
|
||||
inputs.attr('checked', checked ? 'checked' : false);
|
||||
});
|
||||
}
|
||||
},
|
||||
rightClick: function(e) {
|
||||
var target = $(e.target);
|
||||
var tr = target.parents('tr');
|
||||
};
|
||||
|
||||
if((tr.size() === 0) || !(tr.hasClass(selectorName))) {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
if(!methods.isSelected(tr)) {
|
||||
methods.unselectAll();
|
||||
methods.addSelection(tr);
|
||||
lastSelected = tr;
|
||||
}
|
||||
methods.showMenu(e);
|
||||
},
|
||||
unselectAll: function() {
|
||||
var rows = $('.' + contextMenuSelectionClass);
|
||||
rows.each(function() {
|
||||
methods.removeSelection($(this));
|
||||
});
|
||||
},
|
||||
hideMenu: function() {
|
||||
menu.hide();
|
||||
},
|
||||
showMenu: function(e) {
|
||||
var target = $(e.target);
|
||||
var params = target.parents('form').serialize();
|
||||
|
||||
var mouseX = e.pageX;
|
||||
var mouseY = e.pageY;
|
||||
var renderX = mouseX;
|
||||
var renderY = mouseY;
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
data: params,
|
||||
success: function(response, success) {
|
||||
menu.html(response);
|
||||
|
||||
var maxWidth = mouseX + (2 * menu.width());
|
||||
var maxHeight = mouseY + menu.height();
|
||||
|
||||
if(maxWidth > $(window).width()) {
|
||||
renderX -= menu.width();
|
||||
menu.addClass(reverseXClass);
|
||||
} else {
|
||||
menu.removeClass(reverseXClass);
|
||||
}
|
||||
|
||||
if(maxHeight > $(window).height()) {
|
||||
renderY =+ menu.height();
|
||||
menu.addClass(reverseYClass);
|
||||
} else {
|
||||
menu.removeClass(reverseYClass);
|
||||
}
|
||||
|
||||
if(renderX <= 0) {
|
||||
renderX = 1;
|
||||
}
|
||||
if(renderY <= 0) {
|
||||
renderY = 1;
|
||||
}
|
||||
|
||||
menu.css('top', renderY).css('left', renderX);
|
||||
menu.show();
|
||||
}
|
||||
});
|
||||
},
|
||||
addSelection: function(element) {
|
||||
element.addClass(contextMenuSelectionClass);
|
||||
methods.checkSelectionBox(element, true);
|
||||
},
|
||||
isSelected: function(element) {
|
||||
return element.hasClass(contextMenuSelectionClass);
|
||||
},
|
||||
toggleSelection: function(element) {
|
||||
if(methods.isSelected(element)) {
|
||||
methods.removeSelection(element);
|
||||
} else {
|
||||
methods.addSelection(element);
|
||||
}
|
||||
},
|
||||
removeSelection: function(element) {
|
||||
element.removeClass(contextMenuSelectionClass);
|
||||
methods.checkSelectionBox(element, false);
|
||||
},
|
||||
checkSelectionBox: function(element, checked) {
|
||||
var inputs = element.find('input');
|
||||
inputs.each(function() {
|
||||
inputs.attr('checked', checked ? 'checked' : false);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.ContextMenu = function(u) {
|
||||
url = u;
|
||||
methods.createMenu();
|
||||
|
||||
if(!observingContextMenuClick) {
|
||||
$(document).bind('click.contextMenu', methods.click);
|
||||
$(document).bind('contextmenu.contextMenu', methods.click);
|
||||
element.bind('click.contextMenu', methods.click);
|
||||
element.bind('contextmenu.contextMenu', methods.click);
|
||||
observingContextMenuClick = true;
|
||||
}
|
||||
|
||||
methods.unselectAll();
|
||||
lastSelected = null;
|
||||
};
|
||||
|
||||
$.fn.ContextMenu = function(u) {
|
||||
return this.each(function() {
|
||||
new ContextMenuClass($(this), {url: u});
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
||||
|
||||
|
|
Loading…
Reference in New Issue