##// END OF EJS Templates
Issue percentage selector extends screen border (#22059)....
Jean-Philippe Lang -
r14967:ab34455cdd56
parent child
Show More
@@ -1,237 +1,247
1 /* Redmine - project management software
1 /* Redmine - project management software
2 Copyright (C) 2006-2016 Jean-Philippe Lang */
2 Copyright (C) 2006-2016 Jean-Philippe Lang */
3
3
4 var contextMenuObserving;
4 var contextMenuObserving;
5 var contextMenuUrl;
5 var contextMenuUrl;
6
6
7 function contextMenuRightClick(event) {
7 function contextMenuRightClick(event) {
8 var target = $(event.target);
8 var target = $(event.target);
9 if (target.is('a')) {return;}
9 if (target.is('a')) {return;}
10 var tr = target.parents('tr').first();
10 var tr = target.parents('tr').first();
11 if (!tr.hasClass('hascontextmenu')) {return;}
11 if (!tr.hasClass('hascontextmenu')) {return;}
12 event.preventDefault();
12 event.preventDefault();
13 if (!contextMenuIsSelected(tr)) {
13 if (!contextMenuIsSelected(tr)) {
14 contextMenuUnselectAll();
14 contextMenuUnselectAll();
15 contextMenuAddSelection(tr);
15 contextMenuAddSelection(tr);
16 contextMenuSetLastSelected(tr);
16 contextMenuSetLastSelected(tr);
17 }
17 }
18 contextMenuShow(event);
18 contextMenuShow(event);
19 }
19 }
20
20
21 function contextMenuClick(event) {
21 function contextMenuClick(event) {
22 var target = $(event.target);
22 var target = $(event.target);
23 var lastSelected;
23 var lastSelected;
24
24
25 if (target.is('a') && target.hasClass('submenu')) {
25 if (target.is('a') && target.hasClass('submenu')) {
26 event.preventDefault();
26 event.preventDefault();
27 return;
27 return;
28 }
28 }
29 contextMenuHide();
29 contextMenuHide();
30 if (target.is('a') || target.is('img')) { return; }
30 if (target.is('a') || target.is('img')) { return; }
31 if (event.which == 1 || (navigator.appVersion.match(/\bMSIE\b/))) {
31 if (event.which == 1 || (navigator.appVersion.match(/\bMSIE\b/))) {
32 var tr = target.parents('tr').first();
32 var tr = target.parents('tr').first();
33 if (tr.length && tr.hasClass('hascontextmenu')) {
33 if (tr.length && tr.hasClass('hascontextmenu')) {
34 // a row was clicked, check if the click was on checkbox
34 // a row was clicked, check if the click was on checkbox
35 if (target.is('input')) {
35 if (target.is('input')) {
36 // a checkbox may be clicked
36 // a checkbox may be clicked
37 if (target.prop('checked')) {
37 if (target.prop('checked')) {
38 tr.addClass('context-menu-selection');
38 tr.addClass('context-menu-selection');
39 } else {
39 } else {
40 tr.removeClass('context-menu-selection');
40 tr.removeClass('context-menu-selection');
41 }
41 }
42 } else {
42 } else {
43 if (event.ctrlKey || event.metaKey) {
43 if (event.ctrlKey || event.metaKey) {
44 contextMenuToggleSelection(tr);
44 contextMenuToggleSelection(tr);
45 } else if (event.shiftKey) {
45 } else if (event.shiftKey) {
46 lastSelected = contextMenuLastSelected();
46 lastSelected = contextMenuLastSelected();
47 if (lastSelected.length) {
47 if (lastSelected.length) {
48 var toggling = false;
48 var toggling = false;
49 $('.hascontextmenu').each(function(){
49 $('.hascontextmenu').each(function(){
50 if (toggling || $(this).is(tr)) {
50 if (toggling || $(this).is(tr)) {
51 contextMenuAddSelection($(this));
51 contextMenuAddSelection($(this));
52 }
52 }
53 if ($(this).is(tr) || $(this).is(lastSelected)) {
53 if ($(this).is(tr) || $(this).is(lastSelected)) {
54 toggling = !toggling;
54 toggling = !toggling;
55 }
55 }
56 });
56 });
57 } else {
57 } else {
58 contextMenuAddSelection(tr);
58 contextMenuAddSelection(tr);
59 }
59 }
60 } else {
60 } else {
61 contextMenuUnselectAll();
61 contextMenuUnselectAll();
62 contextMenuAddSelection(tr);
62 contextMenuAddSelection(tr);
63 }
63 }
64 contextMenuSetLastSelected(tr);
64 contextMenuSetLastSelected(tr);
65 }
65 }
66 } else {
66 } else {
67 // click is outside the rows
67 // click is outside the rows
68 if (target.is('a') && (target.hasClass('disabled') || target.hasClass('submenu'))) {
68 if (target.is('a') && (target.hasClass('disabled') || target.hasClass('submenu'))) {
69 event.preventDefault();
69 event.preventDefault();
70 } else if (target.is('.toggle-selection') || target.is('.ui-dialog *') || $('#ajax-modal').is(':visible')) {
70 } else if (target.is('.toggle-selection') || target.is('.ui-dialog *') || $('#ajax-modal').is(':visible')) {
71 // nop
71 // nop
72 } else {
72 } else {
73 contextMenuUnselectAll();
73 contextMenuUnselectAll();
74 }
74 }
75 }
75 }
76 }
76 }
77 }
77 }
78
78
79 function contextMenuCreate() {
79 function contextMenuCreate() {
80 if ($('#context-menu').length < 1) {
80 if ($('#context-menu').length < 1) {
81 var menu = document.createElement("div");
81 var menu = document.createElement("div");
82 menu.setAttribute("id", "context-menu");
82 menu.setAttribute("id", "context-menu");
83 menu.setAttribute("style", "display:none;");
83 menu.setAttribute("style", "display:none;");
84 document.getElementById("content").appendChild(menu);
84 document.getElementById("content").appendChild(menu);
85 }
85 }
86 }
86 }
87
87
88 function contextMenuShow(event) {
88 function contextMenuShow(event) {
89 var mouse_x = event.pageX;
89 var mouse_x = event.pageX;
90 var mouse_y = event.pageY;
90 var mouse_y = event.pageY;
91 var mouse_y_c = event.clientY;
91 var render_x = mouse_x;
92 var render_x = mouse_x;
92 var render_y = mouse_y;
93 var render_y = mouse_y;
93 var dims;
94 var dims;
94 var menu_width;
95 var menu_width;
95 var menu_height;
96 var menu_height;
96 var window_width;
97 var window_width;
97 var window_height;
98 var window_height;
98 var max_width;
99 var max_width;
99 var max_height;
100 var max_height;
100
101
101 $('#context-menu').css('left', (render_x + 'px'));
102 $('#context-menu').css('left', (render_x + 'px'));
102 $('#context-menu').css('top', (render_y + 'px'));
103 $('#context-menu').css('top', (render_y + 'px'));
103 $('#context-menu').html('');
104 $('#context-menu').html('');
104
105
105 $.ajax({
106 $.ajax({
106 url: contextMenuUrl,
107 url: contextMenuUrl,
107 data: $(event.target).parents('form').first().serialize(),
108 data: $(event.target).parents('form').first().serialize(),
108 success: function(data, textStatus, jqXHR) {
109 success: function(data, textStatus, jqXHR) {
109 $('#context-menu').html(data);
110 $('#context-menu').html(data);
110 menu_width = $('#context-menu').width();
111 menu_width = $('#context-menu').width();
111 menu_height = $('#context-menu').height();
112 menu_height = $('#context-menu').height();
112 max_width = mouse_x + 2*menu_width;
113 max_width = mouse_x + 2*menu_width;
113 max_height = mouse_y + menu_height;
114 max_height = mouse_y_c + menu_height;
114
115
115 var ws = window_size();
116 var ws = window_size();
116 window_width = ws.width;
117 window_width = ws.width;
117 window_height = ws.height;
118 window_height = ws.height;
118
119
119 /* display the menu above and/or to the left of the click if needed */
120 /* display the menu above and/or to the left of the click if needed */
120 if (max_width > window_width) {
121 if (max_width > window_width) {
121 render_x -= menu_width;
122 render_x -= menu_width;
122 $('#context-menu').addClass('reverse-x');
123 $('#context-menu').addClass('reverse-x');
123 } else {
124 } else {
124 $('#context-menu').removeClass('reverse-x');
125 $('#context-menu').removeClass('reverse-x');
125 }
126 }
127
126 if (max_height > window_height) {
128 if (max_height > window_height) {
127 render_y -= menu_height;
129 render_y -= menu_height;
128 $('#context-menu').addClass('reverse-y');
130 $('#context-menu').addClass('reverse-y');
131 // adding class for submenu
132 if (mouse_y_c < 325) {
133 $('#context-menu .folder').addClass('down');
134 }
129 } else {
135 } else {
130 $('#context-menu').removeClass('reverse-y');
136 // adding class for submenu
137 if (window_height - mouse_y_c < 345) {
138 $('#context-menu .folder').addClass('up');
139 }
140 $('#context-menu').removeClass('reverse-y');
131 }
141 }
142
132 if (render_x <= 0) render_x = 1;
143 if (render_x <= 0) render_x = 1;
133 if (render_y <= 0) render_y = 1;
144 if (render_y <= 0) render_y = 1;
134 $('#context-menu').css('left', (render_x + 'px'));
145 $('#context-menu').css('left', (render_x + 'px'));
135 $('#context-menu').css('top', (render_y + 'px'));
146 $('#context-menu').css('top', (render_y + 'px'));
136 $('#context-menu').show();
147 $('#context-menu').show();
137
148
138 //if (window.parseStylesheets) { window.parseStylesheets(); } // IE
149 //if (window.parseStylesheets) { window.parseStylesheets(); } // IE
139
140 }
150 }
141 });
151 });
142 }
152 }
143
153
144 function contextMenuSetLastSelected(tr) {
154 function contextMenuSetLastSelected(tr) {
145 $('.cm-last').removeClass('cm-last');
155 $('.cm-last').removeClass('cm-last');
146 tr.addClass('cm-last');
156 tr.addClass('cm-last');
147 }
157 }
148
158
149 function contextMenuLastSelected() {
159 function contextMenuLastSelected() {
150 return $('.cm-last').first();
160 return $('.cm-last').first();
151 }
161 }
152
162
153 function contextMenuUnselectAll() {
163 function contextMenuUnselectAll() {
154 $('input[type=checkbox].toggle-selection').prop('checked', false);
164 $('input[type=checkbox].toggle-selection').prop('checked', false);
155 $('.hascontextmenu').each(function(){
165 $('.hascontextmenu').each(function(){
156 contextMenuRemoveSelection($(this));
166 contextMenuRemoveSelection($(this));
157 });
167 });
158 $('.cm-last').removeClass('cm-last');
168 $('.cm-last').removeClass('cm-last');
159 }
169 }
160
170
161 function contextMenuHide() {
171 function contextMenuHide() {
162 $('#context-menu').hide();
172 $('#context-menu').hide();
163 }
173 }
164
174
165 function contextMenuToggleSelection(tr) {
175 function contextMenuToggleSelection(tr) {
166 if (contextMenuIsSelected(tr)) {
176 if (contextMenuIsSelected(tr)) {
167 contextMenuRemoveSelection(tr);
177 contextMenuRemoveSelection(tr);
168 } else {
178 } else {
169 contextMenuAddSelection(tr);
179 contextMenuAddSelection(tr);
170 }
180 }
171 }
181 }
172
182
173 function contextMenuAddSelection(tr) {
183 function contextMenuAddSelection(tr) {
174 tr.addClass('context-menu-selection');
184 tr.addClass('context-menu-selection');
175 contextMenuCheckSelectionBox(tr, true);
185 contextMenuCheckSelectionBox(tr, true);
176 contextMenuClearDocumentSelection();
186 contextMenuClearDocumentSelection();
177 }
187 }
178
188
179 function contextMenuRemoveSelection(tr) {
189 function contextMenuRemoveSelection(tr) {
180 tr.removeClass('context-menu-selection');
190 tr.removeClass('context-menu-selection');
181 contextMenuCheckSelectionBox(tr, false);
191 contextMenuCheckSelectionBox(tr, false);
182 }
192 }
183
193
184 function contextMenuIsSelected(tr) {
194 function contextMenuIsSelected(tr) {
185 return tr.hasClass('context-menu-selection');
195 return tr.hasClass('context-menu-selection');
186 }
196 }
187
197
188 function contextMenuCheckSelectionBox(tr, checked) {
198 function contextMenuCheckSelectionBox(tr, checked) {
189 tr.find('input[type=checkbox]').prop('checked', checked);
199 tr.find('input[type=checkbox]').prop('checked', checked);
190 }
200 }
191
201
192 function contextMenuClearDocumentSelection() {
202 function contextMenuClearDocumentSelection() {
193 // TODO
203 // TODO
194 if (document.selection) {
204 if (document.selection) {
195 document.selection.empty(); // IE
205 document.selection.empty(); // IE
196 } else {
206 } else {
197 window.getSelection().removeAllRanges();
207 window.getSelection().removeAllRanges();
198 }
208 }
199 }
209 }
200
210
201 function contextMenuInit(url) {
211 function contextMenuInit(url) {
202 contextMenuUrl = url;
212 contextMenuUrl = url;
203 contextMenuCreate();
213 contextMenuCreate();
204 contextMenuUnselectAll();
214 contextMenuUnselectAll();
205
215
206 if (!contextMenuObserving) {
216 if (!contextMenuObserving) {
207 $(document).click(contextMenuClick);
217 $(document).click(contextMenuClick);
208 $(document).contextmenu(contextMenuRightClick);
218 $(document).contextmenu(contextMenuRightClick);
209 contextMenuObserving = true;
219 contextMenuObserving = true;
210 }
220 }
211 }
221 }
212
222
213 function toggleIssuesSelection(el) {
223 function toggleIssuesSelection(el) {
214 var checked = $(this).prop('checked');
224 var checked = $(this).prop('checked');
215 var boxes = $(this).parents('table').find('input[name=ids\\[\\]]');
225 var boxes = $(this).parents('table').find('input[name=ids\\[\\]]');
216 boxes.prop('checked', checked).parents('tr').toggleClass('context-menu-selection', checked);
226 boxes.prop('checked', checked).parents('tr').toggleClass('context-menu-selection', checked);
217 }
227 }
218
228
219 function window_size() {
229 function window_size() {
220 var w;
230 var w;
221 var h;
231 var h;
222 if (window.innerWidth) {
232 if (window.innerWidth) {
223 w = window.innerWidth;
233 w = window.innerWidth;
224 h = window.innerHeight;
234 h = window.innerHeight;
225 } else if (document.documentElement) {
235 } else if (document.documentElement) {
226 w = document.documentElement.clientWidth;
236 w = document.documentElement.clientWidth;
227 h = document.documentElement.clientHeight;
237 h = document.documentElement.clientHeight;
228 } else {
238 } else {
229 w = document.body.clientWidth;
239 w = document.body.clientWidth;
230 h = document.body.clientHeight;
240 h = document.body.clientHeight;
231 }
241 }
232 return {width: w, height: h};
242 return {width: w, height: h};
233 }
243 }
234
244
235 $(document).ready(function(){
245 $(document).ready(function(){
236 $('input[type=checkbox].toggle-selection').on('change', toggleIssuesSelection);
246 $('input[type=checkbox].toggle-selection').on('change', toggleIssuesSelection);
237 });
247 });
@@ -1,52 +1,56
1 #context-menu { position: absolute; z-index: 40; font-size: 0.9em;}
1 #context-menu { position: absolute; z-index: 40; font-size: 0.9em;}
2
2
3 #context-menu ul, #context-menu li, #context-menu a {
3 #context-menu ul, #context-menu li, #context-menu a {
4 display:block;
4 display:block;
5 margin:0;
5 margin:0;
6 padding:0;
6 padding:0;
7 border:0;
7 border:0;
8 }
8 }
9
9
10 #context-menu ul {
10 #context-menu ul {
11 width:150px;
11 width:150px;
12 border: 1px solid #ccc;
12 border: 1px solid #ccc;
13 background:white;
13 background:white;
14 list-style:none;
14 list-style:none;
15 padding:2px;
15 padding:2px;
16 border-radius:2px;
16 border-radius:2px;
17 }
17 }
18
18
19 #context-menu li {
19 #context-menu li {
20 position:relative;
20 position:relative;
21 padding:1px;
21 padding:1px;
22 z-index:39;
22 z-index:39;
23 border:1px solid white;
23 border:1px solid white;
24 }
24 }
25 #context-menu li.folder ul { position:absolute; left:168px; /* IE6 */ top:-2px; max-height:300px; overflow:hidden; overflow-y: auto; }
25 #context-menu li.folder ul { position:absolute; left:168px; /* IE6 */ top:-2px; max-height:300px; overflow:hidden; overflow-y: auto; }
26 #context-menu li.folder>ul { left:148px; }
26 #context-menu li.folder>ul { left:148px; }
27
27
28 #context-menu.reverse-y li.folder>ul { top:auto; bottom:0; }
28 #context-menu.reverse-y li.folder>ul, #context-menu li.folder.up>ul { top:auto; bottom:0; }
29 #context-menu.reverse-x li.folder ul { left:auto; right:168px; /* IE6 */ }
29 #context-menu.reverse-x li.folder ul { left:auto; right:168px; /* IE6 */ }
30 #context-menu.reverse-x li.folder>ul { right:148px; }
30 #context-menu.reverse-x li.folder>ul { right:148px; }
31
31
32 #context-menu.reverse-y li.folder.down>ul {
33 position:absolute; top:-2px; bottom: auto; max-height:300px; overflow:hidden; overflow-y: auto;
34 }
35
32 #context-menu a {
36 #context-menu a {
33 text-decoration:none !important;
37 text-decoration:none !important;
34 background-repeat: no-repeat;
38 background-repeat: no-repeat;
35 background-position: 1px 50%;
39 background-position: 1px 50%;
36 padding: 2px 0px 2px 20px;
40 padding: 2px 0px 2px 20px;
37 width:100%; /* IE */
41 width:100%; /* IE */
38 }
42 }
39 #context-menu li>a { width:auto; } /* others */
43 #context-menu li>a { width:auto; } /* others */
40 #context-menu a.disabled, #context-menu a.disabled:hover {color: #aaa;}
44 #context-menu a.disabled, #context-menu a.disabled:hover {color: #aaa;}
41 #context-menu li a.submenu { padding-right:16px; background:url("../images/bullet_arrow_right.png") right no-repeat; }
45 #context-menu li a.submenu { padding-right:16px; background:url("../images/bullet_arrow_right.png") right no-repeat; }
42 #context-menu li:hover { border:1px solid #628db6; background-color:#eef5fd; border-radius:3px; }
46 #context-menu li:hover { border:1px solid #628db6; background-color:#eef5fd; border-radius:3px; }
43 #context-menu a:hover {color:#2A5685;}
47 #context-menu a:hover {color:#2A5685;}
44 #context-menu li.folder:hover { z-index:40; }
48 #context-menu li.folder:hover { z-index:40; }
45 #context-menu ul ul, #context-menu li:hover ul ul { display:none; }
49 #context-menu ul ul, #context-menu li:hover ul ul { display:none; }
46 #context-menu li:hover ul, #context-menu li:hover li:hover ul { display:block; }
50 #context-menu li:hover ul, #context-menu li:hover li:hover ul { display:block; }
47 #context-menu a.icon-checked {background: url(../images/toggle_check.png) no-repeat 3px 40%;}
51 #context-menu a.icon-checked {background: url(../images/toggle_check.png) no-repeat 3px 40%;}
48
52
49 /* selected element */
53 /* selected element */
50 .context-menu-selection { background-color:#507AAA !important; color:#f8f8f8 !important; }
54 .context-menu-selection { background-color:#507AAA !important; color:#f8f8f8 !important; }
51 .context-menu-selection a, .context-menu-selection a:hover { color:#f8f8f8 !important; }
55 .context-menu-selection a, .context-menu-selection a:hover { color:#f8f8f8 !important; }
52 .context-menu-selection:hover { background-color:#507AAA !important; color:#f8f8f8 !important; }
56 .context-menu-selection:hover { background-color:#507AAA !important; color:#f8f8f8 !important; }
General Comments 0
You need to be logged in to leave comments. Login now