jQuery version of the issue context menu
This commit is contained in:
parent
27160b76f5
commit
1b7ddb3cd7
@ -885,7 +885,7 @@ module ApplicationHelper
|
||||
def context_menu(url)
|
||||
unless @context_menu_included
|
||||
content_for :header_tags do
|
||||
javascript_include_tag('context_menu') +
|
||||
javascript_include_tag('context_menu.jquery') +
|
||||
stylesheet_link_tag('context_menu')
|
||||
end
|
||||
if l(:direction) == 'rtl'
|
||||
@ -895,7 +895,7 @@ module ApplicationHelper
|
||||
end
|
||||
@context_menu_included = true
|
||||
end
|
||||
javascript_tag "new ContextMenu('#{ url_for(url) }')"
|
||||
javascript_tag "jQuery(document).ContextMenu('#{ url_for(url) }')"
|
||||
end
|
||||
|
||||
def context_menu_link(name, url, options={})
|
||||
|
@ -138,9 +138,9 @@
|
||||
<% content_for :header_tags do %>
|
||||
<%= auto_discovery_link_tag(:atom, {:format => 'atom', :key => User.current.rss_key}, :title => "#{@issue.project} - #{@issue.tracker} ##{@issue.id}: #{@issue.subject}") %>
|
||||
<%= stylesheet_link_tag 'scm' %>
|
||||
<%= javascript_include_tag 'context_menu' %>
|
||||
<%= javascript_include_tag 'context_menu.jquery' %>
|
||||
<%= stylesheet_link_tag 'context_menu' %>
|
||||
<%= stylesheet_link_tag 'context_menu_rtl' if l(:direction) == 'rtl' %>
|
||||
<% end %>
|
||||
<div id="context-menu" style="display: none;"></div>
|
||||
<%= javascript_tag "new ContextMenu('#{issues_context_menu_path}')" %>
|
||||
<%= javascript_tag "jQuery(document).ContextMenu('#{issues_context_menu_path}')" %>
|
||||
|
211
public/javascripts/context_menu.jquery.js
Normal file
211
public/javascripts/context_menu.jquery.js
Normal file
@ -0,0 +1,211 @@
|
||||
(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 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: 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);
|
||||
observingContextMenuClick = true;
|
||||
}
|
||||
|
||||
methods.unselectAll();
|
||||
lastSelected = null;
|
||||
};
|
||||
})(jQuery);
|
Loading…
x
Reference in New Issue
Block a user