498 lines
18 KiB
JavaScript
498 lines
18 KiB
JavaScript
|
/*! StateRestore 1.4.1
|
||
|
* © SpryMedia Ltd - datatables.net/license
|
||
|
*/
|
||
|
/**
|
||
|
* @summary StateRestore
|
||
|
* @description StateRestore extension for DataTables
|
||
|
* @version 1.4.1
|
||
|
* @author SpryMedia Ltd
|
||
|
* @contact datatables.net
|
||
|
* @copyright Copyright 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
|
||
|
*/
|
||
|
/// <reference path = '../node_modules/@types/jquery/index.d.ts'
|
||
|
import StateRestore, { setJQuery as stateRestoreJQuery } from './StateRestore';
|
||
|
import StateRestoreCollection, { setJQuery as stateRestoreCollectionJQuery } from './StateRestoreCollection';
|
||
|
stateRestoreJQuery($);
|
||
|
stateRestoreCollectionJQuery($);
|
||
|
$.fn.dataTable.StateRestore = StateRestore;
|
||
|
$.fn.DataTable.StateRestore = StateRestore;
|
||
|
$.fn.dataTable.StateRestoreCollection = StateRestoreCollection;
|
||
|
$.fn.DataTable.StateRestoreCollection = StateRestoreCollection;
|
||
|
var apiRegister = DataTable.Api.register;
|
||
|
apiRegister('stateRestore()', function () {
|
||
|
return this;
|
||
|
});
|
||
|
apiRegister('stateRestore.state()', function (identifier) {
|
||
|
var ctx = this.context[0];
|
||
|
if (!ctx._stateRestore) {
|
||
|
var api = DataTable.Api(ctx);
|
||
|
var src = new DataTable.StateRestoreCollection(api, {});
|
||
|
_stateRegen(api, src);
|
||
|
}
|
||
|
this[0] = ctx._stateRestore.getState(identifier);
|
||
|
return this;
|
||
|
});
|
||
|
apiRegister('stateRestore.state.add()', function (identifier, options) {
|
||
|
var ctx = this.context[0];
|
||
|
if (!ctx._stateRestore) {
|
||
|
var api = DataTable.Api(ctx);
|
||
|
var src = new DataTable.StateRestoreCollection(api, {});
|
||
|
_stateRegen(api, src);
|
||
|
}
|
||
|
if (!ctx._stateRestore.c.create) {
|
||
|
return this;
|
||
|
}
|
||
|
if (ctx._stateRestore.addState) {
|
||
|
var states = ctx._stateRestore.s.states;
|
||
|
var ids = [];
|
||
|
for (var _i = 0, states_1 = states; _i < states_1.length; _i++) {
|
||
|
var intState = states_1[_i];
|
||
|
ids.push(intState.s.identifier);
|
||
|
}
|
||
|
ctx._stateRestore.addState(identifier, ids, options);
|
||
|
return this;
|
||
|
}
|
||
|
});
|
||
|
apiRegister('stateRestore.states()', function (ids) {
|
||
|
var ctx = this.context[0];
|
||
|
if (!ctx._stateRestore) {
|
||
|
var api = DataTable.Api(ctx);
|
||
|
var src = new DataTable.StateRestoreCollection(api, {});
|
||
|
_stateRegen(api, src);
|
||
|
}
|
||
|
this.length = 0;
|
||
|
this.push.apply(this, ctx._stateRestore.getStates(ids));
|
||
|
return this;
|
||
|
});
|
||
|
apiRegister('stateRestore.state().save()', function () {
|
||
|
var ctx = this[0];
|
||
|
// Check if saving states is allowed
|
||
|
if (ctx.c.save) {
|
||
|
ctx.save();
|
||
|
}
|
||
|
return this;
|
||
|
});
|
||
|
apiRegister('stateRestore.state().rename()', function (newIdentifier) {
|
||
|
var ctx = this.context[0];
|
||
|
var state = this[0];
|
||
|
// Check if renaming states is allowed
|
||
|
if (state.c.save) {
|
||
|
var states = ctx._stateRestore.s.states;
|
||
|
var ids = [];
|
||
|
for (var _i = 0, states_2 = states; _i < states_2.length; _i++) {
|
||
|
var intState = states_2[_i];
|
||
|
ids.push(intState.s.identifier);
|
||
|
}
|
||
|
state.rename(newIdentifier, ids);
|
||
|
}
|
||
|
return this;
|
||
|
});
|
||
|
apiRegister('stateRestore.state().load()', function () {
|
||
|
var ctx = this[0];
|
||
|
ctx.load();
|
||
|
return this;
|
||
|
});
|
||
|
apiRegister('stateRestore.state().remove()', function (skipModal) {
|
||
|
var ctx = this[0];
|
||
|
// Check if removal of states is allowed
|
||
|
if (ctx.c.remove) {
|
||
|
ctx.remove(skipModal);
|
||
|
}
|
||
|
return this;
|
||
|
});
|
||
|
apiRegister('stateRestore.states().remove()', function (skipModal) {
|
||
|
var _this = this;
|
||
|
var removeAllCallBack = function (skipModalIn) {
|
||
|
var success = true;
|
||
|
var that = _this.toArray();
|
||
|
while (that.length > 0) {
|
||
|
var set = that[0];
|
||
|
if (set !== undefined && set.c.remove) {
|
||
|
var tempSuccess = set.remove(skipModalIn);
|
||
|
if (tempSuccess !== true) {
|
||
|
success = tempSuccess;
|
||
|
}
|
||
|
else {
|
||
|
that.splice(0, 1);
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return success;
|
||
|
};
|
||
|
if (this.context[0]._stateRestore && this.context[0]._stateRestore.c.remove) {
|
||
|
if (skipModal) {
|
||
|
removeAllCallBack(skipModal);
|
||
|
}
|
||
|
else {
|
||
|
this.context[0]._stateRestore.removeAll(removeAllCallBack);
|
||
|
}
|
||
|
}
|
||
|
return this;
|
||
|
});
|
||
|
apiRegister('stateRestore.activeStates()', function () {
|
||
|
var ctx = this.context[0];
|
||
|
this.length = 0;
|
||
|
if (!ctx._stateRestore) {
|
||
|
var api = DataTable.Api(ctx);
|
||
|
var src = new DataTable.StateRestoreCollection(api, {});
|
||
|
_stateRegen(api, src);
|
||
|
}
|
||
|
if (ctx._stateRestore) {
|
||
|
this.push.apply(this, ctx._stateRestore.findActive());
|
||
|
}
|
||
|
return this;
|
||
|
});
|
||
|
DataTable.ext.buttons.stateRestore = {
|
||
|
action: function (e, dt, node, config) {
|
||
|
config._stateRestore.load();
|
||
|
node.blur();
|
||
|
},
|
||
|
className: 'dtsr-state',
|
||
|
config: {
|
||
|
split: ['updateState', 'renameState', 'removeState']
|
||
|
},
|
||
|
text: function (dt) {
|
||
|
return dt.i18n('buttons.stateRestore', 'State %d', dt.stateRestore.states()[0].length + 1);
|
||
|
}
|
||
|
};
|
||
|
DataTable.ext.buttons.updateState = {
|
||
|
action: function (e, dt, node, config) {
|
||
|
$('div.dt-button-background').click();
|
||
|
config.parent._stateRestore.save();
|
||
|
},
|
||
|
text: function (dt) {
|
||
|
return dt.i18n('buttons.updateState', 'Update');
|
||
|
}
|
||
|
};
|
||
|
DataTable.ext.buttons.savedStates = {
|
||
|
buttons: [],
|
||
|
extend: 'collection',
|
||
|
init: function (dt, node, config) {
|
||
|
dt.on('stateRestore-change', function () {
|
||
|
dt.button(node).text(dt.i18n('buttons.savedStates', 'Saved States', dt.stateRestore.states().length));
|
||
|
});
|
||
|
if (dt.settings()[0]._stateRestore === undefined) {
|
||
|
_buttonInit(dt, config);
|
||
|
}
|
||
|
},
|
||
|
name: 'SaveStateRestore',
|
||
|
text: function (dt) {
|
||
|
return dt.i18n('buttons.savedStates', 'Saved States', 0);
|
||
|
}
|
||
|
};
|
||
|
DataTable.ext.buttons.savedStatesCreate = {
|
||
|
buttons: [],
|
||
|
extend: 'collection',
|
||
|
init: function (dt, node, config) {
|
||
|
dt.on('stateRestore-change', function () {
|
||
|
dt.button(node).text(dt.i18n('buttons.savedStates', 'Saved States', dt.stateRestore.states().length));
|
||
|
});
|
||
|
if (dt.settings()[0]._stateRestore === undefined) {
|
||
|
if (config.config === undefined) {
|
||
|
config.config = {};
|
||
|
}
|
||
|
config.config._createInSaved = true;
|
||
|
_buttonInit(dt, config);
|
||
|
}
|
||
|
},
|
||
|
name: 'SaveStateRestore',
|
||
|
text: function (dt) {
|
||
|
return dt.i18n('buttons.savedStates', 'Saved States', 0);
|
||
|
}
|
||
|
};
|
||
|
DataTable.ext.buttons.createState = {
|
||
|
action: function (e, dt, node, config) {
|
||
|
e.stopPropagation();
|
||
|
var stateRestoreOpts = dt.settings()[0]._stateRestore.c;
|
||
|
var language = dt.settings()[0].oLanguage;
|
||
|
// If creation/saving is not allowed then return
|
||
|
if (!stateRestoreOpts.create || !stateRestoreOpts.save) {
|
||
|
return;
|
||
|
}
|
||
|
var prevStates = dt.stateRestore.states().toArray();
|
||
|
// Create a replacement regex based on the i18n values
|
||
|
var defaultString = language.buttons !== undefined && language.buttons.stateRestore !== undefined ?
|
||
|
language.buttons.stateRestore :
|
||
|
'State ';
|
||
|
var replaceRegex;
|
||
|
if (defaultString.indexOf('%d') === defaultString.length - 3) {
|
||
|
replaceRegex = new RegExp(defaultString.replace(/%d/g, ''));
|
||
|
}
|
||
|
else {
|
||
|
var splitString = defaultString.split('%d');
|
||
|
replaceRegex = [];
|
||
|
for (var _i = 0, splitString_1 = splitString; _i < splitString_1.length; _i++) {
|
||
|
var parts = splitString_1[_i];
|
||
|
replaceRegex.push(new RegExp(parts));
|
||
|
}
|
||
|
}
|
||
|
var getId = function (identifier) {
|
||
|
var id;
|
||
|
if (Array.isArray(replaceRegex)) {
|
||
|
id = identifier;
|
||
|
for (var _i = 0, replaceRegex_1 = replaceRegex; _i < replaceRegex_1.length; _i++) {
|
||
|
var reg = replaceRegex_1[_i];
|
||
|
id = id.replace(reg, '');
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
id = identifier.replace(replaceRegex, '');
|
||
|
}
|
||
|
// If the id after replacement is not a number, or the length is the same as before,
|
||
|
// it has been customised so return 0
|
||
|
if (isNaN(+id) || id.length === identifier) {
|
||
|
return 0;
|
||
|
}
|
||
|
// Otherwise return the number that has been assigned previously
|
||
|
else {
|
||
|
return +id;
|
||
|
}
|
||
|
};
|
||
|
// Extract the numbers from the identifiers that use the standard naming convention
|
||
|
var identifiers = prevStates
|
||
|
.map(function (state) { return getId(state.s.identifier); })
|
||
|
.sort(function (a, b) { return +a < +b ?
|
||
|
1 :
|
||
|
+a > +b ?
|
||
|
-1 :
|
||
|
0; });
|
||
|
var lastNumber = identifiers[0];
|
||
|
dt.stateRestore.state.add(dt.i18n('buttons.stateRestore', 'State %d', lastNumber !== undefined ? lastNumber + 1 : 1), config.config);
|
||
|
var states = dt.stateRestore.states().sort(function (a, b) {
|
||
|
var aId = +getId(a.s.identifier);
|
||
|
var bId = +getId(b.s.identifier);
|
||
|
return aId > bId ?
|
||
|
1 :
|
||
|
aId < bId ?
|
||
|
-1 :
|
||
|
0;
|
||
|
});
|
||
|
var button = dt.button('SaveStateRestore:name');
|
||
|
var stateButtons = button[0] !== undefined && button[0].inst.c.buttons[0].buttons !== undefined ?
|
||
|
button[0].inst.c.buttons[0].buttons :
|
||
|
[];
|
||
|
// remove any states from the previous rebuild - if they are still there they will be added later
|
||
|
for (var i = 0; i < stateButtons.length; i++) {
|
||
|
if (stateButtons[i].extend === 'stateRestore') {
|
||
|
stateButtons.splice(i, 1);
|
||
|
i--;
|
||
|
}
|
||
|
}
|
||
|
if (stateRestoreOpts._createInSaved) {
|
||
|
stateButtons.push('createState');
|
||
|
}
|
||
|
for (var _a = 0, states_3 = states; _a < states_3.length; _a++) {
|
||
|
var state = states_3[_a];
|
||
|
var split = stateRestoreOpts.splitSecondaries.slice();
|
||
|
if (split.includes('updateState') && !stateRestoreOpts.save) {
|
||
|
split.splice(split.indexOf('updateState'), 1);
|
||
|
}
|
||
|
if (split.includes('renameState') &&
|
||
|
(!stateRestoreOpts.save || !stateRestoreOpts.rename)) {
|
||
|
split.splice(split.indexOf('renameState'), 1);
|
||
|
}
|
||
|
if (split.includes('removeState') && !stateRestoreOpts.remove) {
|
||
|
split.splice(split.indexOf('removeState'), 1);
|
||
|
}
|
||
|
stateButtons.push({
|
||
|
_stateRestore: state,
|
||
|
attr: {
|
||
|
title: state.s.identifier
|
||
|
},
|
||
|
config: {
|
||
|
split: split
|
||
|
},
|
||
|
extend: 'stateRestore',
|
||
|
text: StateRestore.entityEncode(state.s.identifier),
|
||
|
popoverTitle: StateRestore.entityEncode(state.s.identifier)
|
||
|
});
|
||
|
}
|
||
|
dt.button('SaveStateRestore:name').collectionRebuild(stateButtons);
|
||
|
node.blur();
|
||
|
// Need to disable the removeAllStates button if there are no states and it is present
|
||
|
var buttons = dt.buttons();
|
||
|
for (var _b = 0, buttons_1 = buttons; _b < buttons_1.length; _b++) {
|
||
|
var butt = buttons_1[_b];
|
||
|
if ($(butt.node).hasClass('dtsr-removeAllStates')) {
|
||
|
if (states.length === 0) {
|
||
|
dt.button(butt.node).disable();
|
||
|
}
|
||
|
else {
|
||
|
dt.button(butt.node).enable();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
init: function (dt, node, config) {
|
||
|
if (dt.settings()[0]._stateRestore === undefined && dt.button('SaveStateRestore:name').length > 1) {
|
||
|
_buttonInit(dt, config);
|
||
|
}
|
||
|
},
|
||
|
text: function (dt) {
|
||
|
return dt.i18n('buttons.createState', 'Create State');
|
||
|
}
|
||
|
};
|
||
|
DataTable.ext.buttons.removeState = {
|
||
|
action: function (e, dt, node, config) {
|
||
|
config.parent._stateRestore.remove();
|
||
|
node.blur();
|
||
|
},
|
||
|
text: function (dt) {
|
||
|
return dt.i18n('buttons.removeState', 'Remove');
|
||
|
}
|
||
|
};
|
||
|
DataTable.ext.buttons.removeAllStates = {
|
||
|
action: function (e, dt, node) {
|
||
|
dt.stateRestore.states().remove(true);
|
||
|
node.blur();
|
||
|
},
|
||
|
className: 'dt-button dtsr-removeAllStates',
|
||
|
init: function (dt, node) {
|
||
|
if (!dt.settings()[0]._stateRestore || dt.stateRestore.states().length === 0) {
|
||
|
$(node).addClass('disabled');
|
||
|
}
|
||
|
},
|
||
|
text: function (dt) {
|
||
|
return dt.i18n('buttons.removeAllStates', 'Remove All States');
|
||
|
}
|
||
|
};
|
||
|
DataTable.ext.buttons.renameState = {
|
||
|
action: function (e, dt, node, config) {
|
||
|
var states = dt.settings()[0]._stateRestore.s.states;
|
||
|
var ids = [];
|
||
|
for (var _i = 0, states_4 = states; _i < states_4.length; _i++) {
|
||
|
var state = states_4[_i];
|
||
|
ids.push(state.s.identifier);
|
||
|
}
|
||
|
config.parent._stateRestore.rename(undefined, ids);
|
||
|
node.blur();
|
||
|
},
|
||
|
text: function (dt) {
|
||
|
return dt.i18n('buttons.renameState', 'Rename');
|
||
|
}
|
||
|
};
|
||
|
function _init(settings, options) {
|
||
|
if (options === void 0) { options = null; }
|
||
|
var api = new DataTable.Api(settings);
|
||
|
var opts = options
|
||
|
? options
|
||
|
: api.init().stateRestore || DataTable.defaults.stateRestore;
|
||
|
var stateRestore = new StateRestoreCollection(api, opts);
|
||
|
_stateRegen(api, stateRestore);
|
||
|
return stateRestore;
|
||
|
}
|
||
|
/**
|
||
|
* Initialisation function if initialising using a button
|
||
|
*
|
||
|
* @param dt The datatables instance
|
||
|
* @param config the config for the button
|
||
|
*/
|
||
|
function _buttonInit(dt, config) {
|
||
|
var SRC = new DataTable.StateRestoreCollection(dt, config.config);
|
||
|
_stateRegen(dt, SRC);
|
||
|
}
|
||
|
function _stateRegen(dt, src) {
|
||
|
var states = dt.stateRestore.states();
|
||
|
var button = dt.button('SaveStateRestore:name');
|
||
|
var stateButtons = [];
|
||
|
var i;
|
||
|
// Need to get the original configuration object, so we can rebuild it
|
||
|
// It might be nested, so need to traverse down the tree
|
||
|
if (button[0]) {
|
||
|
var idxs = button.index().split('-');
|
||
|
stateButtons = button[0].inst.c.buttons;
|
||
|
for (i = 0; i < idxs.length; i++) {
|
||
|
if (stateButtons[idxs[i]].buttons) {
|
||
|
stateButtons = stateButtons[idxs[i]].buttons;
|
||
|
}
|
||
|
else {
|
||
|
stateButtons = [];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
var stateRestoreOpts = dt.settings()[0]._stateRestore.c;
|
||
|
// remove any states from the previous rebuild - if they are still there they will be added later
|
||
|
for (i = 0; i < stateButtons.length; i++) {
|
||
|
if (stateButtons[i].extend === 'stateRestore') {
|
||
|
stateButtons.splice(i, 1);
|
||
|
i--;
|
||
|
}
|
||
|
}
|
||
|
if (stateRestoreOpts._createInSaved) {
|
||
|
stateButtons.push('createState');
|
||
|
}
|
||
|
if (states === undefined || states.length === 0) {
|
||
|
stateButtons.push('<span class="' + src.classes.emptyStates + '">' +
|
||
|
dt.i18n('stateRestore.emptyStates', src.c.i18n.emptyStates) +
|
||
|
'</span>');
|
||
|
}
|
||
|
else {
|
||
|
for (var _i = 0, states_5 = states; _i < states_5.length; _i++) {
|
||
|
var state = states_5[_i];
|
||
|
var split = stateRestoreOpts.splitSecondaries.slice();
|
||
|
if (split.includes('updateState') && !stateRestoreOpts.save) {
|
||
|
split.splice(split.indexOf('updateState'), 1);
|
||
|
}
|
||
|
if (split.includes('renameState') &&
|
||
|
(!stateRestoreOpts.save || !stateRestoreOpts.rename)) {
|
||
|
split.splice(split.indexOf('renameState'), 1);
|
||
|
}
|
||
|
if (split.includes('removeState') && !stateRestoreOpts.remove) {
|
||
|
split.splice(split.indexOf('removeState'), 1);
|
||
|
}
|
||
|
stateButtons.push({
|
||
|
_stateRestore: state,
|
||
|
attr: {
|
||
|
title: state.s.identifier
|
||
|
},
|
||
|
config: {
|
||
|
split: split
|
||
|
},
|
||
|
extend: 'stateRestore',
|
||
|
text: StateRestore.entityEncode(state.s.identifier),
|
||
|
popoverTitle: StateRestore.entityEncode(state.s.identifier)
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
dt.button('SaveStateRestore:name').collectionRebuild(stateButtons);
|
||
|
// Need to disable the removeAllStates button if there are no states and it is present
|
||
|
var buttons = dt.buttons();
|
||
|
for (var _a = 0, buttons_2 = buttons; _a < buttons_2.length; _a++) {
|
||
|
var butt = buttons_2[_a];
|
||
|
if ($(butt.node).hasClass('dtsr-removeAllStates')) {
|
||
|
if (states.length === 0) {
|
||
|
dt.button(butt.node).disable();
|
||
|
}
|
||
|
else {
|
||
|
dt.button(butt.node).enable();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// Attach a listener to the document which listens for DataTables initialisation
|
||
|
// events so we can automatically initialise
|
||
|
$(document).on('preInit.dt.dtsr', function (e, settings) {
|
||
|
if (e.namespace !== 'dt') {
|
||
|
return;
|
||
|
}
|
||
|
if (settings.oInit.stateRestore ||
|
||
|
DataTable.defaults.stateRestore) {
|
||
|
if (!settings._stateRestore) {
|
||
|
_init(settings, null);
|
||
|
}
|
||
|
}
|
||
|
});
|