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)
|
def context_menu(url)
|
||||||
unless @context_menu_included
|
unless @context_menu_included
|
||||||
content_for :header_tags do
|
content_for :header_tags do
|
||||||
javascript_include_tag('context_menu') +
|
javascript_include_tag('context_menu.jquery') +
|
||||||
stylesheet_link_tag('context_menu')
|
stylesheet_link_tag('context_menu')
|
||||||
end
|
end
|
||||||
if l(:direction) == 'rtl'
|
if l(:direction) == 'rtl'
|
||||||
@ -895,7 +895,7 @@ module ApplicationHelper
|
|||||||
end
|
end
|
||||||
@context_menu_included = true
|
@context_menu_included = true
|
||||||
end
|
end
|
||||||
javascript_tag "new ContextMenu('#{ url_for(url) }')"
|
javascript_tag "jQuery(document).ContextMenu('#{ url_for(url) }')"
|
||||||
end
|
end
|
||||||
|
|
||||||
def context_menu_link(name, url, options={})
|
def context_menu_link(name, url, options={})
|
||||||
|
@ -138,9 +138,9 @@
|
|||||||
<% content_for :header_tags do %>
|
<% 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}") %>
|
<%= 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' %>
|
<%= 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' %>
|
||||||
<%= stylesheet_link_tag 'context_menu_rtl' if l(:direction) == 'rtl' %>
|
<%= stylesheet_link_tag 'context_menu_rtl' if l(:direction) == 'rtl' %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<div id="context-menu" style="display: none;"></div>
|
<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