META-INF.resources.bower_components.datatables.net-select.js.dataTables.select.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jwebmp-data-tables Show documentation
Show all versions of jwebmp-data-tables Show documentation
The JWebSwing implementation for Data Tables
/*! Select for DataTables 1.2.7
* 2015-2018 SpryMedia Ltd - datatables.net/license/mit
*/
/**
* @summary Select for DataTables
* @description A collection of API methods, events and buttons for DataTables
* that provides selection options of the items in a DataTable
* @version 1.2.7
* @file dataTables.select.js
* @author SpryMedia Ltd (www.sprymedia.co.uk)
* @contact datatables.net/forums
* @copyright Copyright 2015-2018 SpryMedia Ltd.
*
* This source file is free software, available under the following license:
* MIT license - http://datatables.net/license/mit
*
* This source file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
*
* For details please refer to: http://www.datatables.net/extensions/select
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery', 'datatables.net'], function ($) {
return factory($, window, document);
});
}
else if (typeof exports === 'object') {
// CommonJS
module.exports = function (root, $) {
if (!root) {
root = window;
}
if (!$ || !$.fn.dataTable) {
$ = require('datatables.net')(root, $).$;
}
return factory($, root, root.document);
};
}
else {
// Browser
factory(jQuery, window, document);
}
}(function ($, window, document, undefined) {
'use strict';
var DataTable = $.fn.dataTable;
// Version information for debugger
DataTable.select = {};
DataTable.select.version = '1.2.7';
DataTable.select.init = function (dt) {
var ctx = dt.settings()[0];
var init = ctx.oInit.select;
var defaults = DataTable.defaults.select;
var opts = init === undefined ?
defaults :
init;
// Set defaults
var items = 'row';
var style = 'api';
var blurable = false;
var info = true;
var selector = 'td, th';
var className = 'selected';
var setStyle = false;
ctx._select = {};
// Initialisation customisations
if (opts === true) {
style = 'os';
setStyle = true;
}
else if (typeof opts === 'string') {
style = opts;
setStyle = true;
}
else if ($.isPlainObject(opts)) {
if (opts.blurable !== undefined) {
blurable = opts.blurable;
}
if (opts.info !== undefined) {
info = opts.info;
}
if (opts.items !== undefined) {
items = opts.items;
}
if (opts.style !== undefined) {
style = opts.style;
setStyle = true;
}
if (opts.selector !== undefined) {
selector = opts.selector;
}
if (opts.className !== undefined) {
className = opts.className;
}
}
dt.select.selector(selector);
dt.select.items(items);
dt.select.style(style);
dt.select.blurable(blurable);
dt.select.info(info);
ctx._select.className = className;
// Sort table based on selected rows. Requires Select Datatables extension
$.fn.dataTable.ext.order['select-checkbox'] = function (settings, col) {
return this.api().column(col, {order: 'index'}).nodes().map(function (td) {
if (settings._select.items === 'row') {
return $(td).parent().hasClass(settings._select.className);
} else if (settings._select.items === 'cell') {
return $(td).hasClass(settings._select.className);
}
return false;
});
};
// If the init options haven't enabled select, but there is a selectable
// class name, then enable
if (!setStyle && $(dt.table().node()).hasClass('selectable')) {
dt.select.style('os');
}
};
/*
Select is a collection of API methods, event handlers, event emitters and
buttons (for the `Buttons` extension) for DataTables. It provides the following
features, with an overview of how they are implemented:
## Selection of rows, columns and cells. Whether an item is selected or not is
stored in:
* rows: a `_select_selected` property which contains a boolean value of the
DataTables' `aoData` object for each row
* columns: a `_select_selected` property which contains a boolean value of the
DataTables' `aoColumns` object for each column
* cells: a `_selected_cells` property which contains an array of boolean values
of the `aoData` object for each row. The array is the same length as the
columns array, with each element of it representing a cell.
This method of using boolean flags allows Select to operate when nodes have not
been created for rows / cells (DataTables' defer rendering feature).
## API methods
A range of API methods are available for triggering selection and de-selection
of rows. Methods are also available to configure the selection events that can
be triggered by an end user (such as which items are to be selected). To a large
extent, these of API methods *is* Select. It is basically a collection of helper
functions that can be used to select items in a DataTable.
Configuration of select is held in the object `_select` which is attached to the
DataTables settings object on initialisation. Select being available on a table
is not optional when Select is loaded, but its default is for selection only to
be available via the API - so the end user wouldn't be able to select rows
without additional configuration.
The `_select` object contains the following properties:
```
{
items:string - Can be `rows`, `columns` or `cells`. Defines what item
will be selected if the user is allowed to activate row
selection using the mouse.
style:string - Can be `none`, `single`, `multi` or `os`. Defines the
interaction style when selecting items
blurable:boolean - If row selection can be cleared by clicking outside of
the table
info:boolean - If the selection summary should be shown in the table
information elements
}
```
In addition to the API methods, Select also extends the DataTables selector
options for rows, columns and cells adding a `selected` option to the selector
options object, allowing the developer to select only selected items or
unselected items.
## Mouse selection of items
Clicking on items can be used to select items. This is done by a simple event
handler that will select the items using the API methods.
*/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Local functions
*/
/**
* Add one or more cells to the selection when shift clicking in OS selection
* style cell selection.
*
* Cell range is more complicated than row and column as we want to select
* in the visible grid rather than by index in sequence. For example, if you
* click first in cell 1-1 and then shift click in 2-2 - cells 1-2 and 2-1
* should also be selected (and not 1-3, 1-4. etc)
*
* @param {DataTable.Api} dt DataTable
* @param {object} idx Cell index to select to
* @param {object} last Cell index to select from
* @private
*/
function cellRange(dt, idx, last) {
var indexes;
var columnIndexes;
var rowIndexes;
var selectColumns = function (start, end) {
if (start > end) {
var tmp = end;
end = start;
start = tmp;
}
var record = false;
return dt.columns(':visible').indexes().filter(function (i) {
if (i === start) {
record = true;
}
if (i === end) { // not else if, as start might === end
record = false;
return true;
}
return record;
});
};
var selectRows = function (start, end) {
var indexes = dt.rows({search: 'applied'}).indexes();
// Which comes first - might need to swap
if (indexes.indexOf(start) > indexes.indexOf(end)) {
var tmp = end;
end = start;
start = tmp;
}
var record = false;
return indexes.filter(function (i) {
if (i === start) {
record = true;
}
if (i === end) {
record = false;
return true;
}
return record;
});
};
if (!dt.cells({selected: true}).any() && !last) {
// select from the top left cell to this one
columnIndexes = selectColumns(0, idx.column);
rowIndexes = selectRows(0, idx.row);
}
else {
// Get column indexes between old and new
columnIndexes = selectColumns(last.column, idx.column);
rowIndexes = selectRows(last.row, idx.row);
}
indexes = dt.cells(rowIndexes, columnIndexes).flatten();
if (!dt.cells(idx, {selected: true}).any()) {
// Select range
dt.cells(indexes).select();
}
else {
// Deselect range
dt.cells(indexes).deselect();
}
}
/**
* Disable mouse selection by removing the selectors
*
* @param {DataTable.Api} dt DataTable to remove events from
* @private
*/
function disableMouseSelection(dt) {
var ctx = dt.settings()[0];
var selector = ctx._select.selector;
$(dt.table().container())
.off('mousedown.dtSelect', selector)
.off('mouseup.dtSelect', selector)
.off('click.dtSelect', selector);
$('body').off('click.dtSelect' + dt.table().node().id);
}
/**
* Attach mouse listeners to the table to allow mouse selection of items
*
* @param {DataTable.Api} dt DataTable to remove events from
* @private
*/
function enableMouseSelection(dt) {
var container = $(dt.table().container());
var ctx = dt.settings()[0];
var selector = ctx._select.selector;
var matchSelection;
container
.on('mousedown.dtSelect', selector, function (e) {
// Disallow text selection for shift clicking on the table so multi
// element selection doesn't look terrible!
if (e.shiftKey || e.metaKey || e.ctrlKey) {
container
.css('-moz-user-select', 'none')
.one('selectstart.dtSelect', selector, function () {
return false;
});
}
if (window.getSelection) {
matchSelection = window.getSelection();
}
})
.on('mouseup.dtSelect', selector, function () {
// Allow text selection to occur again, Mozilla style (tested in FF
// 35.0.1 - still required)
container.css('-moz-user-select', '');
})
.on('click.dtSelect', selector, function (e) {
var items = dt.select.items();
var idx;
// If text was selected (click and drag), then we shouldn't change
// the row's selected state
if (window.getSelection) {
var selection = window.getSelection();
// If the element that contains the selection is not in the table, we can ignore it
// This can happen if the developer selects text from the click event
if (!selection.anchorNode || $(selection.anchorNode).closest('table')[0] === dt.table().node()) {
if (selection !== matchSelection) {
return;
}
}
}
var ctx = dt.settings()[0];
var wrapperClass = dt.settings()[0].oClasses.sWrapper.replace(/ /g, '.');
// Ignore clicks inside a sub-table
if ($(e.target).closest('div.' + wrapperClass)[0] != dt.table().container()) {
return;
}
var cell = dt.cell($(e.target).closest('td, th'));
// Check the cell actually belongs to the host DataTable (so child
// rows, etc, are ignored)
if (!cell.any()) {
return;
}
var event = $.Event('user-select.dt');
eventTrigger(dt, event, [items, cell, e]);
if (event.isDefaultPrevented()) {
return;
}
var cellIndex = cell.index();
if (items === 'row') {
idx = cellIndex.row;
typeSelect(e, dt, ctx, 'row', idx);
}
else if (items === 'column') {
idx = cell.index().column;
typeSelect(e, dt, ctx, 'column', idx);
}
else if (items === 'cell') {
idx = cell.index();
typeSelect(e, dt, ctx, 'cell', idx);
}
ctx._select_lastCell = cellIndex;
});
// Blurable
$('body').on('click.dtSelect' + dt.table().node().id, function (e) {
if (ctx._select.blurable) {
// If the click was inside the DataTables container, don't blur
if ($(e.target).parents().filter(dt.table().container()).length) {
return;
}
// Ignore elements which have been removed from the DOM (i.e. paging
// buttons)
if ($(e.target).parents('html').length === 0) {
return;
}
// Don't blur in Editor form
if ($(e.target).parents('div.DTE').length) {
return;
}
clear(ctx, true);
}
});
}
/**
* Trigger an event on a DataTable
*
* @param {DataTable.Api} api DataTable to trigger events on
* @param {boolean} selected true if selected, false if deselected
* @param {string} type Item type acting on
* @param {boolean} any Require that there are values before
* triggering
* @private
*/
function eventTrigger(api, type, args, any) {
if (any && !api.flatten().length) {
return;
}
if (typeof type === 'string') {
type = type + '.dt';
}
args.unshift(api);
$(api.table().node()).trigger(type, args);
}
/**
* Update the information element of the DataTable showing information about the
* items selected. This is done by adding tags to the existing text
*
* @param {DataTable.Api} api DataTable to update
* @private
*/
function info(api) {
var ctx = api.settings()[0];
if (!ctx._select.info || !ctx.aanFeatures.i) {
return;
}
if (api.select.style() === 'api') {
return;
}
var rows = api.rows({selected: true}).flatten().length;
var columns = api.columns({selected: true}).flatten().length;
var cells = api.cells({selected: true}).flatten().length;
var add = function (el, name, num) {
el.append($('').append(api.i18n(
'select.' + name + 's',
{_: '%d ' + name + 's selected', 0: '', 1: '1 ' + name + ' selected'},
num
)));
};
// Internal knowledge of DataTables to loop over all information elements
$.each(ctx.aanFeatures.i, function (i, el) {
el = $(el);
var output = $('');
add(output, 'row', rows);
add(output, 'column', columns);
add(output, 'cell', cells);
var exisiting = el.children('span.select-info');
if (exisiting.length) {
exisiting.remove();
}
if (output.text() !== '') {
el.append(output);
}
});
}
/**
* Initialisation of a new table. Attach event handlers and callbacks to allow
* Select to operate correctly.
*
* This will occur _after_ the initial DataTables initialisation, although
* before Ajax data is rendered, if there is ajax data
*
* @param {DataTable.settings} ctx Settings object to operate on
* @private
*/
function init(ctx) {
var api = new DataTable.Api(ctx);
// Row callback so that classes can be added to rows and cells if the item
// was selected before the element was created. This will happen with the
// `deferRender` option enabled.
//
// This method of attaching to `aoRowCreatedCallback` is a hack until
// DataTables has proper events for row manipulation If you are reviewing
// this code to create your own plug-ins, please do not do this!
ctx.aoRowCreatedCallback.push({
fn: function (row, data, index) {
var i, ien;
var d = ctx.aoData[index];
// Row
if (d._select_selected) {
$(row).addClass(ctx._select.className);
}
// Cells and columns - if separated out, we would need to do two
// loops, so it makes sense to combine them into a single one
for (i = 0, ien = ctx.aoColumns.length; i < ien; i++) {
if (ctx.aoColumns[i]._select_selected || (d._selected_cells && d._selected_cells[i])) {
$(d.anCells[i]).addClass(ctx._select.className);
}
}
},
sName: 'select-deferRender'
});
// On Ajax reload we want to reselect all rows which are currently selected,
// if there is an rowId (i.e. a unique value to identify each row with)
api.on('preXhr.dt.dtSelect', function () {
// note that column selection doesn't need to be cached and then
// reselected, as they are already selected
var rows = api.rows({selected: true}).ids(true).filter(function (d) {
return d !== undefined;
});
var cells = api.cells({selected: true}).eq(0).map(function (cellIdx) {
var id = api.row(cellIdx.row).id(true);
return id ?
{row: id, column: cellIdx.column} :
undefined;
}).filter(function (d) {
return d !== undefined;
});
// On the next draw, reselect the currently selected items
api.one('draw.dt.dtSelect', function () {
api.rows(rows).select();
// `cells` is not a cell index selector, so it needs a loop
if (cells.any()) {
cells.each(function (id) {
api.cells(id.row, id.column).select();
});
}
});
});
// Update the table information element with selected item summary
api.on('draw.dtSelect.dt select.dtSelect.dt deselect.dtSelect.dt info.dt', function () {
info(api);
});
// Clean up and release
api.on('destroy.dtSelect', function () {
disableMouseSelection(api);
api.off('.dtSelect');
});
}
/**
* Add one or more items (rows or columns) to the selection when shift clicking
* in OS selection style
*
* @param {DataTable.Api} dt DataTable
* @param {string} type Row or column range selector
* @param {object} idx Item index to select to
* @param {object} last Item index to select from
* @private
*/
function rowColumnRange(dt, type, idx, last) {
// Add a range of rows from the last selected row to this one
var indexes = dt[type + 's']({search: 'applied'}).indexes();
var idx1 = $.inArray(last, indexes);
var idx2 = $.inArray(idx, indexes);
if (!dt[type + 's']({selected: true}).any() && idx1 === -1) {
// select from top to here - slightly odd, but both Windows and Mac OS
// do this
indexes.splice($.inArray(idx, indexes) + 1, indexes.length);
}
else {
// reverse so we can shift click 'up' as well as down
if (idx1 > idx2) {
var tmp = idx2;
idx2 = idx1;
idx1 = tmp;
}
indexes.splice(idx2 + 1, indexes.length);
indexes.splice(0, idx1);
}
if (!dt[type](idx, {selected: true}).any()) {
// Select range
dt[type + 's'](indexes).select();
}
else {
// Deselect range - need to keep the clicked on row selected
indexes.splice($.inArray(idx, indexes), 1);
dt[type + 's'](indexes).deselect();
}
}
/**
* Clear all selected items
*
* @param {DataTable.settings} ctx Settings object of the host DataTable
* @param {boolean} [force=false] Force the de-selection to happen, regardless
* of selection style
* @private
*/
function clear(ctx, force) {
if (force || ctx._select.style === 'single') {
var api = new DataTable.Api(ctx);
api.rows({selected: true}).deselect();
api.columns({selected: true}).deselect();
api.cells({selected: true}).deselect();
}
}
/**
* Select items based on the current configuration for style and items.
*
* @param {object} e Mouse event object
* @param {DataTables.Api} dt DataTable
* @param {DataTable.settings} ctx Settings object of the host DataTable
* @param {string} type Items to select
* @param {int|object} idx Index of the item to select
* @private
*/
function typeSelect(e, dt, ctx, type, idx) {
var style = dt.select.style();
var isSelected = dt[type](idx, {selected: true}).any();
if (style === 'os') {
if (e.ctrlKey || e.metaKey) {
// Add or remove from the selection
dt[type](idx).select(!isSelected);
}
else if (e.shiftKey) {
if (type === 'cell') {
cellRange(dt, idx, ctx._select_lastCell || null);
}
else {
rowColumnRange(dt, type, idx, ctx._select_lastCell ?
ctx._select_lastCell[type] :
null
);
}
}
else {
// No cmd or shift click - deselect if selected, or select
// this row only
var selected = dt[type + 's']({selected: true});
if (isSelected && selected.flatten().length === 1) {
dt[type](idx).deselect();
}
else {
selected.deselect();
dt[type](idx).select();
}
}
} else if (style == 'multi+shift') {
if (e.shiftKey) {
if (type === 'cell') {
cellRange(dt, idx, ctx._select_lastCell || null);
}
else {
rowColumnRange(dt, type, idx, ctx._select_lastCell ?
ctx._select_lastCell[type] :
null
);
}
}
else {
dt[type](idx).select(!isSelected);
}
}
else {
dt[type](idx).select(!isSelected);
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DataTables selectors
*/
// row and column are basically identical just assigned to different properties
// and checking a different array, so we can dynamically create the functions to
// reduce the code size
$.each([
{type: 'row', prop: 'aoData'},
{type: 'column', prop: 'aoColumns'}
], function (i, o) {
DataTable.ext.selector[o.type].push(function (settings, opts, indexes) {
var selected = opts.selected;
var data;
var out = [];
if (selected !== true && selected !== false) {
return indexes;
}
for (var i = 0, ien = indexes.length; i < ien; i++) {
data = settings[o.prop][indexes[i]];
if ((selected === true && data._select_selected === true) ||
(selected === false && !data._select_selected)
) {
out.push(indexes[i]);
}
}
return out;
});
});
DataTable.ext.selector.cell.push(function (settings, opts, cells) {
var selected = opts.selected;
var rowData;
var out = [];
if (selected === undefined) {
return cells;
}
for (var i = 0, ien = cells.length; i < ien; i++) {
rowData = settings.aoData[cells[i].row];
if ((selected === true && rowData._selected_cells && rowData._selected_cells[cells[i].column] === true) ||
(selected === false && (!rowData._selected_cells || !rowData._selected_cells[cells[i].column]))
) {
out.push(cells[i]);
}
}
return out;
});
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* DataTables API
*
* For complete documentation, please refer to the docs/api directory or the
* DataTables site
*/
// Local variables to improve compression
var apiRegister = DataTable.Api.register;
var apiRegisterPlural = DataTable.Api.registerPlural;
apiRegister('select()', function () {
return this.iterator('table', function (ctx) {
DataTable.select.init(new DataTable.Api(ctx));
});
});
apiRegister('select.blurable()', function (flag) {
if (flag === undefined) {
return this.context[0]._select.blurable;
}
return this.iterator('table', function (ctx) {
ctx._select.blurable = flag;
});
});
apiRegister('select.info()', function (flag) {
if (info === undefined) {
return this.context[0]._select.info;
}
return this.iterator('table', function (ctx) {
ctx._select.info = flag;
});
});
apiRegister('select.items()', function (items) {
if (items === undefined) {
return this.context[0]._select.items;
}
return this.iterator('table', function (ctx) {
ctx._select.items = items;
eventTrigger(new DataTable.Api(ctx), 'selectItems', [items]);
});
});
// Takes effect from the _next_ selection. None disables future selection, but
// does not clear the current selection. Use the `deselect` methods for that
apiRegister('select.style()', function (style) {
if (style === undefined) {
return this.context[0]._select.style;
}
return this.iterator('table', function (ctx) {
ctx._select.style = style;
if (!ctx._select_init) {
init(ctx);
}
// Add / remove mouse event handlers. They aren't required when only
// API selection is available
var dt = new DataTable.Api(ctx);
disableMouseSelection(dt);
if (style !== 'api') {
enableMouseSelection(dt);
}
eventTrigger(new DataTable.Api(ctx), 'selectStyle', [style]);
});
});
apiRegister('select.selector()', function (selector) {
if (selector === undefined) {
return this.context[0]._select.selector;
}
return this.iterator('table', function (ctx) {
disableMouseSelection(new DataTable.Api(ctx));
ctx._select.selector = selector;
if (ctx._select.style !== 'api') {
enableMouseSelection(new DataTable.Api(ctx));
}
});
});
apiRegisterPlural('rows().select()', 'row().select()', function (select) {
var api = this;
if (select === false) {
return this.deselect();
}
this.iterator('row', function (ctx, idx) {
clear(ctx);
ctx.aoData[idx]._select_selected = true;
$(ctx.aoData[idx].nTr).addClass(ctx._select.className);
});
this.iterator('table', function (ctx, i) {
eventTrigger(api, 'select', ['row', api[i]], true);
});
return this;
});
apiRegisterPlural('columns().select()', 'column().select()', function (select) {
var api = this;
if (select === false) {
return this.deselect();
}
this.iterator('column', function (ctx, idx) {
clear(ctx);
ctx.aoColumns[idx]._select_selected = true;
var column = new DataTable.Api(ctx).column(idx);
$(column.header()).addClass(ctx._select.className);
$(column.footer()).addClass(ctx._select.className);
column.nodes().to$().addClass(ctx._select.className);
});
this.iterator('table', function (ctx, i) {
eventTrigger(api, 'select', ['column', api[i]], true);
});
return this;
});
apiRegisterPlural('cells().select()', 'cell().select()', function (select) {
var api = this;
if (select === false) {
return this.deselect();
}
this.iterator('cell', function (ctx, rowIdx, colIdx) {
clear(ctx);
var data = ctx.aoData[rowIdx];
if (data._selected_cells === undefined) {
data._selected_cells = [];
}
data._selected_cells[colIdx] = true;
if (data.anCells) {
$(data.anCells[colIdx]).addClass(ctx._select.className);
}
});
this.iterator('table', function (ctx, i) {
eventTrigger(api, 'select', ['cell', api[i]], true);
});
return this;
});
apiRegisterPlural('rows().deselect()', 'row().deselect()', function () {
var api = this;
this.iterator('row', function (ctx, idx) {
ctx.aoData[idx]._select_selected = false;
$(ctx.aoData[idx].nTr).removeClass(ctx._select.className);
});
this.iterator('table', function (ctx, i) {
eventTrigger(api, 'deselect', ['row', api[i]], true);
});
return this;
});
apiRegisterPlural('columns().deselect()', 'column().deselect()', function () {
var api = this;
this.iterator('column', function (ctx, idx) {
ctx.aoColumns[idx]._select_selected = false;
var api = new DataTable.Api(ctx);
var column = api.column(idx);
$(column.header()).removeClass(ctx._select.className);
$(column.footer()).removeClass(ctx._select.className);
// Need to loop over each cell, rather than just using
// `column().nodes()` as cells which are individually selected should
// not have the `selected` class removed from them
api.cells(null, idx).indexes().each(function (cellIdx) {
var data = ctx.aoData[cellIdx.row];
var cellSelected = data._selected_cells;
if (data.anCells && (!cellSelected || !cellSelected[cellIdx.column])) {
$(data.anCells[cellIdx.column]).removeClass(ctx._select.className);
}
});
});
this.iterator('table', function (ctx, i) {
eventTrigger(api, 'deselect', ['column', api[i]], true);
});
return this;
});
apiRegisterPlural('cells().deselect()', 'cell().deselect()', function () {
var api = this;
this.iterator('cell', function (ctx, rowIdx, colIdx) {
var data = ctx.aoData[rowIdx];
data._selected_cells[colIdx] = false;
// Remove class only if the cells exist, and the cell is not column
// selected, in which case the class should remain (since it is selected
// in the column)
if (data.anCells && !ctx.aoColumns[colIdx]._select_selected) {
$(data.anCells[colIdx]).removeClass(ctx._select.className);
}
});
this.iterator('table', function (ctx, i) {
eventTrigger(api, 'deselect', ['cell', api[i]], true);
});
return this;
});
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Buttons
*/
function i18n(label, def) {
return function (dt) {
return dt.i18n('buttons.' + label, def);
};
}
// Common events with suitable namespaces
function namespacedEvents(config) {
var unique = config._eventNamespace;
return 'draw.dt.DT' + unique + ' select.dt.DT' + unique + ' deselect.dt.DT' + unique;
}
function enabled(dt, config) {
if ($.inArray('rows', config.limitTo) !== -1 && dt.rows({selected: true}).any()) {
return true;
}
if ($.inArray('columns', config.limitTo) !== -1 && dt.columns({selected: true}).any()) {
return true;
}
if ($.inArray('cells', config.limitTo) !== -1 && dt.cells({selected: true}).any()) {
return true;
}
return false;
}
var _buttonNamespace = 0;
$.extend(DataTable.ext.buttons, {
selected: {
text: i18n('selected', 'Selected'),
className: 'buttons-selected',
limitTo: ['rows', 'columns', 'cells'],
init: function (dt, node, config) {
var that = this;
config._eventNamespace = '.select' + (_buttonNamespace++);
// .DT namespace listeners are removed by DataTables automatically
// on table destroy
dt.on(namespacedEvents(config), function () {
that.enable(enabled(dt, config));
});
this.disable();
},
destroy: function (dt, node, config) {
dt.off(config._eventNamespace);
}
},
selectedSingle: {
text: i18n('selectedSingle', 'Selected single'),
className: 'buttons-selected-single',
init: function (dt, node, config) {
var that = this;
config._eventNamespace = '.select' + (_buttonNamespace++);
dt.on(namespacedEvents(config), function () {
var count = dt.rows({selected: true}).flatten().length +
dt.columns({selected: true}).flatten().length +
dt.cells({selected: true}).flatten().length;
that.enable(count === 1);
});
this.disable();
},
destroy: function (dt, node, config) {
dt.off(config._eventNamespace);
}
},
selectAll: {
text: i18n('selectAll', 'Select all'),
className: 'buttons-select-all',
action: function () {
var items = this.select.items();
this[items + 's']().select();
}
},
selectNone: {
text: i18n('selectNone', 'Deselect all'),
className: 'buttons-select-none',
action: function () {
clear(this.settings()[0], true);
},
init: function (dt, node, config) {
var that = this;
config._eventNamespace = '.select' + (_buttonNamespace++);
dt.on(namespacedEvents(config), function () {
var count = dt.rows({selected: true}).flatten().length +
dt.columns({selected: true}).flatten().length +
dt.cells({selected: true}).flatten().length;
that.enable(count > 0);
});
this.disable();
},
destroy: function (dt, node, config) {
dt.off(config._eventNamespace);
}
}
});
$.each(['Row', 'Column', 'Cell'], function (i, item) {
var lc = item.toLowerCase();
DataTable.ext.buttons['select' + item + 's'] = {
text: i18n('select' + item + 's', 'Select ' + lc + 's'),
className: 'buttons-select-' + lc + 's',
action: function () {
this.select.items(lc);
},
init: function (dt) {
var that = this;
dt.on('selectItems.dt.DT', function (e, ctx, items) {
that.active(items === lc);
});
}
};
});
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Initialisation
*/
// DataTables creation - check if select has been defined in the options. Note
// this required that the table be in the document! If it isn't then something
// needs to trigger this method unfortunately. The next major release of
// DataTables will rework the events and address this.
$(document).on('preInit.dt.dtSelect', function (e, ctx) {
if (e.namespace !== 'dt') {
return;
}
DataTable.select.init(new DataTable.Api(ctx));
});
return DataTable.select;
}));
© 2015 - 2025 Weber Informatics LLC | Privacy Policy