obsolete.ChilliProject/public/javascripts/context_menu.jquery.js

224 lines
7.9 KiB
JavaScript
Raw Normal View History

(function($) {
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);
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:
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'))
{
// 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
{
// click is outside the rows
if (target.is('a') === false) {
this.unselectAll();
} else {
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;
}
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 {
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);
});
}
};
methods.createMenu();
if(!observingContextMenuClick) {
element.bind('click.contextMenu', methods.click);
element.bind('contextmenu.contextMenu', methods.click);
observingContextMenuClick = true;
}
methods.unselectAll();
};
$.fn.ContextMenu = function(u) {
return this.each(function() {
new ContextMenuClass($(this), {url: u});
});
};
})(jQuery);
/**
* Wrapper function to support the old way of creating aa context menu.
*/
function ContextMenu() {
jQuery(document).ContextMenu(arguments);
}