GPQAPP
3797 строк · 169.6 Кб
1/*! SearchBuilder 1.3.1
2* ©SpryMedia Ltd - datatables.net/license/mit
3*/
4(function () {5'use strict';6
7var $$2;8var dataTable$2;9// eslint-disable-next-line no-extra-parens10var moment = window.moment;11// eslint-disable-next-line no-extra-parens12var luxon = window.luxon;13/**14* Sets the value of jQuery for use in the file
15*
16* @param jq the instance of jQuery to be set
17*/
18function setJQuery$2(jq) {19$$2 = jq;20dataTable$2 = jq.fn.dataTable;21}22/**23* The Criteria class is used within SearchBuilder to represent a search criteria
24*/
25var Criteria = /** @class */ (function () {26function Criteria(table, opts, topGroup, index, depth) {27var _this = this;28if (index === void 0) { index = 0; }29if (depth === void 0) { depth = 1; }30// Check that the required version of DataTables is included31if (!dataTable$2 || !dataTable$2.versionCheck || !dataTable$2.versionCheck('1.10.0')) {32throw new Error('SearchPane requires DataTables 1.10 or newer');33}34this.classes = $$2.extend(true, {}, Criteria.classes);35// Get options from user and any extra conditions/column types defined by plug-ins36this.c = $$2.extend(true, {}, Criteria.defaults, $$2.fn.dataTable.ext.searchBuilder, opts);37var i18n = this.c.i18n;38this.s = {39condition: undefined,40conditions: {},41data: undefined,42dataIdx: -1,43dataPoints: [],44dateFormat: false,45depth: depth,46dt: table,47filled: false,48index: index,49origData: undefined,50topGroup: topGroup,51type: '',52value: []53};54this.dom = {55buttons: $$2('<div/>')56.addClass(this.classes.buttonContainer),57condition: $$2('<select disabled/>')58.addClass(this.classes.condition)59.addClass(this.classes.dropDown)60.addClass(this.classes.italic)61.attr('autocomplete', 'hacking'),62conditionTitle: $$2('<option value="" disabled selected hidden/>')63.html(this.s.dt.i18n('searchBuilder.condition', i18n.condition)),64container: $$2('<div/>')65.addClass(this.classes.container),66data: $$2('<select/>')67.addClass(this.classes.data)68.addClass(this.classes.dropDown)69.addClass(this.classes.italic),70dataTitle: $$2('<option value="" disabled selected hidden/>')71.html(this.s.dt.i18n('searchBuilder.data', i18n.data)),72defaultValue: $$2('<select disabled/>')73.addClass(this.classes.value)74.addClass(this.classes.dropDown)75.addClass(this.classes.select)76.addClass(this.classes.italic),77"delete": $$2('<button/>')78.html(this.s.dt.i18n('searchBuilder.delete', i18n["delete"]))79.addClass(this.classes["delete"])80.addClass(this.classes.button)81.attr('title', this.s.dt.i18n('searchBuilder.deleteTitle', i18n.deleteTitle))82.attr('type', 'button'),83// eslint-disable-next-line no-useless-escape84left: $$2('<button/>')85.html(this.s.dt.i18n('searchBuilder.left', i18n.left))86.addClass(this.classes.left)87.addClass(this.classes.button)88.attr('title', this.s.dt.i18n('searchBuilder.leftTitle', i18n.leftTitle))89.attr('type', 'button'),90// eslint-disable-next-line no-useless-escape91right: $$2('<button/>')92.html(this.s.dt.i18n('searchBuilder.right', i18n.right))93.addClass(this.classes.right)94.addClass(this.classes.button)95.attr('title', this.s.dt.i18n('searchBuilder.rightTitle', i18n.rightTitle))96.attr('type', 'button'),97value: [98$$2('<select disabled/>')99.addClass(this.classes.value)100.addClass(this.classes.dropDown)101.addClass(this.classes.italic)102.addClass(this.classes.select)103],104valueTitle: $$2('<option value="--valueTitle--" disabled selected hidden/>')105.html(this.s.dt.i18n('searchBuilder.value', i18n.value))106};107// If the greyscale option is selected then add the class to add the grey colour to SearchBuilder108if (this.c.greyscale) {109this.dom.data.addClass(this.classes.greyscale);110this.dom.condition.addClass(this.classes.greyscale);111this.dom.defaultValue.addClass(this.classes.greyscale);112for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {113var val = _a[_i];114val.addClass(this.classes.greyscale);115}116}117// For responsive design, adjust the criterias properties on the following events118this.s.dt.on('draw.dtsb', function () {119_this._adjustCriteria();120});121this.s.dt.on('buttons-action.dtsb', function () {122_this._adjustCriteria();123});124$$2(window).on('resize.dtsb', dataTable$2.util.throttle(function () {125_this._adjustCriteria();126}));127this._buildCriteria();128return this;129}130/**131* Escape html characters within a string
132*
133* @param txt the string to be escaped
134* @returns the escaped string
135*/
136Criteria._escapeHTML = function (txt) {137return txt138.toString()139.replace(/&/g, '&')140.replace(/</g, '<')141.replace(/>/g, '>')142.replace(/"/g, '"');143};144/**145* Adds the left button to the criteria
146*/
147Criteria.prototype.updateArrows = function (hasSiblings, redraw) {148if (hasSiblings === void 0) { hasSiblings = false; }149if (redraw === void 0) { redraw = true; }150// Empty the container and append all of the elements in the correct order151this.dom.container.children().detach();152this.dom.container153.append(this.dom.data)154.append(this.dom.condition)155.append(this.dom.value[0]);156this.setListeners();157// Trigger the inserted events for the value elements as they are inserted158if (this.dom.value[0] !== undefined) {159this.dom.value[0].trigger('dtsb-inserted');160}161for (var i = 1; i < this.dom.value.length; i++) {162this.dom.container.append(this.dom.value[i]);163this.dom.value[i].trigger('dtsb-inserted');164}165// If this is a top level criteria then don't let it move left166if (this.s.depth > 1) {167this.dom.buttons.append(this.dom.left);168}169// If the depthLimit of the query has been hit then don't add the right button170if ((this.c.depthLimit === false || this.s.depth < this.c.depthLimit) && hasSiblings) {171this.dom.buttons.append(this.dom.right);172}173else {174this.dom.right.remove();175}176this.dom.buttons.append(this.dom["delete"]);177this.dom.container.append(this.dom.buttons);178if (redraw) {179// A different combination of arrows and selectors may lead to a need for responsive to be triggered180this._adjustCriteria();181}182};183/**184* Destroys the criteria, removing listeners and container from the dom
185*/
186Criteria.prototype.destroy = function () {187// Turn off listeners188this.dom.data.off('.dtsb');189this.dom.condition.off('.dtsb');190this.dom["delete"].off('.dtsb');191for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {192var val = _a[_i];193val.off('.dtsb');194}195// Remove container from the dom196this.dom.container.remove();197};198/**199* Passes in the data for the row and compares it against this single criteria
200*
201* @param rowData The data for the row to be compared
202* @returns boolean Whether the criteria has passed
203*/
204Criteria.prototype.search = function (rowData, rowIdx) {205var condition = this.s.conditions[this.s.condition];206if (this.s.condition !== undefined && condition !== undefined) {207var filter = rowData[this.s.dataIdx];208// This check is in place for if a custom decimal character is in place209if (this.s.type.includes('num') &&210(this.s.dt.settings()[0].oLanguage.sDecimal !== '' ||211this.s.dt.settings()[0].oLanguage.sThousands !== '')) {212var splitRD = [rowData[this.s.dataIdx]];213if (this.s.dt.settings()[0].oLanguage.sDecimal !== '') {214splitRD = rowData[this.s.dataIdx].split(this.s.dt.settings()[0].oLanguage.sDecimal);215}216if (this.s.dt.settings()[0].oLanguage.sThousands !== '') {217for (var i = 0; i < splitRD.length; i++) {218splitRD[i] = splitRD[i].replace(this.s.dt.settings()[0].oLanguage.sThousands, ',');219}220}221filter = splitRD.join('.');222}223// If orthogonal data is in place we need to get it's values for searching224if (this.c.orthogonal.search !== 'filter') {225var settings = this.s.dt.settings()[0];226filter = settings.oApi._fnGetCellData(settings, rowIdx, this.s.dataIdx, typeof this.c.orthogonal === 'string' ?227this.c.orthogonal :228this.c.orthogonal.search);229}230if (this.s.type === 'array') {231// Make sure we are working with an array232if (!Array.isArray(filter)) {233filter = [filter];234}235filter.sort();236for (var _i = 0, filter_1 = filter; _i < filter_1.length; _i++) {237var filt = filter_1[_i];238if (filt && typeof filt === 'string') {239filt = filt.replace(/[\r\n\u2028]/g, ' ');240}241}242}243else if (filter !== null && typeof filter === 'string') {244filter = filter.replace(/[\r\n\u2028]/g, ' ');245}246if (this.s.type.includes('html') && typeof filter === 'string') {247filter = filter.replace(/(<([^>]+)>)/ig, '');248}249// Not ideal, but jqueries .val() returns an empty string even250// when the value set is null, so we shall assume the two are equal251if (filter === null) {252filter = '';253}254return condition.search(filter, this.s.value, this);255}256};257/**258* Gets the details required to rebuild the criteria
259*/
260Criteria.prototype.getDetails = function (deFormatDates) {261if (deFormatDates === void 0) { deFormatDates = false; }262// This check is in place for if a custom decimal character is in place263if (this.s.type !== null &&264this.s.type.includes('num') &&265(this.s.dt.settings()[0].oLanguage.sDecimal !== '' || this.s.dt.settings()[0].oLanguage.sThousands !== '')) {266for (var i = 0; i < this.s.value.length; i++) {267var splitRD = [this.s.value[i].toString()];268if (this.s.dt.settings()[0].oLanguage.sDecimal !== '') {269splitRD = this.s.value[i].split(this.s.dt.settings()[0].oLanguage.sDecimal);270}271if (this.s.dt.settings()[0].oLanguage.sThousands !== '') {272for (var j = 0; j < splitRD.length; j++) {273splitRD[j] = splitRD[j].replace(this.s.dt.settings()[0].oLanguage.sThousands, ',');274}275}276this.s.value[i] = splitRD.join('.');277}278}279else if (this.s.type !== null && deFormatDates) {280if (this.s.type.includes('date') ||281this.s.type.includes('time')) {282for (var i = 0; i < this.s.value.length; i++) {283if (this.s.value[i].match(/^\d{4}-([0]\d|1[0-2])-([0-2]\d|3[01])$/g) === null) {284this.s.value[i] = '';285}286}287}288else if (this.s.type.includes('moment')) {289for (var i = 0; i < this.s.value.length; i++) {290this.s.value[i] = moment(this.s.value[i], this.s.dateFormat).toISOString();291}292}293else if (this.s.type.includes('luxon')) {294for (var i = 0; i < this.s.value.length; i++) {295this.s.value[i] = luxon.DateTime.fromFormat(this.s.value[i], this.s.dateFormat).toISO();296}297}298}299if (this.s.type.includes('num') && this.s.dt.page.info().serverSide) {300for (var i = 0; i < this.s.value.length; i++) {301this.s.value[i] = this.s.value[i].replace(/[^0-9.]/g, '');302}303}304return {305condition: this.s.condition,306data: this.s.data,307origData: this.s.origData,308type: this.s.type,309value: this.s.value.map(function (a) { return a.toString(); })310};311};312/**313* Getter for the node for the container of the criteria
314*
315* @returns JQuery<HTMLElement> the node for the container
316*/
317Criteria.prototype.getNode = function () {318return this.dom.container;319};320/**321* Populates the criteria data, condition and value(s) as far as has been selected
322*/
323Criteria.prototype.populate = function () {324this._populateData();325// If the column index has been found attempt to select a condition326if (this.s.dataIdx !== -1) {327this._populateCondition();328// If the condittion has been found attempt to select the values329if (this.s.condition !== undefined) {330this._populateValue();331}332}333};334/**335* Rebuilds the criteria based upon the details passed in
336*
337* @param loadedCriteria the details required to rebuild the criteria
338*/
339Criteria.prototype.rebuild = function (loadedCriteria) {340// Check to see if the previously selected data exists, if so select it341var foundData = false;342var dataIdx;343this._populateData();344// If a data selection has previously been made attempt to find and select it345if (loadedCriteria.data !== undefined) {346var italic_1 = this.classes.italic;347var data_1 = this.dom.data;348this.dom.data.children('option').each(function () {349if (!foundData &&350($$2(this).text() === loadedCriteria.data ||351loadedCriteria.origData && $$2(this).prop('origData') === loadedCriteria.origData)) {352$$2(this).prop('selected', true);353data_1.removeClass(italic_1);354foundData = true;355dataIdx = $$2(this).val();356}357else {358$$2(this).removeProp('selected');359}360});361}362// If the data has been found and selected then the condition can be populated and searched363if (foundData) {364this.s.data = loadedCriteria.data;365this.s.origData = loadedCriteria.origData;366this.s.dataIdx = dataIdx;367this.c.orthogonal = this._getOptions().orthogonal;368this.dom.dataTitle.remove();369this._populateCondition();370this.dom.conditionTitle.remove();371var condition = void 0;372// Check to see if the previously selected condition exists, if so select it373var options = this.dom.condition.children('option');374// eslint-disable-next-line @typescript-eslint/prefer-for-of375for (var i = 0; i < options.length; i++) {376var option = $$2(options[i]);377if (loadedCriteria.condition !== undefined &&378option.val() === loadedCriteria.condition &&379typeof loadedCriteria.condition === 'string') {380option.prop('selected', true);381condition = option.val();382}383else {384option.removeProp('selected');385}386}387this.s.condition = condition;388// If the condition has been found and selected then the value can be populated and searched389if (this.s.condition !== undefined) {390this.dom.conditionTitle.removeProp('selected');391this.dom.conditionTitle.remove();392this.dom.condition.removeClass(this.classes.italic);393// eslint-disable-next-line @typescript-eslint/prefer-for-of394for (var i = 0; i < options.length; i++) {395var option = $$2(options[i]);396if (option.val() !== this.s.condition) {397option.removeProp('selected');398}399}400this._populateValue(loadedCriteria);401}402else {403this.dom.conditionTitle.prependTo(this.dom.condition).prop('selected', true);404}405}406};407/**408* Sets the listeners for the criteria
409*/
410Criteria.prototype.setListeners = function () {411var _this = this;412this.dom.data413.unbind('change')414.on('change.dtsb', function () {415_this.dom.dataTitle.removeProp('selected');416// Need to go over every option to identify the correct selection417var options = _this.dom.data.children('option.' + _this.classes.option);418// eslint-disable-next-line @typescript-eslint/prefer-for-of419for (var i = 0; i < options.length; i++) {420var option = $$2(options[i]);421if (option.val() === _this.dom.data.val()) {422_this.dom.data.removeClass(_this.classes.italic);423option.prop('selected', true);424_this.s.dataIdx = +option.val();425_this.s.data = option.text();426_this.s.origData = option.prop('origData');427_this.c.orthogonal = _this._getOptions().orthogonal;428// When the data is changed, the values in condition and429// value may also change so need to renew them430_this._clearCondition();431_this._clearValue();432_this._populateCondition();433// If this criteria was previously active in the search then434// remove it from the search and trigger a new search435if (_this.s.filled) {436_this.s.filled = false;437_this.s.dt.draw();438_this.setListeners();439}440_this.s.dt.state.save();441}442else {443option.removeProp('selected');444}445}446});447this.dom.condition448.unbind('change')449.on('change.dtsb', function () {450_this.dom.conditionTitle.removeProp('selected');451// Need to go over every option to identify the correct selection452var options = _this.dom.condition.children('option.' + _this.classes.option);453// eslint-disable-next-line @typescript-eslint/prefer-for-of454for (var i = 0; i < options.length; i++) {455var option = $$2(options[i]);456if (option.val() === _this.dom.condition.val()) {457_this.dom.condition.removeClass(_this.classes.italic);458option.prop('selected', true);459var condDisp = option.val();460// Find the condition that has been selected and store it internally461for (var _i = 0, _a = Object.keys(_this.s.conditions); _i < _a.length; _i++) {462var cond = _a[_i];463if (cond === condDisp) {464_this.s.condition = condDisp;465break;466}467}468// When the condition is changed, the value selector may switch between469// a select element and an input element470_this._clearValue();471_this._populateValue();472for (var _b = 0, _c = _this.dom.value; _b < _c.length; _b++) {473var val = _c[_b];474// If this criteria was previously active in the search then remove475// it from the search and trigger a new search476if (_this.s.filled && val !== undefined && _this.dom.container.has(val[0]).length !== 0) {477_this.s.filled = false;478_this.s.dt.draw();479_this.setListeners();480}481}482if (_this.dom.value.length === 0 ||483_this.dom.value.length === 1 && _this.dom.value[0] === undefined) {484_this.s.dt.draw();485}486}487else {488option.removeProp('selected');489}490}491});492};493/**494* Adjusts the criteria to make SearchBuilder responsive
495*/
496Criteria.prototype._adjustCriteria = function () {497// If this criteria is not present then don't bother adjusting it498if ($$2(document).has(this.dom.container).length === 0) {499return;500}501var valRight;502var valWidth;503var outmostval = this.dom.value[this.dom.value.length - 1];504// Calculate the width and right value of the outmost value element505if (outmostval !== undefined && this.dom.container.has(outmostval[0]).length !== 0) {506valWidth = outmostval.outerWidth(true);507valRight = outmostval.offset().left + valWidth;508}509else {510return;511}512var leftOffset = this.dom.left.offset();513var rightOffset = this.dom.right.offset();514var clearOffset = this.dom["delete"].offset();515var hasLeft = this.dom.container.has(this.dom.left[0]).length !== 0;516var hasRight = this.dom.container.has(this.dom.right[0]).length !== 0;517var buttonsLeft = hasLeft ?518leftOffset.left :519hasRight ?520rightOffset.left :521clearOffset.left;522// Perform the responsive calculations and redraw where necessary523if ((buttonsLeft - valRight < 15 ||524hasLeft && leftOffset.top !== clearOffset.top ||525hasRight && rightOffset.top !== clearOffset.top) &&526!this.dom.container.parent().hasClass(this.classes.vertical)) {527this.dom.container.parent().addClass(this.classes.vertical);528this.s.topGroup.trigger('dtsb-redrawContents');529}530else if (buttonsLeft -531(this.dom.data.offset().left +532this.dom.data.outerWidth(true) +533this.dom.condition.outerWidth(true) +534valWidth) > 15535&& this.dom.container.parent().hasClass(this.classes.vertical)) {536this.dom.container.parent().removeClass(this.classes.vertical);537this.s.topGroup.trigger('dtsb-redrawContents');538}539};540/**541* Builds the elements of the dom together
542*/
543Criteria.prototype._buildCriteria = function () {544// Append Titles for select elements545this.dom.data.append(this.dom.dataTitle);546this.dom.condition.append(this.dom.conditionTitle);547// Add elements to container548this.dom.container549.append(this.dom.data)550.append(this.dom.condition);551for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {552var val = _a[_i];553val.append(this.dom.valueTitle);554this.dom.container.append(val);555}556// Add buttons to container557this.dom.container558.append(this.dom["delete"])559.append(this.dom.right);560this.setListeners();561};562/**563* Clears the condition select element
564*/
565Criteria.prototype._clearCondition = function () {566this.dom.condition.empty();567this.dom.conditionTitle.prop('selected', true).attr('disabled', 'true');568this.dom.condition.prepend(this.dom.conditionTitle).prop('selectedIndex', 0);569this.s.conditions = {};570this.s.condition = undefined;571};572/**573* Clears the value elements
574*/
575Criteria.prototype._clearValue = function () {576if (this.s.condition !== undefined) {577if (this.dom.value.length > 0 && this.dom.value[0] !== undefined) {578var _loop_1 = function (val) {579if (val !== undefined) {580// Timeout is annoying but because of IOS581setTimeout(function () {582val.remove();583}, 50);584}585};586// Remove all of the value elements587for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {588var val = _a[_i];589_loop_1(val);590}591}592// Call the init function to get the value elements for this condition593this.dom.value = [].concat(this.s.conditions[this.s.condition].init(this, Criteria.updateListener));594if (this.dom.value.length > 0 && this.dom.value[0] !== undefined) {595this.dom.value[0].insertAfter(this.dom.condition).trigger('dtsb-inserted');596// Insert all of the value elements597for (var i = 1; i < this.dom.value.length; i++) {598this.dom.value[i].insertAfter(this.dom.value[i - 1]).trigger('dtsb-inserted');599}600}601}602else {603var _loop_2 = function (val) {604if (val !== undefined) {605// Timeout is annoying but because of IOS606setTimeout(function () {607val.remove();608}, 50);609}610};611// Remove all of the value elements612for (var _b = 0, _c = this.dom.value; _b < _c.length; _b++) {613var val = _c[_b];614_loop_2(val);615}616// Append the default valueTitle to the default select element617this.dom.valueTitle618.prop('selected', true);619this.dom.defaultValue620.append(this.dom.valueTitle)621.insertAfter(this.dom.condition);622}623this.s.value = [];624this.dom.value = [625$$2('<select disabled/>')626.addClass(this.classes.value)627.addClass(this.classes.dropDown)628.addClass(this.classes.italic)629.addClass(this.classes.select)630.append(this.dom.valueTitle.clone())631];632};633/**634* Gets the options for the column
635*
636* @returns {object} The options for the column
637*/
638Criteria.prototype._getOptions = function () {639var table = this.s.dt;640return $$2.extend(true, {}, Criteria.defaults, table.settings()[0].aoColumns[this.s.dataIdx].searchBuilder);641};642/**643* Populates the condition dropdown
644*/
645Criteria.prototype._populateCondition = function () {646var conditionOpts = [];647var conditionsLength = Object.keys(this.s.conditions).length;648// If there are no conditions stored then we need to get them from the appropriate type649if (conditionsLength === 0) {650var column = +this.dom.data.children('option:selected').val();651this.s.type = this.s.dt.columns().type().toArray()[column];652var colInits = this.s.dt.settings()[0].aoColumns;653if (colInits !== undefined) {654var colInit = colInits[column];655if (colInit.searchBuilderType !== undefined && colInit.searchBuilderType !== null) {656this.s.type = colInit.searchBuilderType;657}658else if (this.s.type === undefined || this.s.type === null) {659this.s.type = colInit.sType;660}661}662// If the column type is still unknown, call a draw to try reading it again663if (this.s.type === null || this.s.type === undefined) {664$$2.fn.dataTable.ext.oApi._fnColumnTypes(this.s.dt.settings()[0]);665this.s.type = this.s.dt.columns().type().toArray()[column];666}667// Enable the condition element668this.dom.condition669.removeAttr('disabled')670.empty()671.append(this.dom.conditionTitle)672.addClass(this.classes.italic);673this.dom.conditionTitle674.prop('selected', true);675var decimal = this.s.dt.settings()[0].oLanguage.sDecimal;676// This check is in place for if a custom decimal character is in place677if (decimal !== '' && this.s.type.indexOf(decimal) === this.s.type.length - decimal.length) {678if (this.s.type.includes('num-fmt')) {679this.s.type = this.s.type.replace(decimal, '');680}681else if (this.s.type.includes('num')) {682this.s.type = this.s.type.replace(decimal, '');683}684}685// Select which conditions are going to be used based on the column type686var conditionObj = this.c.conditions[this.s.type] !== undefined ?687this.c.conditions[this.s.type] :688this.s.type.includes('moment') ?689this.c.conditions.moment :690this.s.type.includes('luxon') ?691this.c.conditions.luxon :692this.c.conditions.string;693// If it is a moment format then extract the date format694if (this.s.type.includes('moment')) {695this.s.dateFormat = this.s.type.replace(/moment-/g, '');696}697else if (this.s.type.includes('luxon')) {698this.s.dateFormat = this.s.type.replace(/luxon-/g, '');699}700// Add all of the conditions to the select element701for (var _i = 0, _a = Object.keys(conditionObj); _i < _a.length; _i++) {702var condition = _a[_i];703if (conditionObj[condition] !== null) {704// Serverside processing does not supply the options for the select elements705// Instead input elements need to be used for these instead706if (this.s.dt.page.info().serverSide && conditionObj[condition].init === Criteria.initSelect) {707conditionObj[condition].init = Criteria.initInput;708conditionObj[condition].inputValue = Criteria.inputValueInput;709conditionObj[condition].isInputValid = Criteria.isInputValidInput;710}711this.s.conditions[condition] = conditionObj[condition];712var condName = conditionObj[condition].conditionName;713if (typeof condName === 'function') {714condName = condName(this.s.dt, this.c.i18n);715}716conditionOpts.push($$2('<option>', {717text: condName,718value: condition719})720.addClass(this.classes.option)721.addClass(this.classes.notItalic));722}723}724}725// Otherwise we can just load them in726else if (conditionsLength > 0) {727this.dom.condition.empty().removeAttr('disabled').addClass(this.classes.italic);728for (var _b = 0, _c = Object.keys(this.s.conditions); _b < _c.length; _b++) {729var condition = _c[_b];730var condName = this.s.conditions[condition].conditionName;731if (typeof condName === 'function') {732condName = condName(this.s.dt, this.c.i18n);733}734var newOpt = $$2('<option>', {735text: condName,736value: condition737})738.addClass(this.classes.option)739.addClass(this.classes.notItalic);740if (this.s.condition !== undefined && this.s.condition === condName) {741newOpt.prop('selected', true);742this.dom.condition.removeClass(this.classes.italic);743}744conditionOpts.push(newOpt);745}746}747else {748this.dom.condition749.attr('disabled', 'true')750.addClass(this.classes.italic);751return;752}753for (var _d = 0, conditionOpts_1 = conditionOpts; _d < conditionOpts_1.length; _d++) {754var opt = conditionOpts_1[_d];755this.dom.condition.append(opt);756}757this.dom.condition.prop('selectedIndex', 0);758};759/**760* Populates the data select element
761*/
762Criteria.prototype._populateData = function () {763var _this = this;764this.dom.data.empty().append(this.dom.dataTitle);765// If there are no datas stored then we need to get them from the table766if (this.s.dataPoints.length === 0) {767this.s.dt.columns().every(function (index) {768// Need to check that the column can be filtered on before adding it769if (_this.c.columns === true ||770_this.s.dt.columns(_this.c.columns).indexes().toArray().includes(index)) {771var found = false;772for (var _i = 0, _a = _this.s.dataPoints; _i < _a.length; _i++) {773var val = _a[_i];774if (val.index === index) {775found = true;776break;777}778}779if (!found) {780var col = _this.s.dt.settings()[0].aoColumns[index];781var opt = {782index: index,783origData: col.data,784text: (col.searchBuilderTitle === undefined ?785col.sTitle :786col.searchBuilderTitle).replace(/(<([^>]+)>)/ig, '')787};788_this.s.dataPoints.push(opt);789_this.dom.data.append($$2('<option>', {790text: opt.text,791value: opt.index792})793.addClass(_this.classes.option)794.addClass(_this.classes.notItalic)795.prop('origData', col.data)796.prop('selected', _this.s.dataIdx === opt.index ? true : false));797if (_this.s.dataIdx === opt.index) {798_this.dom.dataTitle.removeProp('selected');799}800}801}802});803}804// Otherwise we can just load them in805else {806var _loop_3 = function (data) {807this_1.s.dt.columns().every(function (index) {808var col = _this.s.dt.settings()[0].aoColumns[index];809if ((col.searchBuilderTitle === undefined ?810col.sTitle :811col.searchBuilderTitle).replace(/(<([^>]+)>)/ig, '') === data.text) {812data.index = index;813data.origData = col.data;814}815});816var newOpt = $$2('<option>', {817text: data.text.replace(/(<([^>]+)>)/ig, ''),818value: data.index819})820.addClass(this_1.classes.option)821.addClass(this_1.classes.notItalic)822.prop('origData', data.origData);823if (this_1.s.data === data.text) {824this_1.s.dataIdx = data.index;825this_1.dom.dataTitle.removeProp('selected');826newOpt.prop('selected', true);827this_1.dom.data.removeClass(this_1.classes.italic);828}829this_1.dom.data.append(newOpt);830};831var this_1 = this;832for (var _i = 0, _a = this.s.dataPoints; _i < _a.length; _i++) {833var data = _a[_i];834_loop_3(data);835}836}837};838/**839* Populates the Value select element
840*
841* @param loadedCriteria optional, used to reload criteria from predefined filters
842*/
843Criteria.prototype._populateValue = function (loadedCriteria) {844var _this = this;845var prevFilled = this.s.filled;846this.s.filled = false;847// Remove any previous value elements848// Timeout is annoying but because of IOS849setTimeout(function () {850_this.dom.defaultValue.remove();851}, 50);852var _loop_4 = function (val) {853// Timeout is annoying but because of IOS854setTimeout(function () {855if (val !== undefined) {856val.remove();857}858}, 50);859};860for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {861var val = _a[_i];862_loop_4(val);863}864var children = this.dom.container.children();865if (children.length > 3) {866for (var i = 2; i < children.length - 1; i++) {867$$2(children[i]).remove();868}869}870// Find the column with the title matching the data for the criteria and take note of the index871if (loadedCriteria !== undefined) {872this.s.dt.columns().every(function (index) {873if (_this.s.dt.settings()[0].aoColumns[index].sTitle === loadedCriteria.data) {874_this.s.dataIdx = index;875}876});877}878// Initialise the value elements based on the condition879this.dom.value = [].concat(this.s.conditions[this.s.condition].init(this, Criteria.updateListener, loadedCriteria !== undefined ? loadedCriteria.value : undefined));880if (loadedCriteria !== undefined && loadedCriteria.value !== undefined) {881this.s.value = loadedCriteria.value;882}883// Insert value elements and trigger the inserted event884if (this.dom.value[0] !== undefined) {885this.dom.value[0]886.insertAfter(this.dom.condition)887.trigger('dtsb-inserted');888}889for (var i = 1; i < this.dom.value.length; i++) {890this.dom.value[i]891.insertAfter(this.dom.value[i - 1])892.trigger('dtsb-inserted');893}894// Check if the criteria can be used in a search895this.s.filled = this.s.conditions[this.s.condition].isInputValid(this.dom.value, this);896this.setListeners();897// If it can and this is different to before then trigger a draw898if (prevFilled !== this.s.filled) {899// If using SSP we want to restrict the amount of server calls that take place900// and this will already have taken place901if (!this.s.dt.page.info().serverSide) {902this.s.dt.draw();903}904this.setListeners();905}906};907/**908* Provides throttling capabilities to SearchBuilder without having to use dt's _fnThrottle function
909* This is because that function is not quite suitable for our needs as it runs initially rather than waiting
910*
911* @param args arguments supplied to the throttle function
912* @returns Function that is to be run that implements the throttling
913*/
914Criteria.prototype._throttle = function (fn, frequency) {915if (frequency === void 0) { frequency = 200; }916var last = null;917var timer = null;918var that = this;919if (frequency === null) {920frequency = 200;921}922return function () {923var args = [];924for (var _i = 0; _i < arguments.length; _i++) {925args[_i] = arguments[_i];926}927var now = +new Date();928if (last !== null && now < last + frequency) {929clearTimeout(timer);930}931else {932last = now;933}934timer = setTimeout(function () {935last = null;936fn.apply(that, args);937}, frequency);938};939};940Criteria.version = '1.1.0';941Criteria.classes = {942button: 'dtsb-button',943buttonContainer: 'dtsb-buttonContainer',944condition: 'dtsb-condition',945container: 'dtsb-criteria',946data: 'dtsb-data',947"delete": 'dtsb-delete',948dropDown: 'dtsb-dropDown',949greyscale: 'dtsb-greyscale',950input: 'dtsb-input',951italic: 'dtsb-italic',952joiner: 'dtsp-joiner',953left: 'dtsb-left',954notItalic: 'dtsb-notItalic',955option: 'dtsb-option',956right: 'dtsb-right',957select: 'dtsb-select',958value: 'dtsb-value',959vertical: 'dtsb-vertical'960};961/**962* Default initialisation function for select conditions
963*/
964Criteria.initSelect = function (that, fn, preDefined, array) {965if (preDefined === void 0) { preDefined = null; }966if (array === void 0) { array = false; }967var column = that.dom.data.children('option:selected').val();968var indexArray = that.s.dt.rows().indexes().toArray();969var settings = that.s.dt.settings()[0];970that.dom.valueTitle.prop('selected', true);971// Declare select element to be used with all of the default classes and listeners.972var el = $$2('<select/>')973.addClass(Criteria.classes.value)974.addClass(Criteria.classes.dropDown)975.addClass(Criteria.classes.italic)976.addClass(Criteria.classes.select)977.append(that.dom.valueTitle)978.on('change.dtsb', function () {979$$2(this).removeClass(Criteria.classes.italic);980fn(that, this);981});982if (that.c.greyscale) {983el.addClass(Criteria.classes.greyscale);984}985var added = [];986var options = [];987// Add all of the options from the table to the select element.988// Only add one option for each possible value989for (var _i = 0, indexArray_1 = indexArray; _i < indexArray_1.length; _i++) {990var index = indexArray_1[_i];991var filter = settings.oApi._fnGetCellData(settings, index, column, typeof that.c.orthogonal === 'string' ?992that.c.orthogonal :993that.c.orthogonal.search);994var value = {995filter: typeof filter === 'string' ?996filter.replace(/[\r\n\u2028]/g, ' ') : // Need to replace certain characters to match search values997filter,998index: index,999text: settings.oApi._fnGetCellData(settings, index, column, typeof that.c.orthogonal === 'string' ?1000that.c.orthogonal :1001that.c.orthogonal.display)1002};1003// If we are dealing with an array type, either make sure we are working with arrays, or sort them1004if (that.s.type === 'array') {1005value.filter = !Array.isArray(value.filter) ? [value.filter] : value.filter;1006value.text = !Array.isArray(value.text) ? [value.text] : value.text;1007}1008// Function to add an option to the select element1009var addOption = function (filt, text) {1010if (that.s.type.includes('html') && filt !== null && typeof filt === 'string') {1011filt.replace(/(<([^>]+)>)/ig, '');1012}1013// Add text and value, stripping out any html if that is the column type1014var opt = $$2('<option>', {1015type: Array.isArray(filt) ? 'Array' : 'String',1016value: filt1017})1018.data('sbv', filt)1019.addClass(that.classes.option)1020.addClass(that.classes.notItalic)1021// Have to add the text this way so that special html characters are not escaped - & etc.1022.html(typeof text === 'string' ?1023text.replace(/(<([^>]+)>)/ig, '') :1024text);1025var val = opt.val();1026// Check that this value has not already been added1027if (added.indexOf(val) === -1) {1028added.push(val);1029options.push(opt);1030if (preDefined !== null && Array.isArray(preDefined[0])) {1031preDefined[0] = preDefined[0].sort().join(',');1032}1033// If this value was previously selected as indicated by preDefined, then select it again1034if (preDefined !== null && opt.val() === preDefined[0]) {1035opt.prop('selected', true);1036el.removeClass(Criteria.classes.italic);1037that.dom.valueTitle.removeProp('selected');1038}1039}1040};1041// If this is to add the individual values within the array we need to loop over the array1042if (array) {1043for (var i = 0; i < value.filter.length; i++) {1044addOption(value.filter[i], value.text[i]);1045}1046}1047// Otherwise the value that is in the cell is to be added1048else {1049addOption(value.filter, Array.isArray(value.text) ? value.text.join(', ') : value.text);1050}1051}1052options.sort(function (a, b) {1053if (that.s.type === 'array' ||1054that.s.type === 'string' ||1055that.s.type === 'html') {1056if (a.val() < b.val()) {1057return -1;1058}1059else if (a.val() > b.val()) {1060return 1;1061}1062else {1063return 0;1064}1065}1066else if (that.s.type === 'num' ||1067that.s.type === 'html-num') {1068if (+a.val().replace(/(<([^>]+)>)/ig, '') < +b.val().replace(/(<([^>]+)>)/ig, '')) {1069return -1;1070}1071else if (+a.val().replace(/(<([^>]+)>)/ig, '') > +b.val().replace(/(<([^>]+)>)/ig, '')) {1072return 1;1073}1074else {1075return 0;1076}1077}1078else if (that.s.type === 'num-fmt' || that.s.type === 'html-num-fmt') {1079if (+a.val().replace(/[^0-9.]/g, '') < +b.val().replace(/[^0-9.]/g, '')) {1080return -1;1081}1082else if (+a.val().replace(/[^0-9.]/g, '') > +b.val().replace(/[^0-9.]/g, '')) {1083return 1;1084}1085else {1086return 0;1087}1088}1089});1090for (var _a = 0, options_1 = options; _a < options_1.length; _a++) {1091var opt = options_1[_a];1092el.append(opt);1093}1094return el;1095};1096/**1097* Default initialisation function for select array conditions
1098*
1099* This exists because there needs to be different select functionality for contains/without and equals/not
1100*/
1101Criteria.initSelectArray = function (that, fn, preDefined) {1102if (preDefined === void 0) { preDefined = null; }1103return Criteria.initSelect(that, fn, preDefined, true);1104};1105/**1106* Default initialisation function for input conditions
1107*/
1108Criteria.initInput = function (that, fn, preDefined) {1109if (preDefined === void 0) { preDefined = null; }1110// Declare the input element1111var searchDelay = that.s.dt.settings()[0].searchDelay;1112var el = $$2('<input/>')1113.addClass(Criteria.classes.value)1114.addClass(Criteria.classes.input)1115.on('input.dtsb keypress.dtsb', that._throttle(function (e) {1116var code = e.keyCode || e.which;1117if (!that.c.enterSearch &&1118!(that.s.dt.settings()[0].oInit.search !== undefined &&1119that.s.dt.settings()[0].oInit.search["return"]) ||1120code === 13) {1121return fn(that, this);1122}1123}, searchDelay === null ? 100 : searchDelay));1124if (that.c.greyscale) {1125el.addClass(Criteria.classes.greyscale);1126}1127// If there is a preDefined value then add it1128if (preDefined !== null) {1129el.val(preDefined[0]);1130}1131// This is add responsive functionality to the logic button without redrawing everything else1132that.s.dt.one('draw.dtsb', function () {1133that.s.topGroup.trigger('dtsb-redrawLogic');1134});1135return el;1136};1137/**1138* Default initialisation function for conditions requiring 2 inputs
1139*/
1140Criteria.init2Input = function (that, fn, preDefined) {1141if (preDefined === void 0) { preDefined = null; }1142// Declare all of the necessary jQuery elements1143var searchDelay = that.s.dt.settings()[0].searchDelay;1144var els = [1145$$2('<input/>')1146.addClass(Criteria.classes.value)1147.addClass(Criteria.classes.input)1148.on('input.dtsb keypress.dtsb', that._throttle(function (e) {1149var code = e.keyCode || e.which;1150if (!that.c.enterSearch &&1151!(that.s.dt.settings()[0].oInit.search !== undefined &&1152that.s.dt.settings()[0].oInit.search["return"]) ||1153code === 13) {1154return fn(that, this);1155}1156}, searchDelay === null ? 100 : searchDelay)),1157$$2('<span>')1158.addClass(that.classes.joiner)1159.html(that.s.dt.i18n('searchBuilder.valueJoiner', that.c.i18n.valueJoiner)),1160$$2('<input/>')1161.addClass(Criteria.classes.value)1162.addClass(Criteria.classes.input)1163.on('input.dtsb keypress.dtsb', that._throttle(function (e) {1164var code = e.keyCode || e.which;1165if (!that.c.enterSearch &&1166!(that.s.dt.settings()[0].oInit.search !== undefined &&1167that.s.dt.settings()[0].oInit.search["return"]) ||1168code === 13) {1169return fn(that, this);1170}1171}, searchDelay === null ? 100 : searchDelay))1172];1173if (that.c.greyscale) {1174els[0].addClass(Criteria.classes.greyscale);1175els[2].addClass(Criteria.classes.greyscale);1176}1177// If there is a preDefined value then add it1178if (preDefined !== null) {1179els[0].val(preDefined[0]);1180els[2].val(preDefined[1]);1181}1182// This is add responsive functionality to the logic button without redrawing everything else1183that.s.dt.one('draw.dtsb', function () {1184that.s.topGroup.trigger('dtsb-redrawLogic');1185});1186return els;1187};1188/**1189* Default initialisation function for date conditions
1190*/
1191Criteria.initDate = function (that, fn, preDefined) {1192if (preDefined === void 0) { preDefined = null; }1193var searchDelay = that.s.dt.settings()[0].searchDelay;1194// Declare date element using DataTables dateTime plugin1195var el = $$2('<input/>')1196.addClass(Criteria.classes.value)1197.addClass(Criteria.classes.input)1198.dtDateTime({1199attachTo: 'input',1200format: that.s.dateFormat ? that.s.dateFormat : undefined1201})1202.on('change.dtsb', that._throttle(function () {1203return fn(that, this);1204}, searchDelay === null ? 100 : searchDelay))1205.on('input.dtsb keypress.dtsb', that.c.enterSearch ||1206that.s.dt.settings()[0].oInit.search !== undefined &&1207that.s.dt.settings()[0].oInit.search["return"] ?1208function (e) {1209that._throttle(function () {1210var code = e.keyCode || e.which;1211if (code === 13) {1212return fn(that, this);1213}1214}, searchDelay === null ? 100 : searchDelay);1215} :1216that._throttle(function () {1217return fn(that, this);1218}, searchDelay === null ? 100 : searchDelay));1219if (that.c.greyscale) {1220el.addClass(Criteria.classes.greyscale);1221}1222// If there is a preDefined value then add it1223if (preDefined !== null) {1224el.val(preDefined[0]);1225}1226// This is add responsive functionality to the logic button without redrawing everything else1227that.s.dt.one('draw.dtsb', function () {1228that.s.topGroup.trigger('dtsb-redrawLogic');1229});1230return el;1231};1232Criteria.initNoValue = function (that) {1233// This is add responsive functionality to the logic button without redrawing everything else1234that.s.dt.one('draw.dtsb', function () {1235that.s.topGroup.trigger('dtsb-redrawLogic');1236});1237};1238Criteria.init2Date = function (that, fn, preDefined) {1239var _this = this;1240if (preDefined === void 0) { preDefined = null; }1241var searchDelay = that.s.dt.settings()[0].searchDelay;1242// Declare all of the date elements that are required using DataTables dateTime plugin1243var els = [1244$$2('<input/>')1245.addClass(Criteria.classes.value)1246.addClass(Criteria.classes.input)1247.dtDateTime({1248attachTo: 'input',1249format: that.s.dateFormat ? that.s.dateFormat : undefined1250})1251.on('change.dtsb', searchDelay !== null ?1252that.s.dt.settings()[0].oApi._fnThrottle(function () {1253return fn(that, this);1254}, searchDelay) :1255function () {1256fn(that, _this);1257})1258.on('input.dtsb keypress.dtsb', !that.c.enterSearch &&1259!(that.s.dt.settings()[0].oInit.search !== undefined &&1260that.s.dt.settings()[0].oInit.search["return"]) &&1261searchDelay !== null ?1262that.s.dt.settings()[0].oApi._fnThrottle(function () {1263return fn(that, this);1264}, searchDelay) :1265that.c.enterSearch ||1266that.s.dt.settings()[0].oInit.search !== undefined &&1267that.s.dt.settings()[0].oInit.search["return"] ?1268function (e) {1269var code = e.keyCode || e.which;1270if (code === 13) {1271fn(that, _this);1272}1273} :1274function () {1275fn(that, _this);1276}),1277$$2('<span>')1278.addClass(that.classes.joiner)1279.html(that.s.dt.i18n('searchBuilder.valueJoiner', that.c.i18n.valueJoiner)),1280$$2('<input/>')1281.addClass(Criteria.classes.value)1282.addClass(Criteria.classes.input)1283.dtDateTime({1284attachTo: 'input',1285format: that.s.dateFormat ? that.s.dateFormat : undefined1286})1287.on('change.dtsb', searchDelay !== null ?1288that.s.dt.settings()[0].oApi._fnThrottle(function () {1289return fn(that, this);1290}, searchDelay) :1291function () {1292fn(that, _this);1293})1294.on('input.dtsb keypress.dtsb', !that.c.enterSearch &&1295!(that.s.dt.settings()[0].oInit.search !== undefined &&1296that.s.dt.settings()[0].oInit.search["return"]) &&1297searchDelay !== null ?1298that.s.dt.settings()[0].oApi._fnThrottle(function () {1299return fn(that, this);1300}, searchDelay) :1301that.c.enterSearch ||1302that.s.dt.settings()[0].oInit.search !== undefined &&1303that.s.dt.settings()[0].oInit.search["return"] ?1304function (e) {1305var code = e.keyCode || e.which;1306if (code === 13) {1307fn(that, _this);1308}1309} :1310function () {1311fn(that, _this);1312})1313];1314if (that.c.greyscale) {1315els[0].addClass(Criteria.classes.greyscale);1316els[2].addClass(Criteria.classes.greyscale);1317}1318// If there are and preDefined values then add them1319if (preDefined !== null && preDefined.length > 0) {1320els[0].val(preDefined[0]);1321els[2].val(preDefined[1]);1322}1323// This is add responsive functionality to the logic button without redrawing everything else1324that.s.dt.one('draw.dtsb', function () {1325that.s.topGroup.trigger('dtsb-redrawLogic');1326});1327return els;1328};1329/**1330* Default function for select elements to validate condition
1331*/
1332Criteria.isInputValidSelect = function (el) {1333var allFilled = true;1334// Check each element to make sure that the selections are valid1335for (var _i = 0, el_1 = el; _i < el_1.length; _i++) {1336var element = el_1[_i];1337if (element.children('option:selected').length ===1338element.children('option').length -1339element.children('option.' + Criteria.classes.notItalic).length &&1340element.children('option:selected').length === 1 &&1341element.children('option:selected')[0] === element.children('option')[0]) {1342allFilled = false;1343}1344}1345return allFilled;1346};1347/**1348* Default function for input and date elements to validate condition
1349*/
1350Criteria.isInputValidInput = function (el) {1351var allFilled = true;1352// Check each element to make sure that the inputs are valid1353for (var _i = 0, el_2 = el; _i < el_2.length; _i++) {1354var element = el_2[_i];1355if (element.is('input') && element.val().length === 0) {1356allFilled = false;1357}1358}1359return allFilled;1360};1361/**1362* Default function for getting select conditions
1363*/
1364Criteria.inputValueSelect = function (el) {1365var values = [];1366// Go through the select elements and push each selected option to the return array1367for (var _i = 0, el_3 = el; _i < el_3.length; _i++) {1368var element = el_3[_i];1369if (element.is('select')) {1370values.push(Criteria._escapeHTML(element.children('option:selected').data('sbv')));1371}1372}1373return values;1374};1375/**1376* Default function for getting input conditions
1377*/
1378Criteria.inputValueInput = function (el) {1379var values = [];1380// Go through the input elements and push each value to the return array1381for (var _i = 0, el_4 = el; _i < el_4.length; _i++) {1382var element = el_4[_i];1383if (element.is('input')) {1384values.push(Criteria._escapeHTML(element.val()));1385}1386}1387return values;1388};1389/**1390* Function that is run on each element as a call back when a search should be triggered
1391*/
1392Criteria.updateListener = function (that, el) {1393// When the value is changed the criteria is now complete so can be included in searches1394// Get the condition from the map based on the key that has been selected for the condition1395var condition = that.s.conditions[that.s.condition];1396that.s.filled = condition.isInputValid(that.dom.value, that);1397that.s.value = condition.inputValue(that.dom.value, that);1398if (!that.s.filled) {1399that.s.dt.draw();1400return;1401}1402if (!Array.isArray(that.s.value)) {1403that.s.value = [that.s.value];1404}1405for (var i = 0; i < that.s.value.length; i++) {1406// If the value is an array we need to sort it1407if (Array.isArray(that.s.value[i])) {1408that.s.value[i].sort();1409}1410// Otherwise replace the decimal place character for i18n1411else if (that.s.type.includes('num') &&1412(that.s.dt.settings()[0].oLanguage.sDecimal !== '' ||1413that.s.dt.settings()[0].oLanguage.sThousands !== '')) {1414var splitRD = [that.s.value[i].toString()];1415if (that.s.dt.settings()[0].oLanguage.sDecimal !== '') {1416splitRD = that.s.value[i].split(that.s.dt.settings()[0].oLanguage.sDecimal);1417}1418if (that.s.dt.settings()[0].oLanguage.sThousands !== '') {1419for (var j = 0; j < splitRD.length; j++) {1420splitRD[j] = splitRD[j].replace(that.s.dt.settings()[0].oLanguage.sThousands, ',');1421}1422}1423that.s.value[i] = splitRD.join('.');1424}1425}1426// Take note of the cursor position so that we can refocus there later1427var idx = null;1428var cursorPos = null;1429for (var i = 0; i < that.dom.value.length; i++) {1430if (el === that.dom.value[i][0]) {1431idx = i;1432if (el.selectionStart !== undefined) {1433cursorPos = el.selectionStart;1434}1435}1436}1437// Trigger a search1438that.s.dt.draw();1439// Refocus the element and set the correct cursor position1440if (idx !== null) {1441that.dom.value[idx].removeClass(that.classes.italic);1442that.dom.value[idx].focus();1443if (cursorPos !== null) {1444that.dom.value[idx][0].setSelectionRange(cursorPos, cursorPos);1445}1446}1447};1448// The order of the conditions will make eslint sad :(1449// Has to be in this order so that they are displayed correctly in select elements1450// Also have to disable member ordering for this as the private methods used are not yet declared otherwise1451// eslint-disable-next-line @typescript-eslint/member-ordering1452Criteria.dateConditions = {1453'=': {1454conditionName: function (dt, i18n) {1455return dt.i18n('searchBuilder.conditions.date.equals', i18n.conditions.date.equals);1456},1457init: Criteria.initDate,1458inputValue: Criteria.inputValueInput,1459isInputValid: Criteria.isInputValidInput,1460search: function (value, comparison) {1461value = value.replace(/(\/|-|,)/g, '-');1462return value === comparison[0];1463}1464},1465// eslint-disable-next-line sort-keys1466'!=': {1467conditionName: function (dt, i18n) {1468return dt.i18n('searchBuilder.conditions.date.not', i18n.conditions.date.not);1469},1470init: Criteria.initDate,1471inputValue: Criteria.inputValueInput,1472isInputValid: Criteria.isInputValidInput,1473search: function (value, comparison) {1474value = value.replace(/(\/|-|,)/g, '-');1475return value !== comparison[0];1476}1477},1478'<': {1479conditionName: function (dt, i18n) {1480return dt.i18n('searchBuilder.conditions.date.before', i18n.conditions.date.before);1481},1482init: Criteria.initDate,1483inputValue: Criteria.inputValueInput,1484isInputValid: Criteria.isInputValidInput,1485search: function (value, comparison) {1486value = value.replace(/(\/|-|,)/g, '-');1487return value < comparison[0];1488}1489},1490'>': {1491conditionName: function (dt, i18n) {1492return dt.i18n('searchBuilder.conditions.date.after', i18n.conditions.date.after);1493},1494init: Criteria.initDate,1495inputValue: Criteria.inputValueInput,1496isInputValid: Criteria.isInputValidInput,1497search: function (value, comparison) {1498value = value.replace(/(\/|-|,)/g, '-');1499return value > comparison[0];1500}1501},1502'between': {1503conditionName: function (dt, i18n) {1504return dt.i18n('searchBuilder.conditions.date.between', i18n.conditions.date.between);1505},1506init: Criteria.init2Date,1507inputValue: Criteria.inputValueInput,1508isInputValid: Criteria.isInputValidInput,1509search: function (value, comparison) {1510value = value.replace(/(\/|-|,)/g, '-');1511if (comparison[0] < comparison[1]) {1512return comparison[0] <= value && value <= comparison[1];1513}1514else {1515return comparison[1] <= value && value <= comparison[0];1516}1517}1518},1519// eslint-disable-next-line sort-keys1520'!between': {1521conditionName: function (dt, i18n) {1522return dt.i18n('searchBuilder.conditions.date.notBetween', i18n.conditions.date.notBetween);1523},1524init: Criteria.init2Date,1525inputValue: Criteria.inputValueInput,1526isInputValid: Criteria.isInputValidInput,1527search: function (value, comparison) {1528value = value.replace(/(\/|-|,)/g, '-');1529if (comparison[0] < comparison[1]) {1530return !(comparison[0] <= value && value <= comparison[1]);1531}1532else {1533return !(comparison[1] <= value && value <= comparison[0]);1534}1535}1536},1537'null': {1538conditionName: function (dt, i18n) {1539return dt.i18n('searchBuilder.conditions.date.empty', i18n.conditions.date.empty);1540},1541init: Criteria.initNoValue,1542inputValue: function () {1543return;1544},1545isInputValid: function () {1546return true;1547},1548search: function (value) {1549return value === null || value === undefined || value.length === 0;1550}1551},1552// eslint-disable-next-line sort-keys1553'!null': {1554conditionName: function (dt, i18n) {1555return dt.i18n('searchBuilder.conditions.date.notEmpty', i18n.conditions.date.notEmpty);1556},1557init: Criteria.initNoValue,1558inputValue: function () {1559return;1560},1561isInputValid: function () {1562return true;1563},1564search: function (value) {1565return !(value === null || value === undefined || value.length === 0);1566}1567}1568};1569// The order of the conditions will make eslint sad :(1570// Has to be in this order so that they are displayed correctly in select elements1571// Also have to disable member ordering for this as the private methods used are not yet declared otherwise1572// eslint-disable-next-line @typescript-eslint/member-ordering1573Criteria.momentDateConditions = {1574'=': {1575conditionName: function (dt, i18n) {1576return dt.i18n('searchBuilder.conditions.date.equals', i18n.conditions.date.equals);1577},1578init: Criteria.initDate,1579inputValue: Criteria.inputValueInput,1580isInputValid: Criteria.isInputValidInput,1581search: function (value, comparison, that) {1582return moment(value, that.s.dateFormat).valueOf() ===1583moment(comparison[0], that.s.dateFormat).valueOf();1584}1585},1586// eslint-disable-next-line sort-keys1587'!=': {1588conditionName: function (dt, i18n) {1589return dt.i18n('searchBuilder.conditions.date.not', i18n.conditions.date.not);1590},1591init: Criteria.initDate,1592inputValue: Criteria.inputValueInput,1593isInputValid: Criteria.isInputValidInput,1594search: function (value, comparison, that) {1595return moment(value, that.s.dateFormat).valueOf() !==1596moment(comparison[0], that.s.dateFormat).valueOf();1597}1598},1599'<': {1600conditionName: function (dt, i18n) {1601return dt.i18n('searchBuilder.conditions.date.before', i18n.conditions.date.before);1602},1603init: Criteria.initDate,1604inputValue: Criteria.inputValueInput,1605isInputValid: Criteria.isInputValidInput,1606search: function (value, comparison, that) {1607return moment(value, that.s.dateFormat).valueOf() < moment(comparison[0], that.s.dateFormat).valueOf();1608}1609},1610'>': {1611conditionName: function (dt, i18n) {1612return dt.i18n('searchBuilder.conditions.date.after', i18n.conditions.date.after);1613},1614init: Criteria.initDate,1615inputValue: Criteria.inputValueInput,1616isInputValid: Criteria.isInputValidInput,1617search: function (value, comparison, that) {1618return moment(value, that.s.dateFormat).valueOf() > moment(comparison[0], that.s.dateFormat).valueOf();1619}1620},1621'between': {1622conditionName: function (dt, i18n) {1623return dt.i18n('searchBuilder.conditions.date.between', i18n.conditions.date.between);1624},1625init: Criteria.init2Date,1626inputValue: Criteria.inputValueInput,1627isInputValid: Criteria.isInputValidInput,1628search: function (value, comparison, that) {1629var val = moment(value, that.s.dateFormat).valueOf();1630var comp0 = moment(comparison[0], that.s.dateFormat).valueOf();1631var comp1 = moment(comparison[1], that.s.dateFormat).valueOf();1632if (comp0 < comp1) {1633return comp0 <= val && val <= comp1;1634}1635else {1636return comp1 <= val && val <= comp0;1637}1638}1639},1640// eslint-disable-next-line sort-keys1641'!between': {1642conditionName: function (dt, i18n) {1643return dt.i18n('searchBuilder.conditions.date.notBetween', i18n.conditions.date.notBetween);1644},1645init: Criteria.init2Date,1646inputValue: Criteria.inputValueInput,1647isInputValid: Criteria.isInputValidInput,1648search: function (value, comparison, that) {1649var val = moment(value, that.s.dateFormat).valueOf();1650var comp0 = moment(comparison[0], that.s.dateFormat).valueOf();1651var comp1 = moment(comparison[1], that.s.dateFormat).valueOf();1652if (comp0 < comp1) {1653return !(+comp0 <= +val && +val <= +comp1);1654}1655else {1656return !(+comp1 <= +val && +val <= +comp0);1657}1658}1659},1660'null': {1661conditionName: function (dt, i18n) {1662return dt.i18n('searchBuilder.conditions.date.empty', i18n.conditions.date.empty);1663},1664init: Criteria.initNoValue,1665inputValue: function () {1666return;1667},1668isInputValid: function () {1669return true;1670},1671search: function (value) {1672return value === null || value === undefined || value.length === 0;1673}1674},1675// eslint-disable-next-line sort-keys1676'!null': {1677conditionName: function (dt, i18n) {1678return dt.i18n('searchBuilder.conditions.date.notEmpty', i18n.conditions.date.notEmpty);1679},1680init: Criteria.initNoValue,1681inputValue: function () {1682return;1683},1684isInputValid: function () {1685return true;1686},1687search: function (value) {1688return !(value === null || value === undefined || value.length === 0);1689}1690}1691};1692// The order of the conditions will make eslint sad :(1693// Has to be in this order so that they are displayed correctly in select elements1694// Also have to disable member ordering for this as the private methods used are not yet declared otherwise1695// eslint-disable-next-line @typescript-eslint/member-ordering1696Criteria.luxonDateConditions = {1697'=': {1698conditionName: function (dt, i18n) {1699return dt.i18n('searchBuilder.conditions.date.equals', i18n.conditions.date.equals);1700},1701init: Criteria.initDate,1702inputValue: Criteria.inputValueInput,1703isInputValid: Criteria.isInputValidInput,1704search: function (value, comparison, that) {1705return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts1706=== luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;1707}1708},1709// eslint-disable-next-line sort-keys1710'!=': {1711conditionName: function (dt, i18n) {1712return dt.i18n('searchBuilder.conditions.date.not', i18n.conditions.date.not);1713},1714init: Criteria.initDate,1715inputValue: Criteria.inputValueInput,1716isInputValid: Criteria.isInputValidInput,1717search: function (value, comparison, that) {1718return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts1719!== luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;1720}1721},1722'<': {1723conditionName: function (dt, i18n) {1724return dt.i18n('searchBuilder.conditions.date.before', i18n.conditions.date.before);1725},1726init: Criteria.initDate,1727inputValue: Criteria.inputValueInput,1728isInputValid: Criteria.isInputValidInput,1729search: function (value, comparison, that) {1730return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts1731< luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;1732}1733},1734'>': {1735conditionName: function (dt, i18n) {1736return dt.i18n('searchBuilder.conditions.date.after', i18n.conditions.date.after);1737},1738init: Criteria.initDate,1739inputValue: Criteria.inputValueInput,1740isInputValid: Criteria.isInputValidInput,1741search: function (value, comparison, that) {1742return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts1743> luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;1744}1745},1746'between': {1747conditionName: function (dt, i18n) {1748return dt.i18n('searchBuilder.conditions.date.between', i18n.conditions.date.between);1749},1750init: Criteria.init2Date,1751inputValue: Criteria.inputValueInput,1752isInputValid: Criteria.isInputValidInput,1753search: function (value, comparison, that) {1754var val = luxon.DateTime.fromFormat(value, that.s.dateFormat).ts;1755var comp0 = luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;1756var comp1 = luxon.DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;1757if (comp0 < comp1) {1758return comp0 <= val && val <= comp1;1759}1760else {1761return comp1 <= val && val <= comp0;1762}1763}1764},1765// eslint-disable-next-line sort-keys1766'!between': {1767conditionName: function (dt, i18n) {1768return dt.i18n('searchBuilder.conditions.date.notBetween', i18n.conditions.date.notBetween);1769},1770init: Criteria.init2Date,1771inputValue: Criteria.inputValueInput,1772isInputValid: Criteria.isInputValidInput,1773search: function (value, comparison, that) {1774var val = luxon.DateTime.fromFormat(value, that.s.dateFormat).ts;1775var comp0 = luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;1776var comp1 = luxon.DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;1777if (comp0 < comp1) {1778return !(+comp0 <= +val && +val <= +comp1);1779}1780else {1781return !(+comp1 <= +val && +val <= +comp0);1782}1783}1784},1785'null': {1786conditionName: function (dt, i18n) {1787return dt.i18n('searchBuilder.conditions.date.empty', i18n.conditions.date.empty);1788},1789init: Criteria.initNoValue,1790inputValue: function () {1791return;1792},1793isInputValid: function () {1794return true;1795},1796search: function (value) {1797return value === null || value === undefined || value.length === 0;1798}1799},1800// eslint-disable-next-line sort-keys1801'!null': {1802conditionName: function (dt, i18n) {1803return dt.i18n('searchBuilder.conditions.date.notEmpty', i18n.conditions.date.notEmpty);1804},1805init: Criteria.initNoValue,1806inputValue: function () {1807return;1808},1809isInputValid: function () {1810return true;1811},1812search: function (value) {1813return !(value === null || value === undefined || value.length === 0);1814}1815}1816};1817// The order of the conditions will make eslint sad :(1818// Has to be in this order so that they are displayed correctly in select elements1819// Also have to disable member ordering for this as the private methods used are not yet declared otherwise1820// eslint-disable-next-line @typescript-eslint/member-ordering1821Criteria.numConditions = {1822'=': {1823conditionName: function (dt, i18n) {1824return dt.i18n('searchBuilder.conditions.number.equals', i18n.conditions.number.equals);1825},1826init: Criteria.initSelect,1827inputValue: Criteria.inputValueSelect,1828isInputValid: Criteria.isInputValidSelect,1829search: function (value, comparison) {1830return +value === +comparison[0];1831}1832},1833// eslint-disable-next-line sort-keys1834'!=': {1835conditionName: function (dt, i18n) {1836return dt.i18n('searchBuilder.conditions.number.not', i18n.conditions.number.not);1837},1838init: Criteria.initSelect,1839inputValue: Criteria.inputValueSelect,1840isInputValid: Criteria.isInputValidSelect,1841search: function (value, comparison) {1842return +value !== +comparison[0];1843}1844},1845'<': {1846conditionName: function (dt, i18n) {1847return dt.i18n('searchBuilder.conditions.number.lt', i18n.conditions.number.lt);1848},1849init: Criteria.initInput,1850inputValue: Criteria.inputValueInput,1851isInputValid: Criteria.isInputValidInput,1852search: function (value, comparison) {1853return +value < +comparison[0];1854}1855},1856'<=': {1857conditionName: function (dt, i18n) {1858return dt.i18n('searchBuilder.conditions.number.lte', i18n.conditions.number.lte);1859},1860init: Criteria.initInput,1861inputValue: Criteria.inputValueInput,1862isInputValid: Criteria.isInputValidInput,1863search: function (value, comparison) {1864return +value <= +comparison[0];1865}1866},1867'>=': {1868conditionName: function (dt, i18n) {1869return dt.i18n('searchBuilder.conditions.number.gte', i18n.conditions.number.gte);1870},1871init: Criteria.initInput,1872inputValue: Criteria.inputValueInput,1873isInputValid: Criteria.isInputValidInput,1874search: function (value, comparison) {1875return +value >= +comparison[0];1876}1877},1878// eslint-disable-next-line sort-keys1879'>': {1880conditionName: function (dt, i18n) {1881return dt.i18n('searchBuilder.conditions.number.gt', i18n.conditions.number.gt);1882},1883init: Criteria.initInput,1884inputValue: Criteria.inputValueInput,1885isInputValid: Criteria.isInputValidInput,1886search: function (value, comparison) {1887return +value > +comparison[0];1888}1889},1890'between': {1891conditionName: function (dt, i18n) {1892return dt.i18n('searchBuilder.conditions.number.between', i18n.conditions.number.between);1893},1894init: Criteria.init2Input,1895inputValue: Criteria.inputValueInput,1896isInputValid: Criteria.isInputValidInput,1897search: function (value, comparison) {1898if (+comparison[0] < +comparison[1]) {1899return +comparison[0] <= +value && +value <= +comparison[1];1900}1901else {1902return +comparison[1] <= +value && +value <= +comparison[0];1903}1904}1905},1906// eslint-disable-next-line sort-keys1907'!between': {1908conditionName: function (dt, i18n) {1909return dt.i18n('searchBuilder.conditions.number.notBetween', i18n.conditions.number.notBetween);1910},1911init: Criteria.init2Input,1912inputValue: Criteria.inputValueInput,1913isInputValid: Criteria.isInputValidInput,1914search: function (value, comparison) {1915if (+comparison[0] < +comparison[1]) {1916return !(+comparison[0] <= +value && +value <= +comparison[1]);1917}1918else {1919return !(+comparison[1] <= +value && +value <= +comparison[0]);1920}1921}1922},1923'null': {1924conditionName: function (dt, i18n) {1925return dt.i18n('searchBuilder.conditions.number.empty', i18n.conditions.number.empty);1926},1927init: Criteria.initNoValue,1928inputValue: function () {1929return;1930},1931isInputValid: function () {1932return true;1933},1934search: function (value) {1935return value === null || value === undefined || value.length === 0;1936}1937},1938// eslint-disable-next-line sort-keys1939'!null': {1940conditionName: function (dt, i18n) {1941return dt.i18n('searchBuilder.conditions.number.notEmpty', i18n.conditions.number.notEmpty);1942},1943init: Criteria.initNoValue,1944inputValue: function () {1945return;1946},1947isInputValid: function () {1948return true;1949},1950search: function (value) {1951return !(value === null || value === undefined || value.length === 0);1952}1953}1954};1955// The order of the conditions will make eslint sad :(1956// Has to be in this order so that they are displayed correctly in select elements1957// Also have to disable member ordering for this as the private methods used are not yet declared otherwise1958// eslint-disable-next-line @typescript-eslint/member-ordering1959Criteria.numFmtConditions = {1960'=': {1961conditionName: function (dt, i18n) {1962return dt.i18n('searchBuilder.conditions.number.equals', i18n.conditions.number.equals);1963},1964init: Criteria.initSelect,1965inputValue: Criteria.inputValueSelect,1966isInputValid: Criteria.isInputValidSelect,1967search: function (value, comparison) {1968var val = value.indexOf('-') === 0 ?1969'-' + value.replace(/[^0-9.]/g, '') :1970value.replace(/[^0-9.]/g, '');1971var comp = comparison[0].indexOf('-') === 0 ?1972'-' + comparison[0].replace(/[^0-9.]/g, '') :1973comparison[0].replace(/[^0-9.]/g, '');1974return +val === +comp;1975}1976},1977// eslint-disable-next-line sort-keys1978'!=': {1979conditionName: function (dt, i18n) {1980return dt.i18n('searchBuilder.conditions.number.not', i18n.conditions.number.not);1981},1982init: Criteria.initSelect,1983inputValue: Criteria.inputValueSelect,1984isInputValid: Criteria.isInputValidSelect,1985search: function (value, comparison) {1986var val = value.indexOf('-') === 0 ?1987'-' + value.replace(/[^0-9.]/g, '') :1988value.replace(/[^0-9.]/g, '');1989var comp = comparison[0].indexOf('-') === 0 ?1990'-' + comparison[0].replace(/[^0-9.]/g, '') :1991comparison[0].replace(/[^0-9.]/g, '');1992return +val !== +comp;1993}1994},1995'<': {1996conditionName: function (dt, i18n) {1997return dt.i18n('searchBuilder.conditions.number.lt', i18n.conditions.number.lt);1998},1999init: Criteria.initInput,2000inputValue: Criteria.inputValueInput,2001isInputValid: Criteria.isInputValidInput,2002search: function (value, comparison) {2003var val = value.indexOf('-') === 0 ?2004'-' + value.replace(/[^0-9.]/g, '') :2005value.replace(/[^0-9.]/g, '');2006var comp = comparison[0].indexOf('-') === 0 ?2007'-' + comparison[0].replace(/[^0-9.]/g, '') :2008comparison[0].replace(/[^0-9.]/g, '');2009return +val < +comp;2010}2011},2012'<=': {2013conditionName: function (dt, i18n) {2014return dt.i18n('searchBuilder.conditions.number.lte', i18n.conditions.number.lte);2015},2016init: Criteria.initInput,2017inputValue: Criteria.inputValueInput,2018isInputValid: Criteria.isInputValidInput,2019search: function (value, comparison) {2020var val = value.indexOf('-') === 0 ?2021'-' + value.replace(/[^0-9.]/g, '') :2022value.replace(/[^0-9.]/g, '');2023var comp = comparison[0].indexOf('-') === 0 ?2024'-' + comparison[0].replace(/[^0-9.]/g, '') :2025comparison[0].replace(/[^0-9.]/g, '');2026return +val <= +comp;2027}2028},2029'>=': {2030conditionName: function (dt, i18n) {2031return dt.i18n('searchBuilder.conditions.number.gte', i18n.conditions.number.gte);2032},2033init: Criteria.initInput,2034inputValue: Criteria.inputValueInput,2035isInputValid: Criteria.isInputValidInput,2036search: function (value, comparison) {2037var val = value.indexOf('-') === 0 ?2038'-' + value.replace(/[^0-9.]/g, '') :2039value.replace(/[^0-9.]/g, '');2040var comp = comparison[0].indexOf('-') === 0 ?2041'-' + comparison[0].replace(/[^0-9.]/g, '') :2042comparison[0].replace(/[^0-9.]/g, '');2043return +val >= +comp;2044}2045},2046// eslint-disable-next-line sort-keys2047'>': {2048conditionName: function (dt, i18n) {2049return dt.i18n('searchBuilder.conditions.number.gt', i18n.conditions.number.gt);2050},2051init: Criteria.initInput,2052inputValue: Criteria.inputValueInput,2053isInputValid: Criteria.isInputValidInput,2054search: function (value, comparison) {2055var val = value.indexOf('-') === 0 ?2056'-' + value.replace(/[^0-9.]/g, '') :2057value.replace(/[^0-9.]/g, '');2058var comp = comparison[0].indexOf('-') === 0 ?2059'-' + comparison[0].replace(/[^0-9.]/g, '') :2060comparison[0].replace(/[^0-9.]/g, '');2061return +val > +comp;2062}2063},2064'between': {2065conditionName: function (dt, i18n) {2066return dt.i18n('searchBuilder.conditions.number.between', i18n.conditions.number.between);2067},2068init: Criteria.init2Input,2069inputValue: Criteria.inputValueInput,2070isInputValid: Criteria.isInputValidInput,2071search: function (value, comparison) {2072var val = value.indexOf('-') === 0 ?2073'-' + value.replace(/[^0-9.]/g, '') :2074value.replace(/[^0-9.]/g, '');2075var comp0 = comparison[0].indexOf('-') === 0 ?2076'-' + comparison[0].replace(/[^0-9.]/g, '') :2077comparison[0].replace(/[^0-9.]/g, '');2078var comp1 = comparison[1].indexOf('-') === 0 ?2079'-' + comparison[1].replace(/[^0-9.]/g, '') :2080comparison[1].replace(/[^0-9.]/g, '');2081if (+comp0 < +comp1) {2082return +comp0 <= +val && +val <= +comp1;2083}2084else {2085return +comp1 <= +val && +val <= +comp0;2086}2087}2088},2089// eslint-disable-next-line sort-keys2090'!between': {2091conditionName: function (dt, i18n) {2092return dt.i18n('searchBuilder.conditions.number.notBetween', i18n.conditions.number.notBetween);2093},2094init: Criteria.init2Input,2095inputValue: Criteria.inputValueInput,2096isInputValid: Criteria.isInputValidInput,2097search: function (value, comparison) {2098var val = value.indexOf('-') === 0 ?2099'-' + value.replace(/[^0-9.]/g, '') :2100value.replace(/[^0-9.]/g, '');2101var comp0 = comparison[0].indexOf('-') === 0 ?2102'-' + comparison[0].replace(/[^0-9.]/g, '') :2103comparison[0].replace(/[^0-9.]/g, '');2104var comp1 = comparison[1].indexOf('-') === 0 ?2105'-' + comparison[1].replace(/[^0-9.]/g, '') :2106comparison[1].replace(/[^0-9.]/g, '');2107if (+comp0 < +comp1) {2108return !(+comp0 <= +val && +val <= +comp1);2109}2110else {2111return !(+comp1 <= +val && +val <= +comp0);2112}2113}2114},2115'null': {2116conditionName: function (dt, i18n) {2117return dt.i18n('searchBuilder.conditions.number.empty', i18n.conditions.number.empty);2118},2119init: Criteria.initNoValue,2120inputValue: function () {2121return;2122},2123isInputValid: function () {2124return true;2125},2126search: function (value) {2127return value === null || value === undefined || value.length === 0;2128}2129},2130// eslint-disable-next-line sort-keys2131'!null': {2132conditionName: function (dt, i18n) {2133return dt.i18n('searchBuilder.conditions.number.notEmpty', i18n.conditions.number.notEmpty);2134},2135init: Criteria.initNoValue,2136inputValue: function () {2137return;2138},2139isInputValid: function () {2140return true;2141},2142search: function (value) {2143return !(value === null || value === undefined || value.length === 0);2144}2145}2146};2147// The order of the conditions will make eslint sad :(2148// Has to be in this order so that they are displayed correctly in select elements2149// Also have to disable member ordering for this as the private methods used are not yet declared otherwise2150// eslint-disable-next-line @typescript-eslint/member-ordering2151Criteria.stringConditions = {2152'=': {2153conditionName: function (dt, i18n) {2154return dt.i18n('searchBuilder.conditions.string.equals', i18n.conditions.string.equals);2155},2156init: Criteria.initSelect,2157inputValue: Criteria.inputValueSelect,2158isInputValid: Criteria.isInputValidSelect,2159search: function (value, comparison) {2160return value === comparison[0];2161}2162},2163// eslint-disable-next-line sort-keys2164'!=': {2165conditionName: function (dt, i18n) {2166return dt.i18n('searchBuilder.conditions.string.not', i18n.conditions.string.not);2167},2168init: Criteria.initSelect,2169inputValue: Criteria.inputValueSelect,2170isInputValid: Criteria.isInputValidInput,2171search: function (value, comparison) {2172return value !== comparison[0];2173}2174},2175'starts': {2176conditionName: function (dt, i18n) {2177return dt.i18n('searchBuilder.conditions.string.startsWith', i18n.conditions.string.startsWith);2178},2179init: Criteria.initInput,2180inputValue: Criteria.inputValueInput,2181isInputValid: Criteria.isInputValidInput,2182search: function (value, comparison) {2183return value.toLowerCase().indexOf(comparison[0].toLowerCase()) === 0;2184}2185},2186// eslint-disable-next-line sort-keys2187'!starts': {2188conditionName: function (dt, i18n) {2189return dt.i18n('searchBuilder.conditions.string.notStartsWith', i18n.conditions.string.notStartsWith);2190},2191init: Criteria.initInput,2192inputValue: Criteria.inputValueInput,2193isInputValid: Criteria.isInputValidInput,2194search: function (value, comparison) {2195return value.toLowerCase().indexOf(comparison[0].toLowerCase()) !== 0;2196}2197},2198// eslint-disable-next-line sort-keys2199'contains': {2200conditionName: function (dt, i18n) {2201return dt.i18n('searchBuilder.conditions.string.contains', i18n.conditions.string.contains);2202},2203init: Criteria.initInput,2204inputValue: Criteria.inputValueInput,2205isInputValid: Criteria.isInputValidInput,2206search: function (value, comparison) {2207return value.toLowerCase().includes(comparison[0].toLowerCase());2208}2209},2210// eslint-disable-next-line sort-keys2211'!contains': {2212conditionName: function (dt, i18n) {2213return dt.i18n('searchBuilder.conditions.string.notContains', i18n.conditions.string.notContains);2214},2215init: Criteria.initInput,2216inputValue: Criteria.inputValueInput,2217isInputValid: Criteria.isInputValidInput,2218search: function (value, comparison) {2219return !value.toLowerCase().includes(comparison[0].toLowerCase());2220}2221},2222'ends': {2223conditionName: function (dt, i18n) {2224return dt.i18n('searchBuilder.conditions.string.endsWith', i18n.conditions.string.endsWith);2225},2226init: Criteria.initInput,2227inputValue: Criteria.inputValueInput,2228isInputValid: Criteria.isInputValidInput,2229search: function (value, comparison) {2230return value.toLowerCase().endsWith(comparison[0].toLowerCase());2231}2232},2233// eslint-disable-next-line sort-keys2234'!ends': {2235conditionName: function (dt, i18n) {2236return dt.i18n('searchBuilder.conditions.string.notEndsWith', i18n.conditions.string.notEndsWith);2237},2238init: Criteria.initInput,2239inputValue: Criteria.inputValueInput,2240isInputValid: Criteria.isInputValidInput,2241search: function (value, comparison) {2242return !value.toLowerCase().endsWith(comparison[0].toLowerCase());2243}2244},2245'null': {2246conditionName: function (dt, i18n) {2247return dt.i18n('searchBuilder.conditions.string.empty', i18n.conditions.string.empty);2248},2249init: Criteria.initNoValue,2250inputValue: function () {2251return;2252},2253isInputValid: function () {2254return true;2255},2256search: function (value) {2257return value === null || value === undefined || value.length === 0;2258}2259},2260// eslint-disable-next-line sort-keys2261'!null': {2262conditionName: function (dt, i18n) {2263return dt.i18n('searchBuilder.conditions.string.notEmpty', i18n.conditions.string.notEmpty);2264},2265init: Criteria.initNoValue,2266inputValue: function () {2267return;2268},2269isInputValid: function () {2270return true;2271},2272search: function (value) {2273return !(value === null || value === undefined || value.length === 0);2274}2275}2276};2277// The order of the conditions will make eslint sad :(2278// Also have to disable member ordering for this as the private methods used are not yet declared otherwise2279// eslint-disable-next-line @typescript-eslint/member-ordering2280Criteria.arrayConditions = {2281'contains': {2282conditionName: function (dt, i18n) {2283return dt.i18n('searchBuilder.conditions.array.contains', i18n.conditions.array.contains);2284},2285init: Criteria.initSelectArray,2286inputValue: Criteria.inputValueSelect,2287isInputValid: Criteria.isInputValidSelect,2288search: function (value, comparison) {2289return value.includes(comparison[0]);2290}2291},2292'without': {2293conditionName: function (dt, i18n) {2294return dt.i18n('searchBuilder.conditions.array.without', i18n.conditions.array.without);2295},2296init: Criteria.initSelectArray,2297inputValue: Criteria.inputValueSelect,2298isInputValid: Criteria.isInputValidSelect,2299search: function (value, comparison) {2300return value.indexOf(comparison[0]) === -1;2301}2302},2303// eslint-disable-next-line sort-keys2304'=': {2305conditionName: function (dt, i18n) {2306return dt.i18n('searchBuilder.conditions.array.equals', i18n.conditions.array.equals);2307},2308init: Criteria.initSelect,2309inputValue: Criteria.inputValueSelect,2310isInputValid: Criteria.isInputValidSelect,2311search: function (value, comparison) {2312if (value.length === comparison[0].length) {2313for (var i = 0; i < value.length; i++) {2314if (value[i] !== comparison[0][i]) {2315return false;2316}2317}2318return true;2319}2320return false;2321}2322},2323// eslint-disable-next-line sort-keys2324'!=': {2325conditionName: function (dt, i18n) {2326return dt.i18n('searchBuilder.conditions.array.not', i18n.conditions.array.not);2327},2328init: Criteria.initSelect,2329inputValue: Criteria.inputValueSelect,2330isInputValid: Criteria.isInputValidSelect,2331search: function (value, comparison) {2332if (value.length === comparison[0].length) {2333for (var i = 0; i < value.length; i++) {2334if (value[i] !== comparison[0][i]) {2335return true;2336}2337}2338return false;2339}2340return true;2341}2342},2343'null': {2344conditionName: function (dt, i18n) {2345return dt.i18n('searchBuilder.conditions.array.empty', i18n.conditions.array.empty);2346},2347init: Criteria.initNoValue,2348inputValue: function () {2349return;2350},2351isInputValid: function () {2352return true;2353},2354search: function (value) {2355return value === null || value === undefined || value.length === 0;2356}2357},2358// eslint-disable-next-line sort-keys2359'!null': {2360conditionName: function (dt, i18n) {2361return dt.i18n('searchBuilder.conditions.array.notEmpty', i18n.conditions.array.notEmpty);2362},2363init: Criteria.initNoValue,2364inputValue: function () {2365return;2366},2367isInputValid: function () {2368return true;2369},2370search: function (value) {2371return value !== null && value !== undefined && value.length !== 0;2372}2373}2374};2375// eslint will be sad because we have to disable member ordering for this as the2376// private static properties used are not yet declared otherwise2377// eslint-disable-next-line @typescript-eslint/member-ordering2378Criteria.defaults = {2379columns: true,2380conditions: {2381'array': Criteria.arrayConditions,2382'date': Criteria.dateConditions,2383'html': Criteria.stringConditions,2384'html-num': Criteria.numConditions,2385'html-num-fmt': Criteria.numFmtConditions,2386'luxon': Criteria.luxonDateConditions,2387'moment': Criteria.momentDateConditions,2388'num': Criteria.numConditions,2389'num-fmt': Criteria.numFmtConditions,2390'string': Criteria.stringConditions2391},2392depthLimit: false,2393enterSearch: false,2394filterChanged: undefined,2395greyscale: false,2396i18n: {2397add: 'Add Condition',2398button: {23990: 'Search Builder',2400_: 'Search Builder (%d)'2401},2402clearAll: 'Clear All',2403condition: 'Condition',2404data: 'Data',2405"delete": '×',2406deleteTitle: 'Delete filtering rule',2407left: '<',2408leftTitle: 'Outdent criteria',2409logicAnd: 'And',2410logicOr: 'Or',2411right: '>',2412rightTitle: 'Indent criteria',2413title: {24140: 'Custom Search Builder',2415_: 'Custom Search Builder (%d)'2416},2417value: 'Value',2418valueJoiner: 'and'2419},2420logic: 'AND',2421orthogonal: {2422display: 'display',2423search: 'filter'2424},2425preDefined: false2426};2427return Criteria;2428}());2429
2430var $$1;2431var dataTable$1;2432/**2433* Sets the value of jQuery for use in the file
2434*
2435* @param jq the instance of jQuery to be set
2436*/
2437function setJQuery$1(jq) {2438$$1 = jq;2439dataTable$1 = jq.fn.dataTable;2440}2441/**2442* The Group class is used within SearchBuilder to represent a group of criteria
2443*/
2444var Group = /** @class */ (function () {2445function Group(table, opts, topGroup, index, isChild, depth) {2446if (index === void 0) { index = 0; }2447if (isChild === void 0) { isChild = false; }2448if (depth === void 0) { depth = 1; }2449// Check that the required version of DataTables is included2450if (!dataTable$1 || !dataTable$1.versionCheck || !dataTable$1.versionCheck('1.10.0')) {2451throw new Error('SearchBuilder requires DataTables 1.10 or newer');2452}2453this.classes = $$1.extend(true, {}, Group.classes);2454// Get options from user2455this.c = $$1.extend(true, {}, Group.defaults, opts);2456this.s = {2457criteria: [],2458depth: depth,2459dt: table,2460index: index,2461isChild: isChild,2462logic: undefined,2463opts: opts,2464preventRedraw: false,2465toDrop: undefined,2466topGroup: topGroup2467};2468this.dom = {2469add: $$1('<button/>')2470.addClass(this.classes.add)2471.addClass(this.classes.button)2472.attr('type', 'button'),2473clear: $$1('<button>×</button>')2474.addClass(this.classes.button)2475.addClass(this.classes.clearGroup)2476.attr('type', 'button'),2477container: $$1('<div/>')2478.addClass(this.classes.group),2479logic: $$1('<button><div/></button>')2480.addClass(this.classes.logic)2481.addClass(this.classes.button)2482.attr('type', 'button'),2483logicContainer: $$1('<div/>')2484.addClass(this.classes.logicContainer)2485};2486// A reference to the top level group is maintained throughout any subgroups and criteria that may be created2487if (this.s.topGroup === undefined) {2488this.s.topGroup = this.dom.container;2489}2490this._setup();2491return this;2492}2493/**2494* Destroys the groups buttons, clears the internal criteria and removes it from the dom
2495*/
2496Group.prototype.destroy = function () {2497// Turn off listeners2498this.dom.add.off('.dtsb');2499this.dom.logic.off('.dtsb');2500// Trigger event for groups at a higher level to pick up on2501this.dom.container2502.trigger('dtsb-destroy')2503.remove();2504this.s.criteria = [];2505};2506/**2507* Gets the details required to rebuild the group
2508*/
2509// Eslint upset at empty object but needs to be done2510// eslint-disable-next-line @typescript-eslint/ban-types2511Group.prototype.getDetails = function (deFormatDates) {2512if (deFormatDates === void 0) { deFormatDates = false; }2513if (this.s.criteria.length === 0) {2514return {};2515}2516var details = {2517criteria: [],2518logic: this.s.logic2519};2520// NOTE here crit could be either a subgroup or a criteria2521for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {2522var crit = _a[_i];2523details.criteria.push(crit.criteria.getDetails(deFormatDates));2524}2525return details;2526};2527/**2528* Getter for the node for the container of the group
2529*
2530* @returns Node for the container of the group
2531*/
2532Group.prototype.getNode = function () {2533return this.dom.container;2534};2535/**2536* Rebuilds the group based upon the details passed in
2537*
2538* @param loadedDetails the details required to rebuild the group
2539*/
2540Group.prototype.rebuild = function (loadedDetails) {2541// If no criteria are stored then just return2542if (loadedDetails.criteria === undefined ||2543loadedDetails.criteria === null ||2544Array.isArray(loadedDetails.criteria) && loadedDetails.criteria.length === 0) {2545return;2546}2547this.s.logic = loadedDetails.logic;2548this.dom.logic.children().first().html(this.s.logic === 'OR'2549? this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr)2550: this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));2551// Add all of the criteria, be it a sub group or a criteria2552if (Array.isArray(loadedDetails.criteria)) {2553for (var _i = 0, _a = loadedDetails.criteria; _i < _a.length; _i++) {2554var crit = _a[_i];2555if (crit.logic !== undefined) {2556this._addPrevGroup(crit);2557}2558else if (crit.logic === undefined) {2559this._addPrevCriteria(crit);2560}2561}2562}2563// For all of the criteria children, update the arrows incase they require changing and set the listeners2564for (var _b = 0, _c = this.s.criteria; _b < _c.length; _b++) {2565var crit = _c[_b];2566if (crit.criteria instanceof Criteria) {2567crit.criteria.updateArrows(this.s.criteria.length > 1, false);2568this._setCriteriaListeners(crit.criteria);2569}2570}2571};2572/**2573* Redraws the Contents of the searchBuilder Groups and Criteria
2574*/
2575Group.prototype.redrawContents = function () {2576if (this.s.preventRedraw) {2577return;2578}2579// Clear the container out and add the basic elements2580this.dom.container.children().detach();2581this.dom.container2582.append(this.dom.logicContainer)2583.append(this.dom.add);2584// Sort the criteria by index so that they appear in the correct order2585this.s.criteria.sort(function (a, b) {2586if (a.criteria.s.index < b.criteria.s.index) {2587return -1;2588}2589else if (a.criteria.s.index > b.criteria.s.index) {2590return 1;2591}2592return 0;2593});2594this.setListeners();2595for (var i = 0; i < this.s.criteria.length; i++) {2596var crit = this.s.criteria[i].criteria;2597if (crit instanceof Criteria) {2598// Reset the index to the new value2599this.s.criteria[i].index = i;2600this.s.criteria[i].criteria.s.index = i;2601// Add to the group2602this.s.criteria[i].criteria.dom.container.insertBefore(this.dom.add);2603// Set listeners for various points2604this._setCriteriaListeners(crit);2605this.s.criteria[i].criteria.rebuild(this.s.criteria[i].criteria.getDetails());2606}2607else if (crit instanceof Group && crit.s.criteria.length > 0) {2608// Reset the index to the new value2609this.s.criteria[i].index = i;2610this.s.criteria[i].criteria.s.index = i;2611// Add the sub group to the group2612this.s.criteria[i].criteria.dom.container.insertBefore(this.dom.add);2613// Redraw the contents of the group2614crit.redrawContents();2615this._setGroupListeners(crit);2616}2617else {2618// The group is empty so remove it2619this.s.criteria.splice(i, 1);2620i--;2621}2622}2623this.setupLogic();2624};2625/**2626* Resizes the logic button only rather than the entire dom.
2627*/
2628Group.prototype.redrawLogic = function () {2629for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {2630var crit = _a[_i];2631if (crit instanceof Group) {2632crit.redrawLogic();2633}2634}2635this.setupLogic();2636};2637/**2638* Search method, checking the row data against the criteria in the group
2639*
2640* @param rowData The row data to be compared
2641* @returns boolean The result of the search
2642*/
2643Group.prototype.search = function (rowData, rowIdx) {2644if (this.s.logic === 'AND') {2645return this._andSearch(rowData, rowIdx);2646}2647else if (this.s.logic === 'OR') {2648return this._orSearch(rowData, rowIdx);2649}2650return true;2651};2652/**2653* Locates the groups logic button to the correct location on the page
2654*/
2655Group.prototype.setupLogic = function () {2656// Remove logic button2657this.dom.logicContainer.remove();2658this.dom.clear.remove();2659// If there are no criteria in the group then keep the logic removed and return2660if (this.s.criteria.length < 1) {2661if (!this.s.isChild) {2662this.dom.container.trigger('dtsb-destroy');2663// Set criteria left margin2664this.dom.container.css('margin-left', 0);2665}2666return;2667}2668// Set width, take 2 for the border2669var height = this.dom.container.height() - 1;2670this.dom.clear.height('0px');2671this.dom.logicContainer.append(this.dom.clear).width(height);2672// Prepend logic button2673this.dom.container.prepend(this.dom.logicContainer);2674this._setLogicListener();2675// Set criteria left margin2676this.dom.container.css('margin-left', this.dom.logicContainer.outerHeight(true));2677var logicOffset = this.dom.logicContainer.offset();2678// Set horizontal alignment2679var currentLeft = logicOffset.left;2680var groupLeft = this.dom.container.offset().left;2681var shuffleLeft = currentLeft - groupLeft;2682var newPos = currentLeft - shuffleLeft - this.dom.logicContainer.outerHeight(true);2683this.dom.logicContainer.offset({ left: newPos });2684// Set vertical alignment2685var firstCrit = this.dom.logicContainer.next();2686var currentTop = logicOffset.top;2687var firstTop = $$1(firstCrit).offset().top;2688var shuffleTop = currentTop - firstTop;2689var newTop = currentTop - shuffleTop;2690this.dom.logicContainer.offset({ top: newTop });2691this.dom.clear.outerHeight(this.dom.logicContainer.height());2692this._setClearListener();2693};2694/**2695* Sets listeners on the groups elements
2696*/
2697Group.prototype.setListeners = function () {2698var _this = this;2699this.dom.add.unbind('click');2700this.dom.add.on('click.dtsb', function () {2701// If this is the parent group then the logic button has not been added yet2702if (!_this.s.isChild) {2703_this.dom.container.prepend(_this.dom.logicContainer);2704}2705_this.addCriteria();2706_this.dom.container.trigger('dtsb-add');2707_this.s.dt.state.save();2708return false;2709});2710for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {2711var crit = _a[_i];2712crit.criteria.setListeners();2713}2714this._setClearListener();2715this._setLogicListener();2716};2717/**2718* Adds a criteria to the group
2719*
2720* @param crit Instance of Criteria to be added to the group
2721*/
2722Group.prototype.addCriteria = function (crit, redraw) {2723if (crit === void 0) { crit = null; }2724if (redraw === void 0) { redraw = true; }2725var index = crit === null ? this.s.criteria.length : crit.s.index;2726var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, index, this.s.depth);2727// If a Criteria has been passed in then set the values to continue that2728if (crit !== null) {2729criteria.c = crit.c;2730criteria.s = crit.s;2731criteria.s.depth = this.s.depth;2732criteria.classes = crit.classes;2733}2734criteria.populate();2735var inserted = false;2736for (var i = 0; i < this.s.criteria.length; i++) {2737if (i === 0 && this.s.criteria[i].criteria.s.index > criteria.s.index) {2738// Add the node for the criteria at the start of the group2739criteria.getNode().insertBefore(this.s.criteria[i].criteria.dom.container);2740inserted = true;2741}2742else if (i < this.s.criteria.length - 1 &&2743this.s.criteria[i].criteria.s.index < criteria.s.index &&2744this.s.criteria[i + 1].criteria.s.index > criteria.s.index) {2745// Add the node for the criteria in the correct location2746criteria.getNode().insertAfter(this.s.criteria[i].criteria.dom.container);2747inserted = true;2748}2749}2750if (!inserted) {2751criteria.getNode().insertBefore(this.dom.add);2752}2753// Add the details for this criteria to the array2754this.s.criteria.push({2755criteria: criteria,2756index: index2757});2758this.s.criteria = this.s.criteria.sort(function (a, b) { return a.criteria.s.index - b.criteria.s.index; });2759for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {2760var opt = _a[_i];2761if (opt.criteria instanceof Criteria) {2762opt.criteria.updateArrows(this.s.criteria.length > 1, redraw);2763}2764}2765this._setCriteriaListeners(criteria);2766criteria.setListeners();2767this.setupLogic();2768};2769/**2770* Checks the group to see if it has any filled criteria
2771*/
2772Group.prototype.checkFilled = function () {2773for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {2774var crit = _a[_i];2775if (crit.criteria instanceof Criteria && crit.criteria.s.filled ||2776crit.criteria instanceof Group && crit.criteria.checkFilled()) {2777return true;2778}2779}2780return false;2781};2782/**2783* Gets the count for the number of criteria in this group and any sub groups
2784*/
2785Group.prototype.count = function () {2786var count = 0;2787for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {2788var crit = _a[_i];2789if (crit.criteria instanceof Group) {2790count += crit.criteria.count();2791}2792else {2793count++;2794}2795}2796return count;2797};2798/**2799* Rebuilds a sub group that previously existed
2800*
2801* @param loadedGroup The details of a group within this group
2802*/
2803Group.prototype._addPrevGroup = function (loadedGroup) {2804var idx = this.s.criteria.length;2805var group = new Group(this.s.dt, this.c, this.s.topGroup, idx, true, this.s.depth + 1);2806// Add the new group to the criteria array2807this.s.criteria.push({2808criteria: group,2809index: idx,2810logic: group.s.logic2811});2812// Rebuild it with the previous conditions for that group2813group.rebuild(loadedGroup);2814this.s.criteria[idx].criteria = group;2815this.s.topGroup.trigger('dtsb-redrawContents');2816this._setGroupListeners(group);2817};2818/**2819* Rebuilds a criteria of this group that previously existed
2820*
2821* @param loadedCriteria The details of a criteria within the group
2822*/
2823Group.prototype._addPrevCriteria = function (loadedCriteria) {2824var idx = this.s.criteria.length;2825var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, idx, this.s.depth);2826criteria.populate();2827// Add the new criteria to the criteria array2828this.s.criteria.push({2829criteria: criteria,2830index: idx2831});2832// Rebuild it with the previous conditions for that criteria2833criteria.rebuild(loadedCriteria);2834this.s.criteria[idx].criteria = criteria;2835this.s.topGroup.trigger('dtsb-redrawContents');2836};2837/**2838* Checks And the criteria using AND logic
2839*
2840* @param rowData The row data to be checked against the search criteria
2841* @returns boolean The result of the AND search
2842*/
2843Group.prototype._andSearch = function (rowData, rowIdx) {2844// If there are no criteria then return true for this group2845if (this.s.criteria.length === 0) {2846return true;2847}2848for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {2849var crit = _a[_i];2850// If the criteria is not complete then skip it2851if (crit.criteria instanceof Criteria && !crit.criteria.s.filled) {2852continue;2853}2854// Otherwise if a single one fails return false2855else if (!crit.criteria.search(rowData, rowIdx)) {2856return false;2857}2858}2859// If we get to here then everything has passed, so return true for the group2860return true;2861};2862/**2863* Checks And the criteria using OR logic
2864*
2865* @param rowData The row data to be checked against the search criteria
2866* @returns boolean The result of the OR search
2867*/
2868Group.prototype._orSearch = function (rowData, rowIdx) {2869// If there are no criteria in the group then return true2870if (this.s.criteria.length === 0) {2871return true;2872}2873// This will check to make sure that at least one criteria in the group is complete2874var filledfound = false;2875for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {2876var crit = _a[_i];2877if (crit.criteria instanceof Criteria && crit.criteria.s.filled) {2878// A completed criteria has been found so set the flag2879filledfound = true;2880// If the search passes then return true2881if (crit.criteria.search(rowData, rowIdx)) {2882return true;2883}2884}2885else if (crit.criteria instanceof Group && crit.criteria.checkFilled()) {2886filledfound = true;2887if (crit.criteria.search(rowData, rowIdx)) {2888return true;2889}2890}2891}2892// If we get here we need to return the inverse of filledfound,2893// as if any have been found and we are here then none have passed2894return !filledfound;2895};2896/**2897* Removes a criteria from the group
2898*
2899* @param criteria The criteria instance to be removed
2900*/
2901Group.prototype._removeCriteria = function (criteria, group) {2902if (group === void 0) { group = false; }2903// If removing a criteria and there is only then then just destroy the group2904if (this.s.criteria.length <= 1 && this.s.isChild) {2905this.destroy();2906}2907else {2908// Otherwise splice the given criteria out and redo the indexes2909var last = void 0;2910for (var i = 0; i < this.s.criteria.length; i++) {2911if (this.s.criteria[i].index === criteria.s.index &&2912(!group || this.s.criteria[i].criteria instanceof Group)) {2913last = i;2914}2915}2916// We want to remove the last element with the desired index, as its replacement will be inserted before it2917if (last !== undefined) {2918this.s.criteria.splice(last, 1);2919}2920for (var i = 0; i < this.s.criteria.length; i++) {2921this.s.criteria[i].index = i;2922this.s.criteria[i].criteria.s.index = i;2923}2924}2925};2926/**2927* Sets the listeners in group for a criteria
2928*
2929* @param criteria The criteria for the listeners to be set on
2930*/
2931Group.prototype._setCriteriaListeners = function (criteria) {2932var _this = this;2933criteria.dom["delete"]2934.unbind('click')2935.on('click.dtsb', function () {2936_this._removeCriteria(criteria);2937criteria.dom.container.remove();2938for (var _i = 0, _a = _this.s.criteria; _i < _a.length; _i++) {2939var crit = _a[_i];2940if (crit.criteria instanceof Criteria) {2941crit.criteria.updateArrows(_this.s.criteria.length > 1);2942}2943}2944criteria.destroy();2945_this.s.dt.draw();2946_this.s.topGroup.trigger('dtsb-redrawContents');2947return false;2948});2949criteria.dom.right2950.unbind('click')2951.on('click.dtsb', function () {2952var idx = criteria.s.index;2953var group = new Group(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index, true, _this.s.depth + 1);2954// Add the criteria that is to be moved to the new group2955group.addCriteria(criteria);2956// Update the details in the current groups criteria array2957_this.s.criteria[idx].criteria = group;2958_this.s.criteria[idx].logic = 'AND';2959_this.s.topGroup.trigger('dtsb-redrawContents');2960_this._setGroupListeners(group);2961return false;2962});2963criteria.dom.left2964.unbind('click')2965.on('click.dtsb', function () {2966_this.s.toDrop = new Criteria(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index);2967_this.s.toDrop.s = criteria.s;2968_this.s.toDrop.c = criteria.c;2969_this.s.toDrop.classes = criteria.classes;2970_this.s.toDrop.populate();2971// The dropCriteria event mutates the reference to the index so need to store it2972var index = _this.s.toDrop.s.index;2973_this.dom.container.trigger('dtsb-dropCriteria');2974criteria.s.index = index;2975_this._removeCriteria(criteria);2976// By tracking the top level group we can directly trigger a redraw on it,2977// bubbling is also possible, but that is slow with deep levelled groups2978_this.s.topGroup.trigger('dtsb-redrawContents');2979_this.s.dt.draw();2980return false;2981});2982};2983/**2984* Set's the listeners for the group clear button
2985*/
2986Group.prototype._setClearListener = function () {2987var _this = this;2988this.dom.clear2989.unbind('click')2990.on('click.dtsb', function () {2991if (!_this.s.isChild) {2992_this.dom.container.trigger('dtsb-clearContents');2993return false;2994}2995_this.destroy();2996_this.s.topGroup.trigger('dtsb-redrawContents');2997return false;2998});2999};3000/**3001* Sets listeners for sub groups of this group
3002*
3003* @param group The sub group that the listeners are to be set on
3004*/
3005Group.prototype._setGroupListeners = function (group) {3006var _this = this;3007// Set listeners for the new group3008group.dom.add3009.unbind('click')3010.on('click.dtsb', function () {3011_this.setupLogic();3012_this.dom.container.trigger('dtsb-add');3013return false;3014});3015group.dom.container3016.unbind('dtsb-add')3017.on('dtsb-add.dtsb', function () {3018_this.setupLogic();3019_this.dom.container.trigger('dtsb-add');3020return false;3021});3022group.dom.container3023.unbind('dtsb-destroy')3024.on('dtsb-destroy.dtsb', function () {3025_this._removeCriteria(group, true);3026group.dom.container.remove();3027_this.setupLogic();3028return false;3029});3030group.dom.container3031.unbind('dtsb-dropCriteria')3032.on('dtsb-dropCriteria.dtsb', function () {3033var toDrop = group.s.toDrop;3034toDrop.s.index = group.s.index;3035toDrop.updateArrows(_this.s.criteria.length > 1, false);3036_this.addCriteria(toDrop, false);3037return false;3038});3039group.setListeners();3040};3041/**3042* Sets up the Group instance, setting listeners and appending elements
3043*/
3044Group.prototype._setup = function () {3045this.setListeners();3046this.dom.add.html(this.s.dt.i18n('searchBuilder.add', this.c.i18n.add));3047this.dom.logic.children().first().html(this.c.logic === 'OR'3048? this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr)3049: this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));3050this.s.logic = this.c.logic === 'OR' ? 'OR' : 'AND';3051if (this.c.greyscale) {3052this.dom.logic.addClass(this.classes.greyscale);3053}3054this.dom.logicContainer.append(this.dom.logic).append(this.dom.clear);3055// Only append the logic button immediately if this is a sub group,3056// otherwise it will be prepended later when adding a criteria3057if (this.s.isChild) {3058this.dom.container.append(this.dom.logicContainer);3059}3060this.dom.container.append(this.dom.add);3061};3062/**3063* Sets the listener for the logic button
3064*/
3065Group.prototype._setLogicListener = function () {3066var _this = this;3067this.dom.logic3068.unbind('click')3069.on('click.dtsb', function () {3070_this._toggleLogic();3071_this.s.dt.draw();3072for (var _i = 0, _a = _this.s.criteria; _i < _a.length; _i++) {3073var crit = _a[_i];3074crit.criteria.setListeners();3075}3076});3077};3078/**3079* Toggles the logic for the group
3080*/
3081Group.prototype._toggleLogic = function () {3082if (this.s.logic === 'OR') {3083this.s.logic = 'AND';3084this.dom.logic.children().first().html(this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));3085}3086else if (this.s.logic === 'AND') {3087this.s.logic = 'OR';3088this.dom.logic.children().first().html(this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr));3089}3090};3091Group.version = '1.1.0';3092Group.classes = {3093add: 'dtsb-add',3094button: 'dtsb-button',3095clearGroup: 'dtsb-clearGroup',3096greyscale: 'dtsb-greyscale',3097group: 'dtsb-group',3098inputButton: 'dtsb-iptbtn',3099logic: 'dtsb-logic',3100logicContainer: 'dtsb-logicContainer'3101};3102Group.defaults = {3103columns: true,3104conditions: {3105'date': Criteria.dateConditions,3106'html': Criteria.stringConditions,3107'html-num': Criteria.numConditions,3108'html-num-fmt': Criteria.numFmtConditions,3109'luxon': Criteria.luxonDateConditions,3110'moment': Criteria.momentDateConditions,3111'num': Criteria.numConditions,3112'num-fmt': Criteria.numFmtConditions,3113'string': Criteria.stringConditions3114},3115depthLimit: false,3116enterSearch: false,3117filterChanged: undefined,3118greyscale: false,3119i18n: {3120add: 'Add Condition',3121button: {31220: 'Search Builder',3123_: 'Search Builder (%d)'3124},3125clearAll: 'Clear All',3126condition: 'Condition',3127data: 'Data',3128"delete": '×',3129deleteTitle: 'Delete filtering rule',3130left: '<',3131leftTitle: 'Outdent criteria',3132logicAnd: 'And',3133logicOr: 'Or',3134right: '>',3135rightTitle: 'Indent criteria',3136title: {31370: 'Custom Search Builder',3138_: 'Custom Search Builder (%d)'3139},3140value: 'Value',3141valueJoiner: 'and'3142},3143logic: 'AND',3144orthogonal: {3145display: 'display',3146search: 'filter'3147},3148preDefined: false3149};3150return Group;3151}());3152
3153var $;3154var dataTable;3155/**3156* Sets the value of jQuery for use in the file
3157*
3158* @param jq the instance of jQuery to be set
3159*/
3160function setJQuery(jq) {3161$ = jq;3162dataTable = jq.fn.DataTable;3163}3164/**3165* SearchBuilder class for DataTables.
3166* Allows for complex search queries to be constructed and implemented on a DataTable
3167*/
3168var SearchBuilder = /** @class */ (function () {3169function SearchBuilder(builderSettings, opts) {3170var _this = this;3171// Check that the required version of DataTables is included3172if (!dataTable || !dataTable.versionCheck || !dataTable.versionCheck('1.10.0')) {3173throw new Error('SearchBuilder requires DataTables 1.10 or newer');3174}3175var table = new dataTable.Api(builderSettings);3176this.classes = $.extend(true, {}, SearchBuilder.classes);3177// Get options from user3178this.c = $.extend(true, {}, SearchBuilder.defaults, opts);3179this.dom = {3180clearAll: $('<button type="button">' + table.i18n('searchBuilder.clearAll', this.c.i18n.clearAll) + '</button>')3181.addClass(this.classes.clearAll)3182.addClass(this.classes.button)3183.attr('type', 'button'),3184container: $('<div/>')3185.addClass(this.classes.container),3186title: $('<div/>')3187.addClass(this.classes.title),3188titleRow: $('<div/>')3189.addClass(this.classes.titleRow),3190topGroup: undefined3191};3192this.s = {3193dt: table,3194opts: opts,3195search: undefined,3196topGroup: undefined3197};3198// If searchbuilder is already defined for this table then return3199if (table.settings()[0]._searchBuilder !== undefined) {3200return;3201}3202table.settings()[0]._searchBuilder = this;3203// If using SSP we want to include the previous state in the very first server call3204if (this.s.dt.page.info().serverSide) {3205this.s.dt.on('preXhr.dtsb', function (e, settings, data) {3206var loadedState = _this.s.dt.state.loaded();3207if (loadedState && loadedState.searchBuilder) {3208data.searchBuilder = _this._collapseArray(loadedState.searchBuilder);3209}3210});3211}3212// Run the remaining setup when the table is initialised3213if (this.s.dt.settings()[0]._bInitComplete) {3214this._setUp();3215}3216else {3217table.one('init.dt', function () {3218_this._setUp();3219});3220}3221return this;3222}3223/**3224* Gets the details required to rebuild the SearchBuilder as it currently is
3225*/
3226// eslint upset at empty object but that is what it is3227// eslint-disable-next-line @typescript-eslint/ban-types3228SearchBuilder.prototype.getDetails = function (deFormatDates) {3229if (deFormatDates === void 0) { deFormatDates = false; }3230return this.s.topGroup.getDetails(deFormatDates);3231};3232/**3233* Getter for the node of the container for the searchBuilder
3234*
3235* @returns JQuery<HTMLElement> the node of the container
3236*/
3237SearchBuilder.prototype.getNode = function () {3238return this.dom.container;3239};3240/**3241* Rebuilds the SearchBuilder to a state that is provided
3242*
3243* @param details The details required to perform a rebuild
3244*/
3245SearchBuilder.prototype.rebuild = function (details) {3246this.dom.clearAll.click();3247// If there are no details to rebuild then return3248if (details === undefined || details === null) {3249return this;3250}3251this.s.topGroup.s.preventRedraw = true;3252this.s.topGroup.rebuild(details);3253this.s.topGroup.s.preventRedraw = false;3254this.s.topGroup.redrawContents();3255this.s.dt.draw(false);3256this.s.topGroup.setListeners();3257return this;3258};3259/**3260* Applies the defaults to preDefined criteria
3261*
3262* @param preDef the array of criteria to be processed.
3263*/
3264SearchBuilder.prototype._applyPreDefDefaults = function (preDef) {3265var _this = this;3266if (preDef.criteria !== undefined && preDef.logic === undefined) {3267preDef.logic = 'AND';3268}3269var _loop_1 = function (crit) {3270// Apply the defaults to any further criteria3271if (crit.criteria !== undefined) {3272crit = this_1._applyPreDefDefaults(crit);3273}3274else {3275this_1.s.dt.columns().every(function (index) {3276if (_this.s.dt.settings()[0].aoColumns[index].sTitle === crit.data) {3277crit.dataIdx = index;3278}3279});3280}3281};3282var this_1 = this;3283for (var _i = 0, _a = preDef.criteria; _i < _a.length; _i++) {3284var crit = _a[_i];3285_loop_1(crit);3286}3287return preDef;3288};3289/**3290* Set's up the SearchBuilder
3291*/
3292SearchBuilder.prototype._setUp = function (loadState) {3293var _this = this;3294if (loadState === void 0) { loadState = true; }3295// Register an Api method for getting the column type3296$.fn.DataTable.Api.registerPlural('columns().type()', 'column().type()', function () {3297return this.iterator('column', function (settings, column) {3298return settings.aoColumns[column].sType;3299}, 1);3300});3301// Check that DateTime is included, If not need to check if it could be used3302// eslint-disable-next-line no-extra-parens3303if (!dataTable.DateTime) {3304var types = this.s.dt.columns().type().toArray();3305if (types === undefined || types.includes(undefined) || types.includes(null)) {3306types = [];3307for (var _i = 0, _a = this.s.dt.settings()[0].aoColumns; _i < _a.length; _i++) {3308var colInit = _a[_i];3309types.push(colInit.searchBuilderType !== undefined ? colInit.searchBuilderType : colInit.sType);3310}3311}3312var columnIdxs = this.s.dt.columns().toArray();3313// If the types are not yet set then draw to see if they can be retrieved then3314if (types === undefined || types.includes(undefined) || types.includes(null)) {3315$.fn.dataTable.ext.oApi._fnColumnTypes(this.s.dt.settings()[0]);3316types = this.s.dt.columns().type().toArray();3317}3318for (var i = 0; i < columnIdxs[0].length; i++) {3319var column = columnIdxs[0][i];3320var type = types[column];3321if (3322// Check if this column can be filtered3323(this.c.columns === true ||3324Array.isArray(this.c.columns) &&3325this.c.columns.includes(i)) &&3326// Check if the type is one of the restricted types3327(type.includes('date') ||3328type.includes('moment') ||3329type.includes('luxon'))) {3330alert('SearchBuilder Requires DateTime when used with dates.');3331throw new Error('SearchBuilder requires DateTime');3332}3333}3334}3335this.s.topGroup = new Group(this.s.dt, this.c, undefined);3336this._setClearListener();3337this.s.dt.on('stateSaveParams.dtsb', function (e, settings, data) {3338data.searchBuilder = _this.getDetails();3339data.page = _this.s.dt.page();3340});3341this.s.dt.on('stateLoadParams.dtsb', function (e, settings, data) {3342_this.rebuild(data.searchBuilder);3343});3344this._build();3345this.s.dt.on('preXhr.dtsb', function (e, settings, data) {3346if (_this.s.dt.page.info().serverSide) {3347data.searchBuilder = _this._collapseArray(_this.getDetails(true));3348}3349});3350this.s.dt.on('column-reorder', function () {3351_this.rebuild(_this.getDetails());3352});3353if (loadState) {3354var loadedState = this.s.dt.state.loaded();3355// If the loaded State is not null rebuild based on it for statesave3356if (loadedState !== null && loadedState.searchBuilder !== undefined) {3357this.s.topGroup.rebuild(loadedState.searchBuilder);3358this.s.topGroup.dom.container.trigger('dtsb-redrawContents');3359// If using SSP we want to restrict the amount of server calls that take place3360// and this information will already have been processed3361if (!this.s.dt.page.info().serverSide) {3362this.s.dt.page(loadedState.page).draw('page');3363}3364this.s.topGroup.setListeners();3365}3366// Otherwise load any predefined options3367else if (this.c.preDefined !== false) {3368this.c.preDefined = this._applyPreDefDefaults(this.c.preDefined);3369this.rebuild(this.c.preDefined);3370}3371}3372this._setEmptyListener();3373this.s.dt.state.save();3374};3375SearchBuilder.prototype._collapseArray = function (criteria) {3376if (criteria.logic === undefined) {3377if (criteria.value !== undefined) {3378criteria.value.sort(function (a, b) {3379if (!isNaN(+a)) {3380a = +a;3381b = +b;3382}3383if (a < b) {3384return -1;3385}3386else if (b < a) {3387return 1;3388}3389else {3390return 0;3391}3392});3393criteria.value1 = criteria.value[0];3394criteria.value2 = criteria.value[1];3395}3396}3397else {3398for (var i = 0; i < criteria.criteria.length; i++) {3399criteria.criteria[i] = this._collapseArray(criteria.criteria[i]);3400}3401}3402return criteria;3403};3404/**3405* Updates the title of the SearchBuilder
3406*
3407* @param count the number of filters in the SearchBuilder
3408*/
3409SearchBuilder.prototype._updateTitle = function (count) {3410this.dom.title.html(this.s.dt.i18n('searchBuilder.title', this.c.i18n.title, count));3411};3412/**3413* Builds all of the dom elements together
3414*/
3415SearchBuilder.prototype._build = function () {3416var _this = this;3417// Empty and setup the container3418this.dom.clearAll.remove();3419this.dom.container.empty();3420var count = this.s.topGroup.count();3421this._updateTitle(count);3422this.dom.titleRow.append(this.dom.title);3423this.dom.container.append(this.dom.titleRow);3424this.dom.topGroup = this.s.topGroup.getNode();3425this.dom.container.append(this.dom.topGroup);3426this._setRedrawListener();3427var tableNode = this.s.dt.table(0).node();3428if (!$.fn.dataTable.ext.search.includes(this.s.search)) {3429// Custom search function for SearchBuilder3430this.s.search = function (settings, searchData, dataIndex) {3431if (settings.nTable !== tableNode) {3432return true;3433}3434return _this.s.topGroup.search(searchData, dataIndex);3435};3436// Add SearchBuilder search function to the dataTables search array3437$.fn.dataTable.ext.search.push(this.s.search);3438}3439this.s.dt.on('destroy.dtsb', function () {3440_this.dom.container.remove();3441_this.dom.clearAll.remove();3442var searchIdx = $.fn.dataTable.ext.search.indexOf(_this.s.search);3443while (searchIdx !== -1) {3444$.fn.dataTable.ext.search.splice(searchIdx, 1);3445searchIdx = $.fn.dataTable.ext.search.indexOf(_this.s.search);3446}3447_this.s.dt.off('.dtsb');3448$(_this.s.dt.table().node()).off('.dtsb');3449});3450};3451/**3452* Checks if the clearAll button should be added or not
3453*/
3454SearchBuilder.prototype._checkClear = function () {3455if (this.s.topGroup.s.criteria.length > 0) {3456this.dom.clearAll.insertAfter(this.dom.title);3457this._setClearListener();3458}3459else {3460this.dom.clearAll.remove();3461}3462};3463/**3464* Update the count in the title/button
3465*
3466* @param count Number of filters applied
3467*/
3468SearchBuilder.prototype._filterChanged = function (count) {3469var fn = this.c.filterChanged;3470if (typeof fn === 'function') {3471fn(count, this.s.dt.i18n('searchBuilder.button', this.c.i18n.button, count));3472}3473};3474/**3475* Set the listener for the clear button
3476*/
3477SearchBuilder.prototype._setClearListener = function () {3478var _this = this;3479this.dom.clearAll.unbind('click');3480this.dom.clearAll.on('click.dtsb', function () {3481_this.s.topGroup = new Group(_this.s.dt, _this.c, undefined);3482_this._build();3483_this.s.dt.draw();3484_this.s.topGroup.setListeners();3485_this.dom.clearAll.remove();3486_this._setEmptyListener();3487_this._filterChanged(0);3488return false;3489});3490};3491/**3492* Set the listener for the Redraw event
3493*/
3494SearchBuilder.prototype._setRedrawListener = function () {3495var _this = this;3496this.s.topGroup.dom.container.unbind('dtsb-redrawContents');3497this.s.topGroup.dom.container.on('dtsb-redrawContents.dtsb', function () {3498_this._checkClear();3499_this.s.topGroup.redrawContents();3500_this.s.topGroup.setupLogic();3501_this._setEmptyListener();3502var count = _this.s.topGroup.count();3503_this._updateTitle(count);3504_this._filterChanged(count);3505// If using SSP we want to restrict the amount of server calls that take place3506// and this information will already have been processed3507if (!_this.s.dt.page.info().serverSide) {3508_this.s.dt.draw();3509}3510_this.s.dt.state.save();3511});3512this.s.topGroup.dom.container.unbind('dtsb-redrawLogic');3513this.s.topGroup.dom.container.on('dtsb-redrawLogic.dtsb', function () {3514_this.s.topGroup.redrawLogic();3515var count = _this.s.topGroup.count();3516_this._updateTitle(count);3517_this._filterChanged(count);3518});3519this.s.topGroup.dom.container.unbind('dtsb-add');3520this.s.topGroup.dom.container.on('dtsb-add.dtsb', function () {3521var count = _this.s.topGroup.count();3522_this._updateTitle(count);3523_this._filterChanged(count);3524});3525this.s.dt.on('postEdit.dtsb postCreate.dtsb postRemove.dtsb', function () {3526_this.s.topGroup.redrawContents();3527});3528this.s.topGroup.dom.container.unbind('dtsb-clearContents');3529this.s.topGroup.dom.container.on('dtsb-clearContents.dtsb', function () {3530_this._setUp(false);3531_this._filterChanged(0);3532_this.s.dt.draw();3533});3534};3535/**3536* Sets listeners to check whether clearAll should be added or removed
3537*/
3538SearchBuilder.prototype._setEmptyListener = function () {3539var _this = this;3540this.s.topGroup.dom.add.on('click.dtsb', function () {3541_this._checkClear();3542});3543this.s.topGroup.dom.container.on('dtsb-destroy.dtsb', function () {3544_this.dom.clearAll.remove();3545});3546};3547SearchBuilder.version = '1.3.1';3548SearchBuilder.classes = {3549button: 'dtsb-button',3550clearAll: 'dtsb-clearAll',3551container: 'dtsb-searchBuilder',3552inputButton: 'dtsb-iptbtn',3553title: 'dtsb-title',3554titleRow: 'dtsb-titleRow'3555};3556SearchBuilder.defaults = {3557columns: true,3558conditions: {3559'date': Criteria.dateConditions,3560'html': Criteria.stringConditions,3561'html-num': Criteria.numConditions,3562'html-num-fmt': Criteria.numFmtConditions,3563'luxon': Criteria.luxonDateConditions,3564'moment': Criteria.momentDateConditions,3565'num': Criteria.numConditions,3566'num-fmt': Criteria.numFmtConditions,3567'string': Criteria.stringConditions3568},3569depthLimit: false,3570enterSearch: false,3571filterChanged: undefined,3572greyscale: false,3573i18n: {3574add: 'Add Condition',3575button: {35760: 'Search Builder',3577_: 'Search Builder (%d)'3578},3579clearAll: 'Clear All',3580condition: 'Condition',3581conditions: {3582array: {3583contains: 'Contains',3584empty: 'Empty',3585equals: 'Equals',3586not: 'Not',3587notEmpty: 'Not Empty',3588without: 'Without'3589},3590date: {3591after: 'After',3592before: 'Before',3593between: 'Between',3594empty: 'Empty',3595equals: 'Equals',3596not: 'Not',3597notBetween: 'Not Between',3598notEmpty: 'Not Empty'3599},3600// eslint-disable-next-line id-blacklist3601number: {3602between: 'Between',3603empty: 'Empty',3604equals: 'Equals',3605gt: 'Greater Than',3606gte: 'Greater Than Equal To',3607lt: 'Less Than',3608lte: 'Less Than Equal To',3609not: 'Not',3610notBetween: 'Not Between',3611notEmpty: 'Not Empty'3612},3613// eslint-disable-next-line id-blacklist3614string: {3615contains: 'Contains',3616empty: 'Empty',3617endsWith: 'Ends With',3618equals: 'Equals',3619not: 'Not',3620notContains: 'Does Not Contain',3621notEmpty: 'Not Empty',3622notEndsWith: 'Does Not End With',3623notStartsWith: 'Does Not Start With',3624startsWith: 'Starts With'3625}3626},3627data: 'Data',3628"delete": '×',3629deleteTitle: 'Delete filtering rule',3630left: '<',3631leftTitle: 'Outdent criteria',3632logicAnd: 'And',3633logicOr: 'Or',3634right: '>',3635rightTitle: 'Indent criteria',3636title: {36370: 'Custom Search Builder',3638_: 'Custom Search Builder (%d)'3639},3640value: 'Value',3641valueJoiner: 'and'3642},3643logic: 'AND',3644orthogonal: {3645display: 'display',3646search: 'filter'3647},3648preDefined: false3649};3650return SearchBuilder;3651}());3652
3653/*! SearchBuilder 1.3.13654* ©SpryMedia Ltd - datatables.net/license/mit
3655*/
3656// DataTables extensions common UMD. Note that this allows for AMD, CommonJS3657// (with window and jQuery being allowed as parameters to the returned3658// function) or just default browser loading.3659(function (factory) {3660if (typeof define === 'function' && define.amd) {3661// AMD3662define(['jquery', 'datatables.net'], function ($) {3663return factory($, window, document);3664});3665}3666else if (typeof exports === 'object') {3667// CommonJS3668module.exports = function (root, $) {3669if (!root) {3670root = window;3671}3672if (!$ || !$.fn.dataTable) {3673// eslint-disable-next-line @typescript-eslint/no-var-requires3674$ = require('datatables.net')(root, $).$;3675}3676return factory($, root, root.document);3677};3678}3679else {3680// Browser - assume jQuery has already been loaded3681// eslint-disable-next-line no-extra-parens3682factory(window.jQuery, window, document);3683}3684}(function ($, window, document) {3685setJQuery($);3686setJQuery$1($);3687setJQuery$2($);3688var dataTable = $.fn.dataTable;3689// eslint-disable-next-line no-extra-parens3690$.fn.dataTable.SearchBuilder = SearchBuilder;3691// eslint-disable-next-line no-extra-parens3692$.fn.DataTable.SearchBuilder = SearchBuilder;3693// eslint-disable-next-line no-extra-parens3694$.fn.dataTable.Group = Group;3695// eslint-disable-next-line no-extra-parens3696$.fn.DataTable.Group = Group;3697// eslint-disable-next-line no-extra-parens3698$.fn.dataTable.Criteria = Criteria;3699// eslint-disable-next-line no-extra-parens3700$.fn.DataTable.Criteria = Criteria;3701// eslint-disable-next-line no-extra-parens3702var apiRegister = $.fn.dataTable.Api.register;3703// Set up object for plugins3704$.fn.dataTable.ext.searchBuilder = {3705conditions: {}3706};3707$.fn.dataTable.ext.buttons.searchBuilder = {3708action: function (e, dt, node, config) {3709this.popover(config._searchBuilder.getNode(), {3710align: 'container',3711span: 'container'3712});3713// Need to redraw the contents to calculate the correct positions for the elements3714if (config._searchBuilder.s.topGroup !== undefined) {3715config._searchBuilder.s.topGroup.dom.container.trigger('dtsb-redrawContents');3716}3717if (config._searchBuilder.s.topGroup.s.criteria.length === 0) {3718$('.' + $.fn.dataTable.Group.classes.add).click();3719}3720},3721config: {},3722init: function (dt, node, config) {3723var sb = new $.fn.dataTable.SearchBuilder(dt, $.extend({3724filterChanged: function (count, text) {3725dt.button(node).text(text);3726}3727}, config.config));3728dt.button(node).text(config.text || dt.i18n('searchBuilder.button', sb.c.i18n.button, 0));3729config._searchBuilder = sb;3730},3731text: null3732};3733apiRegister('searchBuilder.getDetails()', function (deFormatDates) {3734if (deFormatDates === void 0) { deFormatDates = false; }3735var ctx = this.context[0];3736// If SearchBuilder has not been initialised on this instance then return3737return ctx._searchBuilder ?3738ctx._searchBuilder.getDetails(deFormatDates) :3739null;3740});3741apiRegister('searchBuilder.rebuild()', function (details) {3742var ctx = this.context[0];3743// If SearchBuilder has not been initialised on this instance then return3744if (ctx._searchBuilder === undefined) {3745return null;3746}3747ctx._searchBuilder.rebuild(details);3748return this;3749});3750apiRegister('searchBuilder.container()', function () {3751var ctx = this.context[0];3752// If SearchBuilder has not been initialised on this instance then return3753return ctx._searchBuilder ?3754ctx._searchBuilder.getNode() :3755null;3756});3757/**3758* Init function for SearchBuilder
3759*
3760* @param settings the settings to be applied
3761* @param options the options for SearchBuilder
3762* @returns JQUERY<HTMLElement> Returns the node of the SearchBuilder
3763*/
3764function _init(settings, options) {3765var api = new dataTable.Api(settings);3766var opts = options3767? options3768: api.init().searchBuilder || dataTable.defaults.searchBuilder;3769var searchBuilder = new SearchBuilder(api, opts);3770var node = searchBuilder.getNode();3771return node;3772}3773// Attach a listener to the document which listens for DataTables initialisation3774// events so we can automatically initialise3775$(document).on('preInit.dt.dtsp', function (e, settings) {3776if (e.namespace !== 'dt') {3777return;3778}3779if (settings.oInit.searchBuilder ||3780dataTable.defaults.searchBuilder) {3781if (!settings._searchBuilder) {3782_init(settings);3783}3784}3785});3786// DataTables `dom` feature option3787dataTable.ext.feature.push({3788cFeature: 'Q',3789fnInit: _init3790});3791// DataTables 2 layout feature3792if (dataTable.ext.features) {3793dataTable.ext.features.register('searchBuilder', _init);3794}3795}));3796
3797}());3798