UNPKG

11.8 kBJavaScriptView Raw
1(function ($) {
2 // register namespace
3 $.extend(true, window, {
4 "Slick": {
5 "CheckboxSelectColumn": CheckboxSelectColumn
6 }
7 });
8
9
10 function CheckboxSelectColumn(options) {
11 var _grid;
12 var _selectableOverride = null;
13 var _selectAll_UID = createUID();
14 var _handler = new Slick.EventHandler();
15 var _selectedRowsLookup = {};
16 var _defaults = {
17 columnId: "_checkbox_selector",
18 cssClass: null,
19 hideSelectAllCheckbox: false,
20 toolTip: "Select/Deselect All",
21 width: 30,
22 hideInColumnTitleRow: false,
23 hideInFilterHeaderRow: true
24 };
25 var _isSelectAllChecked = false;
26
27 var _options = $.extend(true, {}, _defaults, options);
28
29 // user could override the checkbox icon logic from within the options or after instantiating the plugin
30 if (typeof _options.selectableOverride === 'function') {
31 selectableOverride(_options.selectableOverride);
32 }
33
34 function init(grid) {
35 _grid = grid;
36 _handler
37 .subscribe(_grid.onSelectedRowsChanged, handleSelectedRowsChanged)
38 .subscribe(_grid.onClick, handleClick)
39 .subscribe(_grid.onKeyDown, handleKeyDown);
40
41 if (!_options.hideInFilterHeaderRow) {
42 addCheckboxToFilterHeaderRow(grid);
43 }
44 if (!_options.hideInColumnTitleRow) {
45 _handler.subscribe(_grid.onHeaderClick, handleHeaderClick);
46 }
47 }
48
49 function destroy() {
50 _handler.unsubscribeAll();
51 }
52
53 function getOptions() {
54 return _options;
55 }
56
57 function setOptions(options) {
58 _options = $.extend(true, {}, _options, options);
59
60 if (_options.hideSelectAllCheckbox) {
61 hideSelectAllFromColumnHeaderTitleRow();
62 hideSelectAllFromColumnHeaderFilterRow();
63 } else {
64 if (!_options.hideInColumnTitleRow) {
65 renderSelectAllCheckbox(_isSelectAllChecked);
66 _handler.subscribe(_grid.onHeaderClick, handleHeaderClick);
67 } else {
68 hideSelectAllFromColumnHeaderTitleRow();
69 }
70
71 if (!_options.hideInFilterHeaderRow) {
72 var selectAllContainer = $("#filter-checkbox-selectall-container");
73 selectAllContainer.show();
74 selectAllContainer.find('input[type="checkbox"]').prop("checked", _isSelectAllChecked);
75 } else {
76 hideSelectAllFromColumnHeaderFilterRow();
77 }
78 }
79 }
80
81 function hideSelectAllFromColumnHeaderTitleRow() {
82 _grid.updateColumnHeader(_options.columnId, "", "");
83 }
84
85 function hideSelectAllFromColumnHeaderFilterRow() {
86 $("#filter-checkbox-selectall-container").hide();
87 }
88
89 function handleSelectedRowsChanged(e, args) {
90 var selectedRows = _grid.getSelectedRows();
91 var lookup = {}, row, i, k;
92 var disabledCount = 0;
93 if (typeof _selectableOverride === 'function') {
94 for (k = 0; k < _grid.getDataLength(); k++) {
95 // If we are allowed to select the row
96 var dataItem = _grid.getDataItem(k);
97 if (!checkSelectableOverride(i, dataItem, _grid)) {
98 disabledCount++;
99 }
100 }
101 }
102
103 var removeList = [];
104 for (i = 0; i < selectedRows.length; i++) {
105 row = selectedRows[i];
106
107 // If we are allowed to select the row
108 var rowItem = _grid.getDataItem(row);
109 if (checkSelectableOverride(i, rowItem, _grid)) {
110 lookup[row] = true;
111 if (lookup[row] !== _selectedRowsLookup[row]) {
112 _grid.invalidateRow(row);
113 delete _selectedRowsLookup[row];
114 }
115 }
116 else {
117 removeList.push(row);
118 }
119 }
120 for (i in _selectedRowsLookup) {
121 _grid.invalidateRow(i);
122 }
123 _selectedRowsLookup = lookup;
124 _grid.render();
125 _isSelectAllChecked = selectedRows.length && selectedRows.length + disabledCount >= _grid.getDataLength();
126
127 if (!_options.hideInColumnTitleRow && !_options.hideSelectAllCheckbox) {
128 renderSelectAllCheckbox(_isSelectAllChecked);
129 }
130 if (!_options.hideInFilterHeaderRow) {
131 var selectAllElm = $("#header-filter-selector" + _selectAll_UID);
132 selectAllElm.prop("checked", _isSelectAllChecked);
133 }
134 // Remove items that shouln't of been selected in the first place (Got here Ctrl + click)
135 if (removeList.length > 0) {
136 for (i = 0; i < removeList.length; i++) {
137 var remIdx = selectedRows.indexOf(removeList[i]);
138 selectedRows.splice(remIdx, 1);
139 }
140 _grid.setSelectedRows(selectedRows);
141 }
142 }
143
144 function handleKeyDown(e, args) {
145 if (e.which == 32) {
146 if (_grid.getColumns()[args.cell].id === _options.columnId) {
147 // if editing, try to commit
148 if (!_grid.getEditorLock().isActive() || _grid.getEditorLock().commitCurrentEdit()) {
149 toggleRowSelection(args.row);
150 }
151 e.preventDefault();
152 e.stopImmediatePropagation();
153 }
154 }
155 }
156
157 function handleClick(e, args) {
158 // clicking on a row select checkbox
159 if (_grid.getColumns()[args.cell].id === _options.columnId && $(e.target).is(":checkbox")) {
160 // if editing, try to commit
161 if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()) {
162 e.preventDefault();
163 e.stopImmediatePropagation();
164 return;
165 }
166
167 toggleRowSelection(args.row);
168 e.stopPropagation();
169 e.stopImmediatePropagation();
170 }
171 }
172
173 function toggleRowSelection(row) {
174 var dataContext = _grid.getDataItem(row);
175 if (!checkSelectableOverride(row, dataContext, _grid)) {
176 return;
177 }
178
179 if (_selectedRowsLookup[row]) {
180 _grid.setSelectedRows($.grep(_grid.getSelectedRows(), function (n) {
181 return n != row;
182 }));
183 } else {
184 _grid.setSelectedRows(_grid.getSelectedRows().concat(row));
185 }
186 _grid.setActiveCell(row, getCheckboxColumnCellIndex());
187 }
188
189 function selectRows(rowArray) {
190 var i, l = rowArray.length, addRows = [];
191 for (i = 0; i < l; i++) {
192 if (!_selectedRowsLookup[rowArray[i]]) {
193 addRows[addRows.length] = rowArray[i];
194 }
195 }
196 _grid.setSelectedRows(_grid.getSelectedRows().concat(addRows));
197 }
198
199 function deSelectRows(rowArray) {
200 var i, l = rowArray.length, removeRows = [];
201 for (i = 0; i < l; i++) {
202 if (_selectedRowsLookup[rowArray[i]]) {
203 removeRows[removeRows.length] = rowArray[i];
204 }
205 }
206 _grid.setSelectedRows($.grep(_grid.getSelectedRows(), function (n) {
207 return removeRows.indexOf(n) < 0;
208 }));
209 }
210
211 function handleHeaderClick(e, args) {
212 if (args.column.id == _options.columnId && $(e.target).is(":checkbox")) {
213 // if editing, try to commit
214 if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()) {
215 e.preventDefault();
216 e.stopImmediatePropagation();
217 return;
218 }
219
220 if ($(e.target).is(":checked")) {
221 var rows = [];
222 for (var i = 0; i < _grid.getDataLength(); i++) {
223 // Get the row and check it's a selectable row before pushing it onto the stack
224 var rowItem = _grid.getDataItem(i);
225 if (checkSelectableOverride(i, rowItem, _grid)) {
226 rows.push(i);
227 }
228 }
229 _grid.setSelectedRows(rows);
230 } else {
231 _grid.setSelectedRows([]);
232 }
233 e.stopPropagation();
234 e.stopImmediatePropagation();
235 }
236 }
237
238 var _checkboxColumnCellIndex = null;
239
240 function getCheckboxColumnCellIndex() {
241 if (_checkboxColumnCellIndex === null) {
242 _checkboxColumnCellIndex = 0;
243 var colArr = _grid.getColumns();
244 for (var i = 0; i < colArr.length; i++) {
245 if (colArr[i].id == _options.columnId) {
246 _checkboxColumnCellIndex = i;
247 }
248 }
249 }
250 return _checkboxColumnCellIndex;
251 }
252
253 function getColumnDefinition() {
254 return {
255 id: _options.columnId,
256 name: (_options.hideSelectAllCheckbox || _options.hideInColumnTitleRow) ? "" : "<input id='header-selector" + _selectAll_UID + "' type='checkbox'><label for='header-selector" + _selectAll_UID + "'></label>",
257 toolTip: (_options.hideSelectAllCheckbox || _options.hideInColumnTitleRow) ? "" : _options.toolTip,
258 field: "sel",
259 width: _options.width,
260 resizable: false,
261 sortable: false,
262 cssClass: _options.cssClass,
263 hideSelectAllCheckbox: _options.hideSelectAllCheckbox,
264 formatter: checkboxSelectionFormatter
265 };
266 }
267
268 function addCheckboxToFilterHeaderRow(grid) {
269 _handler.subscribe(grid.onHeaderRowCellRendered, function (e, args) {
270 if (args.column.field === "sel") {
271 $(args.node).empty();
272 $("<span id='filter-checkbox-selectall-container'><input id='header-filter-selector" + _selectAll_UID + "' type='checkbox'><label for='header-filter-selector" + _selectAll_UID + "'></label></span>")
273 .appendTo(args.node)
274 .on('click', function (evnt) {
275 handleHeaderClick(evnt, args);
276 });
277 }
278 });
279 }
280
281 function createUID() {
282 return Math.round(10000000 * Math.random());
283 }
284
285 function checkboxSelectionFormatter(row, cell, value, columnDef, dataContext, grid) {
286 var UID = createUID() + row;
287
288 if (dataContext) {
289 if (!checkSelectableOverride(row, dataContext, grid)) {
290 return null;
291 } else {
292 return _selectedRowsLookup[row]
293 ? "<input id='selector" + UID + "' type='checkbox' checked='checked'><label for='selector" + UID + "'></label>"
294 : "<input id='selector" + UID + "' type='checkbox'><label for='selector" + UID + "'></label>";
295 }
296 }
297 return null;
298 }
299
300 function checkSelectableOverride(row, dataContext, grid) {
301 if (typeof _selectableOverride === 'function') {
302 return _selectableOverride(row, dataContext, grid);
303 }
304 return true;
305 }
306
307 function renderSelectAllCheckbox(isSelectAllChecked) {
308 if (isSelectAllChecked) {
309 _grid.updateColumnHeader(_options.columnId, "<input id='header-selector" + _selectAll_UID + "' type='checkbox' checked='checked'><label for='header-selector" + _selectAll_UID + "'></label>", _options.toolTip);
310 } else {
311 _grid.updateColumnHeader(_options.columnId, "<input id='header-selector" + _selectAll_UID + "' type='checkbox'><label for='header-selector" + _selectAll_UID + "'></label>", _options.toolTip);
312 }
313 }
314
315 /**
316 * Method that user can pass to override the default behavior or making every row a selectable row.
317 * In order word, user can choose which rows to be selectable or not by providing his own logic.
318 * @param overrideFn: override function callback
319 */
320 function selectableOverride(overrideFn) {
321 _selectableOverride = overrideFn;
322 }
323
324
325 $.extend(this, {
326 "init": init,
327 "destroy": destroy,
328 "pluginName": "CheckboxSelectColumn",
329
330 "deSelectRows": deSelectRows,
331 "selectRows": selectRows,
332 "getColumnDefinition": getColumnDefinition,
333 "getOptions": getOptions,
334 "selectableOverride": selectableOverride,
335 "setOptions": setOptions,
336 });
337 }
338})(jQuery);
\No newline at end of file