1 | |
---|
2 | Drupal.behaviors.tableSelect = function (context) { |
---|
3 | $('form table:has(th.select-all):not(.tableSelect-processed)', context).each(Drupal.tableSelect); |
---|
4 | }; |
---|
5 | |
---|
6 | Drupal.tableSelect = function() { |
---|
7 | // Do not add a "Select all" checkbox if there are no rows with checkboxes in the table |
---|
8 | if ($('td input:checkbox', this).size() == 0) { |
---|
9 | return; |
---|
10 | } |
---|
11 | |
---|
12 | // Keep track of the table, which checkbox is checked and alias the settings. |
---|
13 | var table = this, checkboxes, lastChecked; |
---|
14 | var strings = { 'selectAll': Drupal.t('Select all rows in this table'), 'selectNone': Drupal.t('Deselect all rows in this table') }; |
---|
15 | var updateSelectAll = function(state) { |
---|
16 | $('th.select-all input:checkbox', table).each(function() { |
---|
17 | $(this).attr('title', state ? strings.selectNone : strings.selectAll); |
---|
18 | this.checked = state; |
---|
19 | }); |
---|
20 | }; |
---|
21 | |
---|
22 | // Find all <th> with class select-all, and insert the check all checkbox. |
---|
23 | $('th.select-all', table).prepend($('<input type="checkbox" class="form-checkbox" />').attr('title', strings.selectAll)).click(function(event) { |
---|
24 | if ($(event.target).is('input:checkbox')) { |
---|
25 | // Loop through all checkboxes and set their state to the select all checkbox' state. |
---|
26 | checkboxes.each(function() { |
---|
27 | this.checked = event.target.checked; |
---|
28 | // Either add or remove the selected class based on the state of the check all checkbox. |
---|
29 | $(this).parents('tr:first')[ this.checked ? 'addClass' : 'removeClass' ]('selected'); |
---|
30 | }); |
---|
31 | // Update the title and the state of the check all box. |
---|
32 | updateSelectAll(event.target.checked); |
---|
33 | } |
---|
34 | }); |
---|
35 | |
---|
36 | // For each of the checkboxes within the table. |
---|
37 | checkboxes = $('td input:checkbox', table).click(function(e) { |
---|
38 | // Either add or remove the selected class based on the state of the check all checkbox. |
---|
39 | $(this).parents('tr:first')[ this.checked ? 'addClass' : 'removeClass' ]('selected'); |
---|
40 | |
---|
41 | // If this is a shift click, we need to highlight everything in the range. |
---|
42 | // Also make sure that we are actually checking checkboxes over a range and |
---|
43 | // that a checkbox has been checked or unchecked before. |
---|
44 | if (e.shiftKey && lastChecked && lastChecked != e.target) { |
---|
45 | // We use the checkbox's parent TR to do our range searching. |
---|
46 | Drupal.tableSelectRange($(e.target).parents('tr')[0], $(lastChecked).parents('tr')[0], e.target.checked); |
---|
47 | } |
---|
48 | |
---|
49 | // If all checkboxes are checked, make sure the select-all one is checked too, otherwise keep unchecked. |
---|
50 | updateSelectAll((checkboxes.length == $(checkboxes).filter(':checked').length)); |
---|
51 | |
---|
52 | // Keep track of the last checked checkbox. |
---|
53 | lastChecked = e.target; |
---|
54 | }); |
---|
55 | $(this).addClass('tableSelect-processed'); |
---|
56 | }; |
---|
57 | |
---|
58 | Drupal.tableSelectRange = function(from, to, state) { |
---|
59 | // We determine the looping mode based on the order of from and to. |
---|
60 | var mode = from.rowIndex > to.rowIndex ? 'previousSibling' : 'nextSibling'; |
---|
61 | |
---|
62 | // Traverse through the sibling nodes. |
---|
63 | for (var i = from[mode]; i; i = i[mode]) { |
---|
64 | // Make sure that we're only dealing with elements. |
---|
65 | if (i.nodeType != 1) { |
---|
66 | continue; |
---|
67 | } |
---|
68 | |
---|
69 | // Either add or remove the selected class based on the state of the target checkbox. |
---|
70 | $(i)[ state ? 'addClass' : 'removeClass' ]('selected'); |
---|
71 | $('input:checkbox', i).each(function() { |
---|
72 | this.checked = state; |
---|
73 | }); |
---|
74 | |
---|
75 | if (to.nodeType) { |
---|
76 | // If we are at the end of the range, stop. |
---|
77 | if (i == to) { |
---|
78 | break; |
---|
79 | } |
---|
80 | } |
---|
81 | // A faster alternative to doing $(i).filter(to).length. |
---|
82 | else if (jQuery.filter(to, [i]).r.length) { |
---|
83 | break; |
---|
84 | } |
---|
85 | } |
---|
86 | }; |
---|