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