(function ($) { // register namespace $.extend(true, window, { "Slick": { "CheckboxSelectColumn": CheckboxSelectColumn } }); function CheckboxSelectColumn(options) { var _grid; var _selectableOverride = null; var _selectAll_UID = createUID(); var _handler = new Slick.EventHandler(); var _selectedRowsLookup = {}; var _defaults = { columnId: "_checkbox_selector", cssClass: null, hideSelectAllCheckbox: false, toolTip: "Select/Deselect All", width: 30, hideInColumnTitleRow: false, hideInFilterHeaderRow: true }; var _isSelectAllChecked = false; var _options = $.extend(true, {}, _defaults, options); function init(grid) { _grid = grid; _handler .subscribe(_grid.onSelectedRowsChanged, handleSelectedRowsChanged) .subscribe(_grid.onClick, handleClick) .subscribe(_grid.onKeyDown, handleKeyDown); if (!_options.hideInFilterHeaderRow) { addCheckboxToFilterHeaderRow(grid); } if (!_options.hideInColumnTitleRow) { _handler.subscribe(_grid.onHeaderClick, handleHeaderClick) } } function destroy() { _handler.unsubscribeAll(); } function getOptions() { return _options; } function setOptions(options) { _options = $.extend(true, {}, _options, options); if (_options.hideSelectAllCheckbox) { hideSelectAllFromColumnHeaderTitleRow(); hideSelectAllFromColumnHeaderFilterRow(); } else { if (!_options.hideInColumnTitleRow) { renderSelectAllCheckbox(_isSelectAllChecked); _handler.subscribe(_grid.onHeaderClick, handleHeaderClick); } else { hideSelectAllFromColumnHeaderTitleRow(); } if (!_options.hideInFilterHeaderRow) { var selectAllContainer = $("#filter-checkbox-selectall-container"); selectAllContainer.show(); selectAllContainer.find('input[type="checkbox"]').prop("checked", _isSelectAllChecked); } else { hideSelectAllFromColumnHeaderFilterRow(); } } } function hideSelectAllFromColumnHeaderTitleRow() { _grid.updateColumnHeader(_options.columnId, "", ""); } function hideSelectAllFromColumnHeaderFilterRow() { $("#filter-checkbox-selectall-container").hide(); } function handleSelectedRowsChanged(e, args) { var selectedRows = _grid.getSelectedRows(); var lookup = {}, row, i; var disabledCount = 0; if (typeof _selectableOverride === 'function') { for (k = 0; k < _grid.getDataLength(); k++) { // If we are allowed to select the row var dataItem = _grid.getDataItem(k); if (!checkSelectableOverride(i, dataItem, _grid)) { disabledCount++; } } } var removeList = []; for (i = 0; i < selectedRows.length; i++) { row = selectedRows[i]; // If we are allowed to select the row var rowItem = _grid.getDataItem(row); if (checkSelectableOverride(i, rowItem, _grid)) { lookup[row] = true; if (lookup[row] !== _selectedRowsLookup[row]) { _grid.invalidateRow(row); delete _selectedRowsLookup[row]; } } else { removeList.push(row); } } for (i in _selectedRowsLookup) { _grid.invalidateRow(i); } _selectedRowsLookup = lookup; _grid.render(); _isSelectAllChecked = selectedRows.length && selectedRows.length + disabledCount >= _grid.getDataLength(); if (!_options.hideInColumnTitleRow && !_options.hideSelectAllCheckbox) { renderSelectAllCheckbox(_isSelectAllChecked); } if (!_options.hideInFilterHeaderRow) { var selectAllElm = $("#header-filter-selector" + _selectAll_UID); selectAllElm.prop("checked", _isSelectAllChecked); } // Remove items that shouln't of been selected in the first place (Got here Ctrl + click) if (removeList.length > 0) { for (i = 0; i < removeList.length; i++) { var remIdx = selectedRows.indexOf(removeList[i]); selectedRows.splice(remIdx, 1); } _grid.setSelectedRows(selectedRows); } } function handleKeyDown(e, args) { if (e.which == 32) { if (_grid.getColumns()[args.cell].id === _options.columnId) { // if editing, try to commit if (!_grid.getEditorLock().isActive() || _grid.getEditorLock().commitCurrentEdit()) { toggleRowSelection(args.row); } e.preventDefault(); e.stopImmediatePropagation(); } } } function handleClick(e, args) { // clicking on a row select checkbox if (_grid.getColumns()[args.cell].id === _options.columnId && $(e.target).is(":checkbox")) { // if editing, try to commit if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()) { e.preventDefault(); e.stopImmediatePropagation(); return; } toggleRowSelection(args.row); e.stopPropagation(); e.stopImmediatePropagation(); } } function toggleRowSelection(row) { var dataContext = _grid.getDataItem(row); if (!checkSelectableOverride(row, dataContext, _grid)) { return; } if (_selectedRowsLookup[row]) { _grid.setSelectedRows($.grep(_grid.getSelectedRows(), function (n) { return n != row })); } else { _grid.setSelectedRows(_grid.getSelectedRows().concat(row)); } _grid.setActiveCell(row, getCheckboxColumnCellIndex()); } function selectRows(rowArray) { var i, l = rowArray.length, addRows = []; for (i = 0; i < l; i++) { if (!_selectedRowsLookup[rowArray[i]]) { addRows[addRows.length] = rowArray[i]; } } _grid.setSelectedRows(_grid.getSelectedRows().concat(addRows)); } function deSelectRows(rowArray) { var i, l = rowArray.length, removeRows = []; for (i = 0; i < l; i++) { if (_selectedRowsLookup[rowArray[i]]) { removeRows[removeRows.length] = rowArray[i]; } } _grid.setSelectedRows($.grep(_grid.getSelectedRows(), function (n) { return removeRows.indexOf(n) < 0 })); } function handleHeaderClick(e, args) { if (args.column.id == _options.columnId && $(e.target).is(":checkbox")) { // if editing, try to commit if (_grid.getEditorLock().isActive() && !_grid.getEditorLock().commitCurrentEdit()) { e.preventDefault(); e.stopImmediatePropagation(); return; } if ($(e.target).is(":checked")) { var rows = []; for (var i = 0; i < _grid.getDataLength(); i++) { // Get the row and check it's a selectable row before pushing it onto the stack var rowItem = _grid.getDataItem(i); if (rowItem.selectableRow !== false) { rows.push(i); } } _grid.setSelectedRows(rows); } else { _grid.setSelectedRows([]); } e.stopPropagation(); e.stopImmediatePropagation(); } } var _checkboxColumnCellIndex = null; function getCheckboxColumnCellIndex() { if (_checkboxColumnCellIndex === null) { _checkboxColumnCellIndex = 0; var colArr = _grid.getColumns(); for (var i = 0; i < colArr.length; i++) { if (colArr[i].id == _options.columnId) { _checkboxColumnCellIndex = i; } } } return _checkboxColumnCellIndex; } function getColumnDefinition() { return { id: _options.columnId, name: (_options.hideSelectAllCheckbox || _options.hideInColumnTitleRow) ? "" : "", toolTip: _options.toolTip, field: "sel", width: _options.width, resizable: false, sortable: false, cssClass: _options.cssClass, hideSelectAllCheckbox: _options.hideSelectAllCheckbox, formatter: checkboxSelectionFormatter }; } function addCheckboxToFilterHeaderRow(grid) { grid.onHeaderRowCellRendered.subscribe(function (e, args) { if (args.column.field === "sel") { $(args.node).empty(); $("") .appendTo(args.node) .on('click', function (evnt) { handleHeaderClick(evnt, args) }); } }); } function createUID() { return Math.round(10000000 * Math.random()); } function checkboxSelectionFormatter(row, cell, value, columnDef, dataContext, grid) { var UID = createUID() + row; if (dataContext) { if (!checkSelectableOverride(row, dataContext, grid)) { return null; } else { return _selectedRowsLookup[row] ? "" : ""; } } return null; } function checkSelectableOverride(row, dataContext, grid) { if (typeof _selectableOverride === 'function') { return _selectableOverride(row, dataContext, grid); } return true; } function renderSelectAllCheckbox(isSelectAllChecked) { if (isSelectAllChecked) { _grid.updateColumnHeader(_options.columnId, "", _options.toolTip); } else { _grid.updateColumnHeader(_options.columnId, "", _options.toolTip); } } /** * Method that user can pass to override the default behavior or making every row a selectable row. * In order word, user can choose which rows to be selectable or not by providing his own logic. * @param overrideFn: override function callback */ function selectableOverride(overrideFn) { _selectableOverride = overrideFn; } $.extend(this, { "init": init, "destroy": destroy, "pluginName": "CheckboxSelectColumn", "deSelectRows": deSelectRows, "selectRows": selectRows, "getColumnDefinition": getColumnDefinition, "getOptions": getOptions, "selectableOverride": selectableOverride, "setOptions": setOptions, }); } })(jQuery);