Mercurial > hg > cmmr2012-drupal-site
comparison core/misc/tableselect.es6.js @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children | a9cd425dd02b |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c75dbcec494b |
---|---|
1 /** | |
2 * @file | |
3 * Table select functionality. | |
4 */ | |
5 | |
6 (function ($, Drupal) { | |
7 /** | |
8 * Initialize tableSelects. | |
9 * | |
10 * @type {Drupal~behavior} | |
11 * | |
12 * @prop {Drupal~behaviorAttach} attach | |
13 * Attaches tableSelect functionality. | |
14 */ | |
15 Drupal.behaviors.tableSelect = { | |
16 attach(context, settings) { | |
17 // Select the inner-most table in case of nested tables. | |
18 $(context) | |
19 .find('th.select-all') | |
20 .closest('table') | |
21 .once('table-select') | |
22 .each(Drupal.tableSelect); | |
23 }, | |
24 }; | |
25 | |
26 /** | |
27 * Callback used in {@link Drupal.behaviors.tableSelect}. | |
28 */ | |
29 Drupal.tableSelect = function () { | |
30 // Do not add a "Select all" checkbox if there are no rows with checkboxes | |
31 // in the table. | |
32 if ($(this).find('td input[type="checkbox"]').length === 0) { | |
33 return; | |
34 } | |
35 | |
36 // Keep track of the table, which checkbox is checked and alias the | |
37 // settings. | |
38 const table = this; | |
39 let checkboxes; | |
40 let lastChecked; | |
41 const $table = $(table); | |
42 const strings = { | |
43 selectAll: Drupal.t('Select all rows in this table'), | |
44 selectNone: Drupal.t('Deselect all rows in this table'), | |
45 }; | |
46 const updateSelectAll = function (state) { | |
47 // Update table's select-all checkbox (and sticky header's if available). | |
48 $table.prev('table.sticky-header').addBack().find('th.select-all input[type="checkbox"]').each(function () { | |
49 const $checkbox = $(this); | |
50 const stateChanged = $checkbox.prop('checked') !== state; | |
51 | |
52 $checkbox.attr('title', state ? strings.selectNone : strings.selectAll); | |
53 | |
54 /** | |
55 * @checkbox {HTMLElement} | |
56 */ | |
57 if (stateChanged) { | |
58 $checkbox.prop('checked', state).trigger('change'); | |
59 } | |
60 }); | |
61 }; | |
62 | |
63 // Find all <th> with class select-all, and insert the check all checkbox. | |
64 $table.find('th.select-all').prepend($('<input type="checkbox" class="form-checkbox" />').attr('title', strings.selectAll)).on('click', (event) => { | |
65 if ($(event.target).is('input[type="checkbox"]')) { | |
66 // Loop through all checkboxes and set their state to the select all | |
67 // checkbox' state. | |
68 checkboxes.each(function () { | |
69 const $checkbox = $(this); | |
70 const stateChanged = $checkbox.prop('checked') !== event.target.checked; | |
71 | |
72 /** | |
73 * @checkbox {HTMLElement} | |
74 */ | |
75 if (stateChanged) { | |
76 $checkbox.prop('checked', event.target.checked).trigger('change'); | |
77 } | |
78 // Either add or remove the selected class based on the state of the | |
79 // check all checkbox. | |
80 | |
81 /** | |
82 * @checkbox {HTMLElement} | |
83 */ | |
84 $checkbox.closest('tr').toggleClass('selected', this.checked); | |
85 }); | |
86 // Update the title and the state of the check all box. | |
87 updateSelectAll(event.target.checked); | |
88 } | |
89 }); | |
90 | |
91 // For each of the checkboxes within the table that are not disabled. | |
92 checkboxes = $table.find('td input[type="checkbox"]:enabled').on('click', function (e) { | |
93 // Either add or remove the selected class based on the state of the | |
94 // check all checkbox. | |
95 | |
96 /** | |
97 * @this {HTMLElement} | |
98 */ | |
99 $(this).closest('tr').toggleClass('selected', this.checked); | |
100 | |
101 // If this is a shift click, we need to highlight everything in the | |
102 // range. Also make sure that we are actually checking checkboxes | |
103 // over a range and that a checkbox has been checked or unchecked before. | |
104 if (e.shiftKey && lastChecked && lastChecked !== e.target) { | |
105 // We use the checkbox's parent <tr> to do our range searching. | |
106 Drupal.tableSelectRange($(e.target).closest('tr')[0], $(lastChecked).closest('tr')[0], e.target.checked); | |
107 } | |
108 | |
109 // If all checkboxes are checked, make sure the select-all one is checked | |
110 // too, otherwise keep unchecked. | |
111 updateSelectAll((checkboxes.length === checkboxes.filter(':checked').length)); | |
112 | |
113 // Keep track of the last checked checkbox. | |
114 lastChecked = e.target; | |
115 }); | |
116 | |
117 // If all checkboxes are checked on page load, make sure the select-all one | |
118 // is checked too, otherwise keep unchecked. | |
119 updateSelectAll((checkboxes.length === checkboxes.filter(':checked').length)); | |
120 }; | |
121 | |
122 /** | |
123 * @param {HTMLElement} from | |
124 * The HTML element representing the "from" part of the range. | |
125 * @param {HTMLElement} to | |
126 * The HTML element representing the "to" part of the range. | |
127 * @param {bool} state | |
128 * The state to set on the range. | |
129 */ | |
130 Drupal.tableSelectRange = function (from, to, state) { | |
131 // We determine the looping mode based on the order of from and to. | |
132 const mode = from.rowIndex > to.rowIndex ? 'previousSibling' : 'nextSibling'; | |
133 | |
134 // Traverse through the sibling nodes. | |
135 for (let i = from[mode]; i; i = i[mode]) { | |
136 const $i = $(i); | |
137 // Make sure that we're only dealing with elements. | |
138 if (i.nodeType !== 1) { | |
139 continue; | |
140 } | |
141 // Either add or remove the selected class based on the state of the | |
142 // target checkbox. | |
143 $i.toggleClass('selected', state); | |
144 $i.find('input[type="checkbox"]').prop('checked', state); | |
145 | |
146 if (to.nodeType) { | |
147 // If we are at the end of the range, stop. | |
148 if (i === to) { | |
149 break; | |
150 } | |
151 } | |
152 // A faster alternative to doing $(i).filter(to).length. | |
153 else if ($.filter(to, [i]).r.length) { | |
154 break; | |
155 } | |
156 } | |
157 }; | |
158 }(jQuery, Drupal)); |