##// END OF EJS Templates
Replaces the link with a checkbox to select/unselect all items in the list....
Jean-Philippe Lang -
r14347:c29727dd39fa
parent child
Show More
@@ -1,45 +1,44
1 <%= form_tag({}) do -%>
1 <%= form_tag({}) do -%>
2 <%= hidden_field_tag 'back_url', url_for(params), :id => nil %>
2 <%= hidden_field_tag 'back_url', url_for(params), :id => nil %>
3 <div class="autoscroll">
3 <div class="autoscroll">
4 <table class="list issues <%= sort_css_classes %>">
4 <table class="list issues <%= sort_css_classes %>">
5 <thead>
5 <thead>
6 <tr>
6 <tr>
7 <th class="checkbox hide-when-print">
7 <th class="checkbox hide-when-print">
8 <%= link_to image_tag('toggle_check.png'), {},
8 <%= check_box_tag 'check_all', '', false, :class => 'toggle-selection',
9 :onclick => 'toggleIssuesSelection(this); return false;',
10 :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
9 :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
11 </th>
10 </th>
12 <% query.inline_columns.each do |column| %>
11 <% query.inline_columns.each do |column| %>
13 <%= column_header(column) %>
12 <%= column_header(column) %>
14 <% end %>
13 <% end %>
15 </tr>
14 </tr>
16 </thead>
15 </thead>
17 <tbody>
16 <tbody>
18 <% grouped_issue_list(issues, @query, @issue_count_by_group) do |issue, level, group_name, group_count, group_totals| -%>
17 <% grouped_issue_list(issues, @query, @issue_count_by_group) do |issue, level, group_name, group_count, group_totals| -%>
19 <% if group_name %>
18 <% if group_name %>
20 <% reset_cycle %>
19 <% reset_cycle %>
21 <tr class="group open">
20 <tr class="group open">
22 <td colspan="<%= query.inline_columns.size + 2 %>">
21 <td colspan="<%= query.inline_columns.size + 2 %>">
23 <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
22 <span class="expander" onclick="toggleRowGroup(this);">&nbsp;</span>
24 <span class="name"><%= group_name %></span> <span class="count"><%= group_count %></span> <span class="totals"><%= group_totals %></span>
23 <span class="name"><%= group_name %></span> <span class="count"><%= group_count %></span> <span class="totals"><%= group_totals %></span>
25 <%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}",
24 <%= link_to_function("#{l(:button_collapse_all)}/#{l(:button_expand_all)}",
26 "toggleAllRowGroups(this)", :class => 'toggle-all') %>
25 "toggleAllRowGroups(this)", :class => 'toggle-all') %>
27 </td>
26 </td>
28 </tr>
27 </tr>
29 <% end %>
28 <% end %>
30 <tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
29 <tr id="issue-<%= issue.id %>" class="hascontextmenu <%= cycle('odd', 'even') %> <%= issue.css_classes %> <%= level > 0 ? "idnt idnt-#{level}" : nil %>">
31 <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
30 <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", issue.id, false, :id => nil) %></td>
32 <%= raw query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, issue)}</td>"}.join %>
31 <%= raw query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, issue)}</td>"}.join %>
33 </tr>
32 </tr>
34 <% @query.block_columns.each do |column|
33 <% @query.block_columns.each do |column|
35 if (text = column_content(column, issue)) && text.present? -%>
34 if (text = column_content(column, issue)) && text.present? -%>
36 <tr class="<%= current_cycle %>">
35 <tr class="<%= current_cycle %>">
37 <td colspan="<%= @query.inline_columns.size + 1 %>" class="<%= column.css_classes %>"><%= text %></td>
36 <td colspan="<%= @query.inline_columns.size + 1 %>" class="<%= column.css_classes %>"><%= text %></td>
38 </tr>
37 </tr>
39 <% end -%>
38 <% end -%>
40 <% end -%>
39 <% end -%>
41 <% end -%>
40 <% end -%>
42 </tbody>
41 </tbody>
43 </table>
42 </table>
44 </div>
43 </div>
45 <% end -%>
44 <% end -%>
@@ -1,41 +1,39
1 <%= form_tag({}) do -%>
1 <%= form_tag({}) do -%>
2 <%= hidden_field_tag 'back_url', url_for(params) %>
2 <%= hidden_field_tag 'back_url', url_for(params) %>
3 <div class="autoscroll">
3 <div class="autoscroll">
4 <table class="list time-entries">
4 <table class="list time-entries">
5 <thead>
5 <thead>
6 <tr>
6 <tr>
7 <th class="checkbox hide-when-print">
7 <th class="checkbox hide-when-print">
8 <%= link_to image_tag('toggle_check.png'),
8 <%= check_box_tag 'check_all', '', false, :class => 'toggle-selection',
9 {},
10 :onclick => 'toggleIssuesSelection(this); return false;',
11 :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
9 :title => "#{l(:button_check_all)}/#{l(:button_uncheck_all)}" %>
12 </th>
10 </th>
13 <% @query.inline_columns.each do |column| %>
11 <% @query.inline_columns.each do |column| %>
14 <%= column_header(column) %>
12 <%= column_header(column) %>
15 <% end %>
13 <% end %>
16 <th></th>
14 <th></th>
17 </tr>
15 </tr>
18 </thead>
16 </thead>
19 <tbody>
17 <tbody>
20 <% entries.each do |entry| -%>
18 <% entries.each do |entry| -%>
21 <tr class="time-entry <%= cycle("odd", "even") %> hascontextmenu">
19 <tr class="time-entry <%= cycle("odd", "even") %> hascontextmenu">
22 <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", entry.id, false, :id => nil) %></td>
20 <td class="checkbox hide-when-print"><%= check_box_tag("ids[]", entry.id, false, :id => nil) %></td>
23 <%= raw @query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, entry)}</td>"}.join %>
21 <%= raw @query.inline_columns.map {|column| "<td class=\"#{column.css_classes}\">#{column_content(column, entry)}</td>"}.join %>
24 <td class="buttons">
22 <td class="buttons">
25 <% if entry.editable_by?(User.current) -%>
23 <% if entry.editable_by?(User.current) -%>
26 <%= link_to image_tag('edit.png'), edit_time_entry_path(entry),
24 <%= link_to image_tag('edit.png'), edit_time_entry_path(entry),
27 :title => l(:button_edit) %>
25 :title => l(:button_edit) %>
28 <%= link_to image_tag('delete.png'), time_entry_path(entry),
26 <%= link_to image_tag('delete.png'), time_entry_path(entry),
29 :data => {:confirm => l(:text_are_you_sure)},
27 :data => {:confirm => l(:text_are_you_sure)},
30 :method => :delete,
28 :method => :delete,
31 :title => l(:button_delete) %>
29 :title => l(:button_delete) %>
32 <% end -%>
30 <% end -%>
33 </td>
31 </td>
34 </tr>
32 </tr>
35 <% end -%>
33 <% end -%>
36 </tbody>
34 </tbody>
37 </table>
35 </table>
38 </div>
36 </div>
39 <% end -%>
37 <% end -%>
40
38
41 <%= context_menu time_entries_context_menu_path %>
39 <%= context_menu time_entries_context_menu_path %>
@@ -1,239 +1,237
1 /* Redmine - project management software
1 /* Redmine - project management software
2 Copyright (C) 2006-2015 Jean-Philippe Lang */
2 Copyright (C) 2006-2015 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')) {
71 // nop
70 } else {
72 } else {
71 contextMenuUnselectAll();
73 contextMenuUnselectAll();
72 }
74 }
73 }
75 }
74 }
76 }
75 }
77 }
76
78
77 function contextMenuCreate() {
79 function contextMenuCreate() {
78 if ($('#context-menu').length < 1) {
80 if ($('#context-menu').length < 1) {
79 var menu = document.createElement("div");
81 var menu = document.createElement("div");
80 menu.setAttribute("id", "context-menu");
82 menu.setAttribute("id", "context-menu");
81 menu.setAttribute("style", "display:none;");
83 menu.setAttribute("style", "display:none;");
82 document.getElementById("content").appendChild(menu);
84 document.getElementById("content").appendChild(menu);
83 }
85 }
84 }
86 }
85
87
86 function contextMenuShow(event) {
88 function contextMenuShow(event) {
87 var mouse_x = event.pageX;
89 var mouse_x = event.pageX;
88 var mouse_y = event.pageY;
90 var mouse_y = event.pageY;
89 var render_x = mouse_x;
91 var render_x = mouse_x;
90 var render_y = mouse_y;
92 var render_y = mouse_y;
91 var dims;
93 var dims;
92 var menu_width;
94 var menu_width;
93 var menu_height;
95 var menu_height;
94 var window_width;
96 var window_width;
95 var window_height;
97 var window_height;
96 var max_width;
98 var max_width;
97 var max_height;
99 var max_height;
98
100
99 $('#context-menu').css('left', (render_x + 'px'));
101 $('#context-menu').css('left', (render_x + 'px'));
100 $('#context-menu').css('top', (render_y + 'px'));
102 $('#context-menu').css('top', (render_y + 'px'));
101 $('#context-menu').html('');
103 $('#context-menu').html('');
102
104
103 $.ajax({
105 $.ajax({
104 url: contextMenuUrl,
106 url: contextMenuUrl,
105 data: $(event.target).parents('form').first().serialize(),
107 data: $(event.target).parents('form').first().serialize(),
106 success: function(data, textStatus, jqXHR) {
108 success: function(data, textStatus, jqXHR) {
107 $('#context-menu').html(data);
109 $('#context-menu').html(data);
108 menu_width = $('#context-menu').width();
110 menu_width = $('#context-menu').width();
109 menu_height = $('#context-menu').height();
111 menu_height = $('#context-menu').height();
110 max_width = mouse_x + 2*menu_width;
112 max_width = mouse_x + 2*menu_width;
111 max_height = mouse_y + menu_height;
113 max_height = mouse_y + menu_height;
112
114
113 var ws = window_size();
115 var ws = window_size();
114 window_width = ws.width;
116 window_width = ws.width;
115 window_height = ws.height;
117 window_height = ws.height;
116
118
117 /* display the menu above and/or to the left of the click if needed */
119 /* display the menu above and/or to the left of the click if needed */
118 if (max_width > window_width) {
120 if (max_width > window_width) {
119 render_x -= menu_width;
121 render_x -= menu_width;
120 $('#context-menu').addClass('reverse-x');
122 $('#context-menu').addClass('reverse-x');
121 } else {
123 } else {
122 $('#context-menu').removeClass('reverse-x');
124 $('#context-menu').removeClass('reverse-x');
123 }
125 }
124 if (max_height > window_height) {
126 if (max_height > window_height) {
125 render_y -= menu_height;
127 render_y -= menu_height;
126 $('#context-menu').addClass('reverse-y');
128 $('#context-menu').addClass('reverse-y');
127 } else {
129 } else {
128 $('#context-menu').removeClass('reverse-y');
130 $('#context-menu').removeClass('reverse-y');
129 }
131 }
130 if (render_x <= 0) render_x = 1;
132 if (render_x <= 0) render_x = 1;
131 if (render_y <= 0) render_y = 1;
133 if (render_y <= 0) render_y = 1;
132 $('#context-menu').css('left', (render_x + 'px'));
134 $('#context-menu').css('left', (render_x + 'px'));
133 $('#context-menu').css('top', (render_y + 'px'));
135 $('#context-menu').css('top', (render_y + 'px'));
134 $('#context-menu').show();
136 $('#context-menu').show();
135
137
136 //if (window.parseStylesheets) { window.parseStylesheets(); } // IE
138 //if (window.parseStylesheets) { window.parseStylesheets(); } // IE
137
139
138 }
140 }
139 });
141 });
140 }
142 }
141
143
142 function contextMenuSetLastSelected(tr) {
144 function contextMenuSetLastSelected(tr) {
143 $('.cm-last').removeClass('cm-last');
145 $('.cm-last').removeClass('cm-last');
144 tr.addClass('cm-last');
146 tr.addClass('cm-last');
145 }
147 }
146
148
147 function contextMenuLastSelected() {
149 function contextMenuLastSelected() {
148 return $('.cm-last').first();
150 return $('.cm-last').first();
149 }
151 }
150
152
151 function contextMenuUnselectAll() {
153 function contextMenuUnselectAll() {
154 $('input[type=checkbox].toggle-selection').prop('checked', false);
152 $('.hascontextmenu').each(function(){
155 $('.hascontextmenu').each(function(){
153 contextMenuRemoveSelection($(this));
156 contextMenuRemoveSelection($(this));
154 });
157 });
155 $('.cm-last').removeClass('cm-last');
158 $('.cm-last').removeClass('cm-last');
156 }
159 }
157
160
158 function contextMenuHide() {
161 function contextMenuHide() {
159 $('#context-menu').hide();
162 $('#context-menu').hide();
160 }
163 }
161
164
162 function contextMenuToggleSelection(tr) {
165 function contextMenuToggleSelection(tr) {
163 if (contextMenuIsSelected(tr)) {
166 if (contextMenuIsSelected(tr)) {
164 contextMenuRemoveSelection(tr);
167 contextMenuRemoveSelection(tr);
165 } else {
168 } else {
166 contextMenuAddSelection(tr);
169 contextMenuAddSelection(tr);
167 }
170 }
168 }
171 }
169
172
170 function contextMenuAddSelection(tr) {
173 function contextMenuAddSelection(tr) {
171 tr.addClass('context-menu-selection');
174 tr.addClass('context-menu-selection');
172 contextMenuCheckSelectionBox(tr, true);
175 contextMenuCheckSelectionBox(tr, true);
173 contextMenuClearDocumentSelection();
176 contextMenuClearDocumentSelection();
174 }
177 }
175
178
176 function contextMenuRemoveSelection(tr) {
179 function contextMenuRemoveSelection(tr) {
177 tr.removeClass('context-menu-selection');
180 tr.removeClass('context-menu-selection');
178 contextMenuCheckSelectionBox(tr, false);
181 contextMenuCheckSelectionBox(tr, false);
179 }
182 }
180
183
181 function contextMenuIsSelected(tr) {
184 function contextMenuIsSelected(tr) {
182 return tr.hasClass('context-menu-selection');
185 return tr.hasClass('context-menu-selection');
183 }
186 }
184
187
185 function contextMenuCheckSelectionBox(tr, checked) {
188 function contextMenuCheckSelectionBox(tr, checked) {
186 tr.find('input[type=checkbox]').prop('checked', checked);
189 tr.find('input[type=checkbox]').prop('checked', checked);
187 }
190 }
188
191
189 function contextMenuClearDocumentSelection() {
192 function contextMenuClearDocumentSelection() {
190 // TODO
193 // TODO
191 if (document.selection) {
194 if (document.selection) {
192 document.selection.empty(); // IE
195 document.selection.empty(); // IE
193 } else {
196 } else {
194 window.getSelection().removeAllRanges();
197 window.getSelection().removeAllRanges();
195 }
198 }
196 }
199 }
197
200
198 function contextMenuInit(url) {
201 function contextMenuInit(url) {
199 contextMenuUrl = url;
202 contextMenuUrl = url;
200 contextMenuCreate();
203 contextMenuCreate();
201 contextMenuUnselectAll();
204 contextMenuUnselectAll();
202
205
203 if (!contextMenuObserving) {
206 if (!contextMenuObserving) {
204 $(document).click(contextMenuClick);
207 $(document).click(contextMenuClick);
205 $(document).contextmenu(contextMenuRightClick);
208 $(document).contextmenu(contextMenuRightClick);
206 contextMenuObserving = true;
209 contextMenuObserving = true;
207 }
210 }
208 }
211 }
209
212
210 function toggleIssuesSelection(el) {
213 function toggleIssuesSelection(el) {
211 var boxes = $(el).parents('form').find('input[type=checkbox]');
214 var checked = $(this).prop('checked');
212 var all_checked = true;
215 var boxes = $(this).parents('table').find('input[name=ids\\[\\]]');
213 boxes.each(function(){ if (!$(this).prop('checked')) { all_checked = false; } });
216 boxes.prop('checked', checked).parents('tr').toggleClass('context-menu-selection', checked);
214 boxes.each(function(){
215 if (all_checked) {
216 $(this).removeAttr('checked');
217 $(this).parents('tr').removeClass('context-menu-selection');
218 } else if (!$(this).prop('checked')) {
219 $(this).prop('checked', true);
220 $(this).parents('tr').addClass('context-menu-selection');
221 }
222 });
223 }
217 }
224
218
225 function window_size() {
219 function window_size() {
226 var w;
220 var w;
227 var h;
221 var h;
228 if (window.innerWidth) {
222 if (window.innerWidth) {
229 w = window.innerWidth;
223 w = window.innerWidth;
230 h = window.innerHeight;
224 h = window.innerHeight;
231 } else if (document.documentElement) {
225 } else if (document.documentElement) {
232 w = document.documentElement.clientWidth;
226 w = document.documentElement.clientWidth;
233 h = document.documentElement.clientHeight;
227 h = document.documentElement.clientHeight;
234 } else {
228 } else {
235 w = document.body.clientWidth;
229 w = document.body.clientWidth;
236 h = document.body.clientHeight;
230 h = document.body.clientHeight;
237 }
231 }
238 return {width: w, height: h};
232 return {width: w, height: h};
239 }
233 }
234
235 $(document).ready(function(){
236 $('input[type=checkbox].toggle-selection').on('change', toggleIssuesSelection);
237 });
General Comments 0
You need to be logged in to leave comments. Login now