datatables.net-searchbuilder 1.3.0 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- /*! SearchBuilder 1.3.0
1
+ /*! SearchBuilder 1.3.2
2
2
  * ©SpryMedia Ltd - datatables.net/license/mit
3
3
  */
4
4
  (function () {
@@ -6,10 +6,12 @@
6
6
 
7
7
  var $$2;
8
8
  var dataTable$2;
9
- // eslint-disable-next-line no-extra-parens
10
- var moment = window.moment;
11
- // eslint-disable-next-line no-extra-parens
12
- var luxon = window.luxon;
9
+ function moment() {
10
+ return window.moment;
11
+ }
12
+ function luxon() {
13
+ return window.luxon;
14
+ }
13
15
  /**
14
16
  * Sets the value of jQuery for use in the file
15
17
  *
@@ -23,10 +25,11 @@
23
25
  * The Criteria class is used within SearchBuilder to represent a search criteria
24
26
  */
25
27
  var Criteria = /** @class */ (function () {
26
- function Criteria(table, opts, topGroup, index, depth) {
28
+ function Criteria(table, opts, topGroup, index, depth, serverData) {
27
29
  var _this = this;
28
30
  if (index === void 0) { index = 0; }
29
31
  if (depth === void 0) { depth = 1; }
32
+ if (serverData === void 0) { serverData = undefined; }
30
33
  // Check that the required version of DataTables is included
31
34
  if (!dataTable$2 || !dataTable$2.versionCheck || !dataTable$2.versionCheck('1.10.0')) {
32
35
  throw new Error('SearchPane requires DataTables 1.10 or newer');
@@ -47,6 +50,8 @@
47
50
  filled: false,
48
51
  index: index,
49
52
  origData: undefined,
53
+ preventRedraw: false,
54
+ serverData: serverData,
50
55
  topGroup: topGroup,
51
56
  type: '',
52
57
  value: []
@@ -60,7 +65,7 @@
60
65
  .addClass(this.classes.italic)
61
66
  .attr('autocomplete', 'hacking'),
62
67
  conditionTitle: $$2('<option value="" disabled selected hidden/>')
63
- .text(this.s.dt.i18n('searchBuilder.condition', i18n.condition)),
68
+ .html(this.s.dt.i18n('searchBuilder.condition', i18n.condition)),
64
69
  container: $$2('<div/>')
65
70
  .addClass(this.classes.container),
66
71
  data: $$2('<select/>')
@@ -68,27 +73,30 @@
68
73
  .addClass(this.classes.dropDown)
69
74
  .addClass(this.classes.italic),
70
75
  dataTitle: $$2('<option value="" disabled selected hidden/>')
71
- .text(this.s.dt.i18n('searchBuilder.data', i18n.data)),
76
+ .html(this.s.dt.i18n('searchBuilder.data', i18n.data)),
72
77
  defaultValue: $$2('<select disabled/>')
73
78
  .addClass(this.classes.value)
74
79
  .addClass(this.classes.dropDown)
75
- .addClass(this.classes.select),
80
+ .addClass(this.classes.select)
81
+ .addClass(this.classes.italic),
76
82
  "delete": $$2('<button/>')
77
83
  .html(this.s.dt.i18n('searchBuilder.delete', i18n["delete"]))
78
84
  .addClass(this.classes["delete"])
79
85
  .addClass(this.classes.button)
80
86
  .attr('title', this.s.dt.i18n('searchBuilder.deleteTitle', i18n.deleteTitle))
81
87
  .attr('type', 'button'),
88
+ inputCont: $$2('<div/>')
89
+ .addClass(this.classes.inputCont),
82
90
  // eslint-disable-next-line no-useless-escape
83
91
  left: $$2('<button/>')
84
- .text(this.s.dt.i18n('searchBuilder.left', i18n.left))
92
+ .html(this.s.dt.i18n('searchBuilder.left', i18n.left))
85
93
  .addClass(this.classes.left)
86
94
  .addClass(this.classes.button)
87
95
  .attr('title', this.s.dt.i18n('searchBuilder.leftTitle', i18n.leftTitle))
88
96
  .attr('type', 'button'),
89
97
  // eslint-disable-next-line no-useless-escape
90
98
  right: $$2('<button/>')
91
- .text(this.s.dt.i18n('searchBuilder.right', i18n.right))
99
+ .html(this.s.dt.i18n('searchBuilder.right', i18n.right))
92
100
  .addClass(this.classes.right)
93
101
  .addClass(this.classes.button)
94
102
  .attr('title', this.s.dt.i18n('searchBuilder.rightTitle', i18n.rightTitle))
@@ -100,8 +108,8 @@
100
108
  .addClass(this.classes.italic)
101
109
  .addClass(this.classes.select)
102
110
  ],
103
- valueTitle: $$2('<option value="--valueTitle--" selected/>')
104
- .text(this.s.dt.i18n('searchBuilder.value', i18n.value))
111
+ valueTitle: $$2('<option value="--valueTitle--" disabled selected hidden/>')
112
+ .html(this.s.dt.i18n('searchBuilder.value', i18n.value))
105
113
  };
106
114
  // If the greyscale option is selected then add the class to add the grey colour to SearchBuilder
107
115
  if (this.c.greyscale) {
@@ -113,30 +121,48 @@
113
121
  val.addClass(this.classes.greyscale);
114
122
  }
115
123
  }
116
- // For responsive design, adjust the criterias properties on the following events
117
- this.s.dt.on('draw.dtsb', function () {
118
- _this._adjustCriteria();
119
- });
120
- this.s.dt.on('buttons-action.dtsb', function () {
121
- _this._adjustCriteria();
122
- });
123
124
  $$2(window).on('resize.dtsb', dataTable$2.util.throttle(function () {
124
- _this._adjustCriteria();
125
+ _this.s.topGroup.trigger('dtsb-redrawLogic');
125
126
  }));
126
127
  this._buildCriteria();
127
128
  return this;
128
129
  }
130
+ /**
131
+ * Escape html characters within a string
132
+ *
133
+ * @param txt the string to be escaped
134
+ * @returns the escaped string
135
+ */
136
+ Criteria._escapeHTML = function (txt) {
137
+ return txt
138
+ .toString()
139
+ .replace(/&amp;/g, '&')
140
+ .replace(/&lt;/g, '<')
141
+ .replace(/&gt;/g, '>')
142
+ .replace(/&quot;/g, '"');
143
+ };
144
+ /**
145
+ * Parses formatted numbers down to a form where they can be compared
146
+ *
147
+ * @param val the value to convert
148
+ * @returns the converted value
149
+ */
150
+ Criteria.parseNumFmt = function (val) {
151
+ return +val.replace(/(?!^-)[^0-9.]/g, '');
152
+ };
129
153
  /**
130
154
  * Adds the left button to the criteria
131
155
  */
132
- Criteria.prototype.updateArrows = function (hasSiblings, redraw) {
156
+ Criteria.prototype.updateArrows = function (hasSiblings) {
133
157
  if (hasSiblings === void 0) { hasSiblings = false; }
134
- if (redraw === void 0) { redraw = true; }
135
158
  // Empty the container and append all of the elements in the correct order
136
159
  this.dom.container.children().detach();
137
160
  this.dom.container
138
161
  .append(this.dom.data)
139
162
  .append(this.dom.condition)
163
+ .append(this.dom.inputCont);
164
+ this.dom.inputCont
165
+ .empty()
140
166
  .append(this.dom.value[0]);
141
167
  this.setListeners();
142
168
  // Trigger the inserted events for the value elements as they are inserted
@@ -144,7 +170,7 @@
144
170
  this.dom.value[0].trigger('dtsb-inserted');
145
171
  }
146
172
  for (var i = 1; i < this.dom.value.length; i++) {
147
- this.dom.container.append(this.dom.value[i]);
173
+ this.dom.inputCont.append(this.dom.value[i]);
148
174
  this.dom.value[i].trigger('dtsb-inserted');
149
175
  }
150
176
  // If this is a top level criteria then don't let it move left
@@ -160,10 +186,6 @@
160
186
  }
161
187
  this.dom.buttons.append(this.dom["delete"]);
162
188
  this.dom.container.append(this.dom.buttons);
163
- if (redraw) {
164
- // A different combination of arrows and selectors may lead to a need for responsive to be triggered
165
- this._adjustCriteria();
166
- }
167
189
  };
168
190
  /**
169
191
  * Destroys the criteria, removing listeners and container from the dom
@@ -220,15 +242,15 @@
220
242
  filter.sort();
221
243
  for (var _i = 0, filter_1 = filter; _i < filter_1.length; _i++) {
222
244
  var filt = filter_1[_i];
223
- if (filt) {
245
+ if (filt && typeof filt === 'string') {
224
246
  filt = filt.replace(/[\r\n\u2028]/g, ' ');
225
247
  }
226
248
  }
227
249
  }
228
- else if (filter !== null) {
250
+ else if (filter !== null && typeof filter === 'string') {
229
251
  filter = filter.replace(/[\r\n\u2028]/g, ' ');
230
252
  }
231
- if (this.s.type.includes('html')) {
253
+ if (this.s.type.includes('html') && typeof filter === 'string') {
232
254
  filter = filter.replace(/(<([^>]+)>)/ig, '');
233
255
  }
234
256
  // Not ideal, but jqueries .val() returns an empty string even
@@ -272,12 +294,20 @@
272
294
  }
273
295
  else if (this.s.type.includes('moment')) {
274
296
  for (var i = 0; i < this.s.value.length; i++) {
275
- this.s.value[i] = moment(this.s.value[i], this.s.dateFormat).toISOString();
297
+ if (this.s.value[i] &&
298
+ this.s.value[i].length > 0 &&
299
+ moment()(this.s.value[i], this.s.dateFormat, true).isValid()) {
300
+ this.s.value[i] = moment()(this.s.value[i], this.s.dateFormat).format('YYYY-MM-DD HH:mm:ss');
301
+ }
276
302
  }
277
303
  }
278
304
  else if (this.s.type.includes('luxon')) {
279
305
  for (var i = 0; i < this.s.value.length; i++) {
280
- this.s.value[i] = luxon.DateTime.fromFormat(this.s.value[i], this.s.dateFormat).toISO();
306
+ if (this.s.value[i] &&
307
+ this.s.value[i].length > 0 &&
308
+ luxon().DateTime.fromFormat(this.s.value[i], this.s.dateFormat).invalid === null) {
309
+ this.s.value[i] = luxon().DateTime.fromFormat(this.s.value[i], this.s.dateFormat).toFormat('yyyy-MM-dd HH:mm:ss');
310
+ }
281
311
  }
282
312
  }
283
313
  }
@@ -291,7 +321,7 @@
291
321
  data: this.s.data,
292
322
  origData: this.s.origData,
293
323
  type: this.s.type,
294
- value: this.s.value.map(function (a) { return a.toString(); })
324
+ value: this.s.value.map(function (a) { return a !== null && a !== undefined ? a.toString() : a; })
295
325
  };
296
326
  };
297
327
  /**
@@ -331,7 +361,9 @@
331
361
  var italic_1 = this.classes.italic;
332
362
  var data_1 = this.dom.data;
333
363
  this.dom.data.children('option').each(function () {
334
- if ($$2(this).text() === loadedCriteria.data) {
364
+ if (!foundData &&
365
+ ($$2(this).text() === loadedCriteria.data ||
366
+ loadedCriteria.origData && $$2(this).prop('origData') === loadedCriteria.origData)) {
335
367
  $$2(this).prop('selected', true);
336
368
  data_1.removeClass(italic_1);
337
369
  foundData = true;
@@ -456,7 +488,7 @@
456
488
  var val = _c[_b];
457
489
  // If this criteria was previously active in the search then remove
458
490
  // it from the search and trigger a new search
459
- if (_this.s.filled && val !== undefined && _this.dom.container.has(val[0]).length !== 0) {
491
+ if (_this.s.filled && val !== undefined && _this.dom.inputCont.has(val[0]).length !== 0) {
460
492
  _this.s.filled = false;
461
493
  _this.s.dt.draw();
462
494
  _this.setListeners();
@@ -473,52 +505,16 @@
473
505
  }
474
506
  });
475
507
  };
476
- /**
477
- * Adjusts the criteria to make SearchBuilder responsive
478
- */
479
- Criteria.prototype._adjustCriteria = function () {
480
- // If this criteria is not present then don't bother adjusting it
481
- if ($$2(document).has(this.dom.container).length === 0) {
482
- return;
483
- }
484
- var valRight;
485
- var valWidth;
486
- var outmostval = this.dom.value[this.dom.value.length - 1];
487
- // Calculate the width and right value of the outmost value element
488
- if (outmostval !== undefined && this.dom.container.has(outmostval[0]).length !== 0) {
489
- valWidth = outmostval.outerWidth(true);
490
- valRight = outmostval.offset().left + valWidth;
491
- }
492
- else {
508
+ Criteria.prototype.setupButtons = function () {
509
+ if (window.innerWidth > 550) {
510
+ this.dom.container.removeClass(this.classes.vertical);
511
+ this.dom.buttons.css('left', null);
512
+ this.dom.buttons.css('top', null);
493
513
  return;
494
514
  }
495
- var leftOffset = this.dom.left.offset();
496
- var rightOffset = this.dom.right.offset();
497
- var clearOffset = this.dom["delete"].offset();
498
- var hasLeft = this.dom.container.has(this.dom.left[0]).length !== 0;
499
- var hasRight = this.dom.container.has(this.dom.right[0]).length !== 0;
500
- var buttonsLeft = hasLeft ?
501
- leftOffset.left :
502
- hasRight ?
503
- rightOffset.left :
504
- clearOffset.left;
505
- // Perform the responsive calculations and redraw where necessary
506
- if ((buttonsLeft - valRight < 15 ||
507
- hasLeft && leftOffset.top !== clearOffset.top ||
508
- hasRight && rightOffset.top !== clearOffset.top) &&
509
- !this.dom.container.parent().hasClass(this.classes.vertical)) {
510
- this.dom.container.parent().addClass(this.classes.vertical);
511
- this.s.topGroup.trigger('dtsb-redrawContents');
512
- }
513
- else if (buttonsLeft -
514
- (this.dom.data.offset().left +
515
- this.dom.data.outerWidth(true) +
516
- this.dom.condition.outerWidth(true) +
517
- valWidth) > 15
518
- && this.dom.container.parent().hasClass(this.classes.vertical)) {
519
- this.dom.container.parent().removeClass(this.classes.vertical);
520
- this.s.topGroup.trigger('dtsb-redrawContents');
521
- }
515
+ this.dom.container.addClass(this.classes.vertical);
516
+ this.dom.buttons.css('left', this.dom.data.innerWidth());
517
+ this.dom.buttons.css('top', this.dom.data.position().top);
522
518
  };
523
519
  /**
524
520
  * Builds the elements of the dom together
@@ -531,15 +527,17 @@
531
527
  this.dom.container
532
528
  .append(this.dom.data)
533
529
  .append(this.dom.condition);
530
+ this.dom.inputCont.empty();
534
531
  for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
535
532
  var val = _a[_i];
536
533
  val.append(this.dom.valueTitle);
537
- this.dom.container.append(val);
534
+ this.dom.inputCont.append(val);
538
535
  }
539
536
  // Add buttons to container
540
- this.dom.container
537
+ this.dom.buttons
541
538
  .append(this.dom["delete"])
542
539
  .append(this.dom.right);
540
+ this.dom.container.append(this.dom.inputCont).append(this.dom.buttons);
543
541
  this.setListeners();
544
542
  };
545
543
  /**
@@ -575,10 +573,15 @@
575
573
  // Call the init function to get the value elements for this condition
576
574
  this.dom.value = [].concat(this.s.conditions[this.s.condition].init(this, Criteria.updateListener));
577
575
  if (this.dom.value.length > 0 && this.dom.value[0] !== undefined) {
578
- this.dom.value[0].insertAfter(this.dom.condition).trigger('dtsb-inserted');
576
+ this.dom.inputCont
577
+ .empty()
578
+ .append(this.dom.value[0])
579
+ .insertAfter(this.dom.condition);
580
+ this.dom.value[0].trigger('dtsb-inserted');
579
581
  // Insert all of the value elements
580
582
  for (var i = 1; i < this.dom.value.length; i++) {
581
- this.dom.value[i].insertAfter(this.dom.value[i - 1]).trigger('dtsb-inserted');
583
+ this.dom.inputCont.append(this.dom.value[i]);
584
+ this.dom.value[i].trigger('dtsb-inserted');
582
585
  }
583
586
  }
584
587
  }
@@ -628,11 +631,11 @@
628
631
  Criteria.prototype._populateCondition = function () {
629
632
  var conditionOpts = [];
630
633
  var conditionsLength = Object.keys(this.s.conditions).length;
634
+ var colInits = this.s.dt.settings()[0].aoColumns;
635
+ var column = +this.dom.data.children('option:selected').val();
631
636
  // If there are no conditions stored then we need to get them from the appropriate type
632
637
  if (conditionsLength === 0) {
633
- var column = +this.dom.data.children('option:selected').val();
634
638
  this.s.type = this.s.dt.columns().type().toArray()[column];
635
- var colInits = this.s.dt.settings()[0].aoColumns;
636
639
  if (colInits !== undefined) {
637
640
  var colInit = colInits[column];
638
641
  if (colInit.searchBuilderType !== undefined && colInit.searchBuilderType !== null) {
@@ -687,9 +690,15 @@
687
690
  // Serverside processing does not supply the options for the select elements
688
691
  // Instead input elements need to be used for these instead
689
692
  if (this.s.dt.page.info().serverSide && conditionObj[condition].init === Criteria.initSelect) {
690
- conditionObj[condition].init = Criteria.initInput;
691
- conditionObj[condition].inputValue = Criteria.inputValueInput;
692
- conditionObj[condition].isInputValid = Criteria.isInputValidInput;
693
+ var col = colInits[column];
694
+ if (this.s.serverData[col.data]) {
695
+ conditionObj[condition].init = Criteria.initSelectSSP;
696
+ }
697
+ else {
698
+ conditionObj[condition].init = Criteria.initInput;
699
+ }
700
+ conditionObj[condition].inputValue = Criteria.inputValueSelect;
701
+ conditionObj[condition].isInputValid = Criteria.isInputValidSelect;
693
702
  }
694
703
  this.s.conditions[condition] = conditionObj[condition];
695
704
  var condName = conditionObj[condition].conditionName;
@@ -737,7 +746,44 @@
737
746
  var opt = conditionOpts_1[_d];
738
747
  this.dom.condition.append(opt);
739
748
  }
740
- this.dom.condition.prop('selectedIndex', 0);
749
+ // Selecting a default condition if one is set
750
+ if (colInits[column].searchBuilder && colInits[column].searchBuilder.defaultCondition) {
751
+ var defaultCondition = colInits[column].searchBuilder.defaultCondition;
752
+ // If it is a number just use it as an index
753
+ if (typeof defaultCondition === 'number') {
754
+ this.dom.condition.prop('selectedIndex', defaultCondition);
755
+ this.dom.condition.trigger('change');
756
+ }
757
+ // If it is a string then things get slightly more tricly
758
+ else if (typeof defaultCondition === 'string') {
759
+ // We need to check each condition option to see if any will match
760
+ for (var i = 0; i < conditionOpts.length; i++) {
761
+ // Need to check against the stored conditions so we can match the token "cond" to the option
762
+ for (var _e = 0, _f = Object.keys(this.s.conditions); _e < _f.length; _e++) {
763
+ var cond = _f[_e];
764
+ var condName = this.s.conditions[cond].conditionName;
765
+ if (
766
+ // If the conditionName matches the text of the option
767
+ (typeof condName === 'string' ? condName : condName(this.s.dt, this.c.i18n)) ===
768
+ conditionOpts[i].text() &&
769
+ // and the tokens match
770
+ cond === defaultCondition) {
771
+ // Select that option
772
+ this.dom.condition
773
+ .prop('selectedIndex', this.dom.condition.children().toArray().indexOf(conditionOpts[i][0]))
774
+ .removeClass(this.classes.italic);
775
+ this.dom.condition.trigger('change');
776
+ i = conditionOpts.length;
777
+ break;
778
+ }
779
+ }
780
+ }
781
+ }
782
+ }
783
+ // If not default set then default to 0, the title
784
+ else {
785
+ this.dom.condition.prop('selectedIndex', 0);
786
+ }
741
787
  };
742
788
  /**
743
789
  * Populates the data select element
@@ -844,9 +890,10 @@
844
890
  var val = _a[_i];
845
891
  _loop_4(val);
846
892
  }
847
- var children = this.dom.container.children();
848
- if (children.length > 3) {
849
- for (var i = 2; i < children.length - 1; i++) {
893
+ var children = this.dom.inputCont.children();
894
+ if (children.length > 1) {
895
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
896
+ for (var i = 0; i < children.length; i++) {
850
897
  $$2(children[i]).remove();
851
898
  }
852
899
  }
@@ -863,10 +910,11 @@
863
910
  if (loadedCriteria !== undefined && loadedCriteria.value !== undefined) {
864
911
  this.s.value = loadedCriteria.value;
865
912
  }
913
+ this.dom.inputCont.empty();
866
914
  // Insert value elements and trigger the inserted event
867
915
  if (this.dom.value[0] !== undefined) {
868
916
  this.dom.value[0]
869
- .insertAfter(this.dom.condition)
917
+ .appendTo(this.dom.inputCont)
870
918
  .trigger('dtsb-inserted');
871
919
  }
872
920
  for (var i = 1; i < this.dom.value.length; i++) {
@@ -878,8 +926,12 @@
878
926
  this.s.filled = this.s.conditions[this.s.condition].isInputValid(this.dom.value, this);
879
927
  this.setListeners();
880
928
  // If it can and this is different to before then trigger a draw
881
- if (prevFilled !== this.s.filled) {
882
- this.s.dt.draw();
929
+ if (!this.s.preventRedraw && prevFilled !== this.s.filled) {
930
+ // If using SSP we want to restrict the amount of server calls that take place
931
+ // and this will already have taken place
932
+ if (!this.s.dt.page.info().serverSide) {
933
+ this.s.dt.draw();
934
+ }
883
935
  this.setListeners();
884
936
  }
885
937
  };
@@ -927,6 +979,7 @@
927
979
  dropDown: 'dtsb-dropDown',
928
980
  greyscale: 'dtsb-greyscale',
929
981
  input: 'dtsb-input',
982
+ inputCont: 'dtsb-inputCont',
930
983
  italic: 'dtsb-italic',
931
984
  joiner: 'dtsp-joiner',
932
985
  left: 'dtsb-left',
@@ -946,6 +999,7 @@
946
999
  var column = that.dom.data.children('option:selected').val();
947
1000
  var indexArray = that.s.dt.rows().indexes().toArray();
948
1001
  var settings = that.s.dt.settings()[0];
1002
+ that.dom.valueTitle.prop('selected', true);
949
1003
  // Declare select element to be used with all of the default classes and listeners.
950
1004
  var el = $$2('<select/>')
951
1005
  .addClass(Criteria.classes.value)
@@ -980,22 +1034,20 @@
980
1034
  };
981
1035
  // If we are dealing with an array type, either make sure we are working with arrays, or sort them
982
1036
  if (that.s.type === 'array') {
983
- value.filter = !Array.isArray(value.filter) ?
984
- [value.filter] :
985
- value.filter = value.filter.sort();
986
- value.text = !Array.isArray(value.text) ?
987
- [value.text] :
988
- value.text = value.text.sort();
1037
+ value.filter = !Array.isArray(value.filter) ? [value.filter] : value.filter;
1038
+ value.text = !Array.isArray(value.text) ? [value.text] : value.text;
989
1039
  }
990
1040
  // Function to add an option to the select element
991
1041
  var addOption = function (filt, text) {
1042
+ if (that.s.type.includes('html') && filt !== null && typeof filt === 'string') {
1043
+ filt.replace(/(<([^>]+)>)/ig, '');
1044
+ }
992
1045
  // Add text and value, stripping out any html if that is the column type
993
1046
  var opt = $$2('<option>', {
994
1047
  type: Array.isArray(filt) ? 'Array' : 'String',
995
- value: that.s.type.includes('html') && filt !== null && typeof filt === 'string' ?
996
- filt.replace(/(<([^>]+)>)/ig, '') :
997
- filt
1048
+ value: filt
998
1049
  })
1050
+ .data('sbv', filt)
999
1051
  .addClass(that.classes.option)
1000
1052
  .addClass(that.classes.notItalic)
1001
1053
  // Have to add the text this way so that special html characters are not escaped - &amp; etc.
@@ -1014,6 +1066,7 @@
1014
1066
  if (preDefined !== null && opt.val() === preDefined[0]) {
1015
1067
  opt.prop('selected', true);
1016
1068
  el.removeClass(Criteria.classes.italic);
1069
+ that.dom.valueTitle.removeProp('selected');
1017
1070
  }
1018
1071
  }
1019
1072
  };
@@ -1025,7 +1078,7 @@
1025
1078
  }
1026
1079
  // Otherwise the value that is in the cell is to be added
1027
1080
  else {
1028
- addOption(value.filter, value.text);
1081
+ addOption(value.filter, Array.isArray(value.text) ? value.text.join(', ') : value.text);
1029
1082
  }
1030
1083
  }
1031
1084
  options.sort(function (a, b) {
@@ -1072,6 +1125,64 @@
1072
1125
  }
1073
1126
  return el;
1074
1127
  };
1128
+ /**
1129
+ * Default initialisation function for select conditions
1130
+ */
1131
+ Criteria.initSelectSSP = function (that, fn, preDefined) {
1132
+ if (preDefined === void 0) { preDefined = null; }
1133
+ that.dom.valueTitle.prop('selected', true);
1134
+ // Declare select element to be used with all of the default classes and listeners.
1135
+ var el = $$2('<select/>')
1136
+ .addClass(Criteria.classes.value)
1137
+ .addClass(Criteria.classes.dropDown)
1138
+ .addClass(Criteria.classes.italic)
1139
+ .addClass(Criteria.classes.select)
1140
+ .append(that.dom.valueTitle)
1141
+ .on('change.dtsb', function () {
1142
+ $$2(this).removeClass(Criteria.classes.italic);
1143
+ fn(that, this);
1144
+ });
1145
+ if (that.c.greyscale) {
1146
+ el.addClass(Criteria.classes.greyscale);
1147
+ }
1148
+ var options = [];
1149
+ for (var _i = 0, _a = that.s.serverData[that.s.origData]; _i < _a.length; _i++) {
1150
+ var option = _a[_i];
1151
+ var value = option.value;
1152
+ var label = option.label;
1153
+ // Function to add an option to the select element
1154
+ var addOption = function (filt, text) {
1155
+ if (that.s.type.includes('html') && filt !== null && typeof filt === 'string') {
1156
+ filt.replace(/(<([^>]+)>)/ig, '');
1157
+ }
1158
+ // Add text and value, stripping out any html if that is the column type
1159
+ var opt = $$2('<option>', {
1160
+ type: Array.isArray(filt) ? 'Array' : 'String',
1161
+ value: filt
1162
+ })
1163
+ .data('sbv', filt)
1164
+ .addClass(that.classes.option)
1165
+ .addClass(that.classes.notItalic)
1166
+ // Have to add the text this way so that special html characters are not escaped - &amp; etc.
1167
+ .html(typeof text === 'string' ?
1168
+ text.replace(/(<([^>]+)>)/ig, '') :
1169
+ text);
1170
+ options.push(opt);
1171
+ // If this value was previously selected as indicated by preDefined, then select it again
1172
+ if (preDefined !== null && opt.val() === preDefined[0]) {
1173
+ opt.prop('selected', true);
1174
+ el.removeClass(Criteria.classes.italic);
1175
+ that.dom.valueTitle.removeProp('selected');
1176
+ }
1177
+ };
1178
+ addOption(value, label);
1179
+ }
1180
+ for (var _b = 0, options_2 = options; _b < options_2.length; _b++) {
1181
+ var opt = options_2[_b];
1182
+ el.append(opt);
1183
+ }
1184
+ return el;
1185
+ };
1075
1186
  /**
1076
1187
  * Default initialisation function for select array conditions
1077
1188
  *
@@ -1093,12 +1204,7 @@
1093
1204
  .addClass(Criteria.classes.input)
1094
1205
  .on('input.dtsb keypress.dtsb', that._throttle(function (e) {
1095
1206
  var code = e.keyCode || e.which;
1096
- if (!that.c.enterSearch &&
1097
- !(that.s.dt.settings()[0].oInit.search !== undefined &&
1098
- that.s.dt.settings()[0].oInit.search["return"]) ||
1099
- code === 13) {
1100
- return fn(that, this);
1101
- }
1207
+ return fn(that, this, code);
1102
1208
  }, searchDelay === null ? 100 : searchDelay));
1103
1209
  if (that.c.greyscale) {
1104
1210
  el.addClass(Criteria.classes.greyscale);
@@ -1126,27 +1232,17 @@
1126
1232
  .addClass(Criteria.classes.input)
1127
1233
  .on('input.dtsb keypress.dtsb', that._throttle(function (e) {
1128
1234
  var code = e.keyCode || e.which;
1129
- if (!that.c.enterSearch &&
1130
- !(that.s.dt.settings()[0].oInit.search !== undefined &&
1131
- that.s.dt.settings()[0].oInit.search["return"]) ||
1132
- code === 13) {
1133
- return fn(that, this);
1134
- }
1235
+ return fn(that, this, code);
1135
1236
  }, searchDelay === null ? 100 : searchDelay)),
1136
1237
  $$2('<span>')
1137
1238
  .addClass(that.classes.joiner)
1138
- .text(that.s.dt.i18n('searchBuilder.valueJoiner', that.c.i18n.valueJoiner)),
1239
+ .html(that.s.dt.i18n('searchBuilder.valueJoiner', that.c.i18n.valueJoiner)),
1139
1240
  $$2('<input/>')
1140
1241
  .addClass(Criteria.classes.value)
1141
1242
  .addClass(Criteria.classes.input)
1142
1243
  .on('input.dtsb keypress.dtsb', that._throttle(function (e) {
1143
1244
  var code = e.keyCode || e.which;
1144
- if (!that.c.enterSearch &&
1145
- !(that.s.dt.settings()[0].oInit.search !== undefined &&
1146
- that.s.dt.settings()[0].oInit.search["return"]) ||
1147
- code === 13) {
1148
- return fn(that, this);
1149
- }
1245
+ return fn(that, this, code);
1150
1246
  }, searchDelay === null ? 100 : searchDelay))
1151
1247
  ];
1152
1248
  if (that.c.greyscale) {
@@ -1181,20 +1277,12 @@
1181
1277
  .on('change.dtsb', that._throttle(function () {
1182
1278
  return fn(that, this);
1183
1279
  }, searchDelay === null ? 100 : searchDelay))
1184
- .on('input.dtsb keypress.dtsb', that.c.enterSearch ||
1185
- that.s.dt.settings()[0].oInit.search !== undefined &&
1186
- that.s.dt.settings()[0].oInit.search["return"] ?
1187
- function (e) {
1188
- that._throttle(function () {
1189
- var code = e.keyCode || e.which;
1190
- if (code === 13) {
1191
- return fn(that, this);
1192
- }
1193
- }, searchDelay === null ? 100 : searchDelay);
1194
- } :
1280
+ .on('input.dtsb keypress.dtsb', function (e) {
1195
1281
  that._throttle(function () {
1196
- return fn(that, this);
1197
- }, searchDelay === null ? 100 : searchDelay));
1282
+ var code = e.keyCode || e.which;
1283
+ return fn(that, this, code);
1284
+ }, searchDelay === null ? 100 : searchDelay);
1285
+ });
1198
1286
  if (that.c.greyscale) {
1199
1287
  el.addClass(Criteria.classes.greyscale);
1200
1288
  }
@@ -1234,28 +1322,15 @@
1234
1322
  function () {
1235
1323
  fn(that, _this);
1236
1324
  })
1237
- .on('input.dtsb keypress.dtsb', !that.c.enterSearch &&
1238
- !(that.s.dt.settings()[0].oInit.search !== undefined &&
1239
- that.s.dt.settings()[0].oInit.search["return"]) &&
1240
- searchDelay !== null ?
1325
+ .on('input.dtsb keypress.dtsb', function (e) {
1241
1326
  that.s.dt.settings()[0].oApi._fnThrottle(function () {
1242
- return fn(that, this);
1243
- }, searchDelay) :
1244
- that.c.enterSearch ||
1245
- that.s.dt.settings()[0].oInit.search !== undefined &&
1246
- that.s.dt.settings()[0].oInit.search["return"] ?
1247
- function (e) {
1248
- var code = e.keyCode || e.which;
1249
- if (code === 13) {
1250
- fn(that, _this);
1251
- }
1252
- } :
1253
- function () {
1254
- fn(that, _this);
1255
- }),
1327
+ var code = e.keyCode || e.which;
1328
+ return fn(that, this, code);
1329
+ }, searchDelay === null ? 0 : searchDelay);
1330
+ }),
1256
1331
  $$2('<span>')
1257
1332
  .addClass(that.classes.joiner)
1258
- .text(that.s.dt.i18n('searchBuilder.valueJoiner', that.c.i18n.valueJoiner)),
1333
+ .html(that.s.dt.i18n('searchBuilder.valueJoiner', that.c.i18n.valueJoiner)),
1259
1334
  $$2('<input/>')
1260
1335
  .addClass(Criteria.classes.value)
1261
1336
  .addClass(Criteria.classes.input)
@@ -1277,18 +1352,10 @@
1277
1352
  that.s.dt.settings()[0].oApi._fnThrottle(function () {
1278
1353
  return fn(that, this);
1279
1354
  }, searchDelay) :
1280
- that.c.enterSearch ||
1281
- that.s.dt.settings()[0].oInit.search !== undefined &&
1282
- that.s.dt.settings()[0].oInit.search["return"] ?
1283
- function (e) {
1284
- var code = e.keyCode || e.which;
1285
- if (code === 13) {
1286
- fn(that, _this);
1287
- }
1288
- } :
1289
- function () {
1290
- fn(that, _this);
1291
- })
1355
+ function (e) {
1356
+ var code = e.keyCode || e.which;
1357
+ fn(that, _this, code);
1358
+ })
1292
1359
  ];
1293
1360
  if (that.c.greyscale) {
1294
1361
  els[0].addClass(Criteria.classes.greyscale);
@@ -1317,7 +1384,7 @@
1317
1384
  element.children('option').length -
1318
1385
  element.children('option.' + Criteria.classes.notItalic).length &&
1319
1386
  element.children('option:selected').length === 1 &&
1320
- element.children('option:selected')[0] === element.children('option:hidden')[0]) {
1387
+ element.children('option:selected')[0] === element.children('option')[0]) {
1321
1388
  allFilled = false;
1322
1389
  }
1323
1390
  }
@@ -1346,11 +1413,7 @@
1346
1413
  for (var _i = 0, el_3 = el; _i < el_3.length; _i++) {
1347
1414
  var element = el_3[_i];
1348
1415
  if (element.is('select')) {
1349
- var val = element.children('option:selected').val();
1350
- // If the type of the option is an array we need to split it up and sort it
1351
- values.push(element.children('option:selected').attr('type') === 'Array' ?
1352
- val.split(',').sort() :
1353
- val);
1416
+ values.push(Criteria._escapeHTML(element.children('option:selected').data('sbv')));
1354
1417
  }
1355
1418
  }
1356
1419
  return values;
@@ -1364,7 +1427,7 @@
1364
1427
  for (var _i = 0, el_4 = el; _i < el_4.length; _i++) {
1365
1428
  var element = el_4[_i];
1366
1429
  if (element.is('input')) {
1367
- values.push(element.val());
1430
+ values.push(Criteria._escapeHTML(element.val()));
1368
1431
  }
1369
1432
  }
1370
1433
  return values;
@@ -1372,14 +1435,19 @@
1372
1435
  /**
1373
1436
  * Function that is run on each element as a call back when a search should be triggered
1374
1437
  */
1375
- Criteria.updateListener = function (that, el) {
1438
+ Criteria.updateListener = function (that, el, code) {
1376
1439
  // When the value is changed the criteria is now complete so can be included in searches
1377
1440
  // Get the condition from the map based on the key that has been selected for the condition
1378
1441
  var condition = that.s.conditions[that.s.condition];
1379
1442
  that.s.filled = condition.isInputValid(that.dom.value, that);
1380
1443
  that.s.value = condition.inputValue(that.dom.value, that);
1381
1444
  if (!that.s.filled) {
1382
- that.s.dt.draw();
1445
+ if (!that.c.enterSearch &&
1446
+ !(that.s.dt.settings()[0].oInit.search !== undefined &&
1447
+ that.s.dt.settings()[0].oInit.search["return"]) ||
1448
+ code === 13) {
1449
+ that.s.dt.draw();
1450
+ }
1383
1451
  return;
1384
1452
  }
1385
1453
  if (!Array.isArray(that.s.value)) {
@@ -1417,8 +1485,13 @@
1417
1485
  }
1418
1486
  }
1419
1487
  }
1420
- // Trigger a search
1421
- that.s.dt.draw();
1488
+ if (!that.c.enterSearch &&
1489
+ !(that.s.dt.settings()[0].oInit.search !== undefined &&
1490
+ that.s.dt.settings()[0].oInit.search["return"]) ||
1491
+ code === 13) {
1492
+ // Trigger a search
1493
+ that.s.dt.draw();
1494
+ }
1422
1495
  // Refocus the element and set the correct cursor position
1423
1496
  if (idx !== null) {
1424
1497
  that.dom.value[idx].removeClass(that.classes.italic);
@@ -1562,8 +1635,8 @@
1562
1635
  inputValue: Criteria.inputValueInput,
1563
1636
  isInputValid: Criteria.isInputValidInput,
1564
1637
  search: function (value, comparison, that) {
1565
- return moment(value, that.s.dateFormat).valueOf() ===
1566
- moment(comparison[0], that.s.dateFormat).valueOf();
1638
+ return moment()(value, that.s.dateFormat).valueOf() ===
1639
+ moment()(comparison[0], that.s.dateFormat).valueOf();
1567
1640
  }
1568
1641
  },
1569
1642
  // eslint-disable-next-line sort-keys
@@ -1575,8 +1648,8 @@
1575
1648
  inputValue: Criteria.inputValueInput,
1576
1649
  isInputValid: Criteria.isInputValidInput,
1577
1650
  search: function (value, comparison, that) {
1578
- return moment(value, that.s.dateFormat).valueOf() !==
1579
- moment(comparison[0], that.s.dateFormat).valueOf();
1651
+ return moment()(value, that.s.dateFormat).valueOf() !==
1652
+ moment()(comparison[0], that.s.dateFormat).valueOf();
1580
1653
  }
1581
1654
  },
1582
1655
  '<': {
@@ -1587,7 +1660,7 @@
1587
1660
  inputValue: Criteria.inputValueInput,
1588
1661
  isInputValid: Criteria.isInputValidInput,
1589
1662
  search: function (value, comparison, that) {
1590
- return moment(value, that.s.dateFormat).valueOf() < moment(comparison[0], that.s.dateFormat).valueOf();
1663
+ return moment()(value, that.s.dateFormat).valueOf() < moment()(comparison[0], that.s.dateFormat).valueOf();
1591
1664
  }
1592
1665
  },
1593
1666
  '>': {
@@ -1598,7 +1671,7 @@
1598
1671
  inputValue: Criteria.inputValueInput,
1599
1672
  isInputValid: Criteria.isInputValidInput,
1600
1673
  search: function (value, comparison, that) {
1601
- return moment(value, that.s.dateFormat).valueOf() > moment(comparison[0], that.s.dateFormat).valueOf();
1674
+ return moment()(value, that.s.dateFormat).valueOf() > moment()(comparison[0], that.s.dateFormat).valueOf();
1602
1675
  }
1603
1676
  },
1604
1677
  'between': {
@@ -1609,9 +1682,9 @@
1609
1682
  inputValue: Criteria.inputValueInput,
1610
1683
  isInputValid: Criteria.isInputValidInput,
1611
1684
  search: function (value, comparison, that) {
1612
- var val = moment(value, that.s.dateFormat).valueOf();
1613
- var comp0 = moment(comparison[0], that.s.dateFormat).valueOf();
1614
- var comp1 = moment(comparison[1], that.s.dateFormat).valueOf();
1685
+ var val = moment()(value, that.s.dateFormat).valueOf();
1686
+ var comp0 = moment()(comparison[0], that.s.dateFormat).valueOf();
1687
+ var comp1 = moment()(comparison[1], that.s.dateFormat).valueOf();
1615
1688
  if (comp0 < comp1) {
1616
1689
  return comp0 <= val && val <= comp1;
1617
1690
  }
@@ -1629,9 +1702,9 @@
1629
1702
  inputValue: Criteria.inputValueInput,
1630
1703
  isInputValid: Criteria.isInputValidInput,
1631
1704
  search: function (value, comparison, that) {
1632
- var val = moment(value, that.s.dateFormat).valueOf();
1633
- var comp0 = moment(comparison[0], that.s.dateFormat).valueOf();
1634
- var comp1 = moment(comparison[1], that.s.dateFormat).valueOf();
1705
+ var val = moment()(value, that.s.dateFormat).valueOf();
1706
+ var comp0 = moment()(comparison[0], that.s.dateFormat).valueOf();
1707
+ var comp1 = moment()(comparison[1], that.s.dateFormat).valueOf();
1635
1708
  if (comp0 < comp1) {
1636
1709
  return !(+comp0 <= +val && +val <= +comp1);
1637
1710
  }
@@ -1685,8 +1758,8 @@
1685
1758
  inputValue: Criteria.inputValueInput,
1686
1759
  isInputValid: Criteria.isInputValidInput,
1687
1760
  search: function (value, comparison, that) {
1688
- return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts
1689
- === luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1761
+ return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
1762
+ === luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1690
1763
  }
1691
1764
  },
1692
1765
  // eslint-disable-next-line sort-keys
@@ -1698,8 +1771,8 @@
1698
1771
  inputValue: Criteria.inputValueInput,
1699
1772
  isInputValid: Criteria.isInputValidInput,
1700
1773
  search: function (value, comparison, that) {
1701
- return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts
1702
- !== luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1774
+ return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
1775
+ !== luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1703
1776
  }
1704
1777
  },
1705
1778
  '<': {
@@ -1710,8 +1783,8 @@
1710
1783
  inputValue: Criteria.inputValueInput,
1711
1784
  isInputValid: Criteria.isInputValidInput,
1712
1785
  search: function (value, comparison, that) {
1713
- return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts
1714
- < luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1786
+ return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
1787
+ < luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1715
1788
  }
1716
1789
  },
1717
1790
  '>': {
@@ -1722,8 +1795,8 @@
1722
1795
  inputValue: Criteria.inputValueInput,
1723
1796
  isInputValid: Criteria.isInputValidInput,
1724
1797
  search: function (value, comparison, that) {
1725
- return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts
1726
- > luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1798
+ return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
1799
+ > luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1727
1800
  }
1728
1801
  },
1729
1802
  'between': {
@@ -1734,9 +1807,9 @@
1734
1807
  inputValue: Criteria.inputValueInput,
1735
1808
  isInputValid: Criteria.isInputValidInput,
1736
1809
  search: function (value, comparison, that) {
1737
- var val = luxon.DateTime.fromFormat(value, that.s.dateFormat).ts;
1738
- var comp0 = luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1739
- var comp1 = luxon.DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;
1810
+ var val = luxon().DateTime.fromFormat(value, that.s.dateFormat).ts;
1811
+ var comp0 = luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1812
+ var comp1 = luxon().DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;
1740
1813
  if (comp0 < comp1) {
1741
1814
  return comp0 <= val && val <= comp1;
1742
1815
  }
@@ -1754,9 +1827,9 @@
1754
1827
  inputValue: Criteria.inputValueInput,
1755
1828
  isInputValid: Criteria.isInputValidInput,
1756
1829
  search: function (value, comparison, that) {
1757
- var val = luxon.DateTime.fromFormat(value, that.s.dateFormat).ts;
1758
- var comp0 = luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1759
- var comp1 = luxon.DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;
1830
+ var val = luxon().DateTime.fromFormat(value, that.s.dateFormat).ts;
1831
+ var comp0 = luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1832
+ var comp1 = luxon().DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;
1760
1833
  if (comp0 < comp1) {
1761
1834
  return !(+comp0 <= +val && +val <= +comp1);
1762
1835
  }
@@ -1948,13 +2021,7 @@
1948
2021
  inputValue: Criteria.inputValueSelect,
1949
2022
  isInputValid: Criteria.isInputValidSelect,
1950
2023
  search: function (value, comparison) {
1951
- var val = value.indexOf('-') === 0 ?
1952
- '-' + value.replace(/[^0-9.]/g, '') :
1953
- value.replace(/[^0-9.]/g, '');
1954
- var comp = comparison[0].indexOf('-') === 0 ?
1955
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
1956
- comparison[0].replace(/[^0-9.]/g, '');
1957
- return +val === +comp;
2024
+ return Criteria.parseNumFmt(value) === Criteria.parseNumFmt(comparison[0]);
1958
2025
  }
1959
2026
  },
1960
2027
  // eslint-disable-next-line sort-keys
@@ -1966,13 +2033,7 @@
1966
2033
  inputValue: Criteria.inputValueSelect,
1967
2034
  isInputValid: Criteria.isInputValidSelect,
1968
2035
  search: function (value, comparison) {
1969
- var val = value.indexOf('-') === 0 ?
1970
- '-' + value.replace(/[^0-9.]/g, '') :
1971
- value.replace(/[^0-9.]/g, '');
1972
- var comp = comparison[0].indexOf('-') === 0 ?
1973
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
1974
- comparison[0].replace(/[^0-9.]/g, '');
1975
- return +val !== +comp;
2036
+ return Criteria.parseNumFmt(value) !== Criteria.parseNumFmt(comparison[0]);
1976
2037
  }
1977
2038
  },
1978
2039
  '<': {
@@ -1983,13 +2044,7 @@
1983
2044
  inputValue: Criteria.inputValueInput,
1984
2045
  isInputValid: Criteria.isInputValidInput,
1985
2046
  search: function (value, comparison) {
1986
- var val = value.indexOf('-') === 0 ?
1987
- '-' + value.replace(/[^0-9.]/g, '') :
1988
- value.replace(/[^0-9.]/g, '');
1989
- var comp = comparison[0].indexOf('-') === 0 ?
1990
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
1991
- comparison[0].replace(/[^0-9.]/g, '');
1992
- return +val < +comp;
2047
+ return Criteria.parseNumFmt(value) < Criteria.parseNumFmt(comparison[0]);
1993
2048
  }
1994
2049
  },
1995
2050
  '<=': {
@@ -2000,13 +2055,7 @@
2000
2055
  inputValue: Criteria.inputValueInput,
2001
2056
  isInputValid: Criteria.isInputValidInput,
2002
2057
  search: function (value, comparison) {
2003
- var val = value.indexOf('-') === 0 ?
2004
- '-' + value.replace(/[^0-9.]/g, '') :
2005
- value.replace(/[^0-9.]/g, '');
2006
- var comp = comparison[0].indexOf('-') === 0 ?
2007
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
2008
- comparison[0].replace(/[^0-9.]/g, '');
2009
- return +val <= +comp;
2058
+ return Criteria.parseNumFmt(value) <= Criteria.parseNumFmt(comparison[0]);
2010
2059
  }
2011
2060
  },
2012
2061
  '>=': {
@@ -2017,13 +2066,7 @@
2017
2066
  inputValue: Criteria.inputValueInput,
2018
2067
  isInputValid: Criteria.isInputValidInput,
2019
2068
  search: function (value, comparison) {
2020
- var val = value.indexOf('-') === 0 ?
2021
- '-' + value.replace(/[^0-9.]/g, '') :
2022
- value.replace(/[^0-9.]/g, '');
2023
- var comp = comparison[0].indexOf('-') === 0 ?
2024
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
2025
- comparison[0].replace(/[^0-9.]/g, '');
2026
- return +val >= +comp;
2069
+ return Criteria.parseNumFmt(value) >= Criteria.parseNumFmt(comparison[0]);
2027
2070
  }
2028
2071
  },
2029
2072
  // eslint-disable-next-line sort-keys
@@ -2035,13 +2078,7 @@
2035
2078
  inputValue: Criteria.inputValueInput,
2036
2079
  isInputValid: Criteria.isInputValidInput,
2037
2080
  search: function (value, comparison) {
2038
- var val = value.indexOf('-') === 0 ?
2039
- '-' + value.replace(/[^0-9.]/g, '') :
2040
- value.replace(/[^0-9.]/g, '');
2041
- var comp = comparison[0].indexOf('-') === 0 ?
2042
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
2043
- comparison[0].replace(/[^0-9.]/g, '');
2044
- return +val > +comp;
2081
+ return Criteria.parseNumFmt(value) > Criteria.parseNumFmt(comparison[0]);
2045
2082
  }
2046
2083
  },
2047
2084
  'between': {
@@ -2052,15 +2089,9 @@
2052
2089
  inputValue: Criteria.inputValueInput,
2053
2090
  isInputValid: Criteria.isInputValidInput,
2054
2091
  search: function (value, comparison) {
2055
- var val = value.indexOf('-') === 0 ?
2056
- '-' + value.replace(/[^0-9.]/g, '') :
2057
- value.replace(/[^0-9.]/g, '');
2058
- var comp0 = comparison[0].indexOf('-') === 0 ?
2059
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
2060
- comparison[0].replace(/[^0-9.]/g, '');
2061
- var comp1 = comparison[1].indexOf('-') === 0 ?
2062
- '-' + comparison[1].replace(/[^0-9.]/g, '') :
2063
- comparison[1].replace(/[^0-9.]/g, '');
2092
+ var val = Criteria.parseNumFmt(value);
2093
+ var comp0 = Criteria.parseNumFmt(comparison[0]);
2094
+ var comp1 = Criteria.parseNumFmt(comparison[1]);
2064
2095
  if (+comp0 < +comp1) {
2065
2096
  return +comp0 <= +val && +val <= +comp1;
2066
2097
  }
@@ -2078,15 +2109,9 @@
2078
2109
  inputValue: Criteria.inputValueInput,
2079
2110
  isInputValid: Criteria.isInputValidInput,
2080
2111
  search: function (value, comparison) {
2081
- var val = value.indexOf('-') === 0 ?
2082
- '-' + value.replace(/[^0-9.]/g, '') :
2083
- value.replace(/[^0-9.]/g, '');
2084
- var comp0 = comparison[0].indexOf('-') === 0 ?
2085
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
2086
- comparison[0].replace(/[^0-9.]/g, '');
2087
- var comp1 = comparison[1].indexOf('-') === 0 ?
2088
- '-' + comparison[1].replace(/[^0-9.]/g, '') :
2089
- comparison[1].replace(/[^0-9.]/g, '');
2112
+ var val = Criteria.parseNumFmt(value);
2113
+ var comp0 = Criteria.parseNumFmt(comparison[0]);
2114
+ var comp1 = Criteria.parseNumFmt(comparison[1]);
2090
2115
  if (+comp0 < +comp1) {
2091
2116
  return !(+comp0 <= +val && +val <= +comp1);
2092
2117
  }
@@ -2425,10 +2450,11 @@
2425
2450
  * The Group class is used within SearchBuilder to represent a group of criteria
2426
2451
  */
2427
2452
  var Group = /** @class */ (function () {
2428
- function Group(table, opts, topGroup, index, isChild, depth) {
2453
+ function Group(table, opts, topGroup, index, isChild, depth, serverData) {
2429
2454
  if (index === void 0) { index = 0; }
2430
2455
  if (isChild === void 0) { isChild = false; }
2431
2456
  if (depth === void 0) { depth = 1; }
2457
+ if (serverData === void 0) { serverData = undefined; }
2432
2458
  // Check that the required version of DataTables is included
2433
2459
  if (!dataTable$1 || !dataTable$1.versionCheck || !dataTable$1.versionCheck('1.10.0')) {
2434
2460
  throw new Error('SearchBuilder requires DataTables 1.10 or newer');
@@ -2445,6 +2471,7 @@
2445
2471
  logic: undefined,
2446
2472
  opts: opts,
2447
2473
  preventRedraw: false,
2474
+ serverData: serverData,
2448
2475
  toDrop: undefined,
2449
2476
  topGroup: topGroup
2450
2477
  };
@@ -2528,7 +2555,7 @@
2528
2555
  return;
2529
2556
  }
2530
2557
  this.s.logic = loadedDetails.logic;
2531
- this.dom.logic.children().first().text(this.s.logic === 'OR'
2558
+ this.dom.logic.children().first().html(this.s.logic === 'OR'
2532
2559
  ? this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr)
2533
2560
  : this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));
2534
2561
  // Add all of the criteria, be it a sub group or a criteria
@@ -2547,7 +2574,7 @@
2547
2574
  for (var _b = 0, _c = this.s.criteria; _b < _c.length; _b++) {
2548
2575
  var crit = _c[_b];
2549
2576
  if (crit.criteria instanceof Criteria) {
2550
- crit.criteria.updateArrows(this.s.criteria.length > 1, false);
2577
+ crit.criteria.updateArrows(this.s.criteria.length > 1);
2551
2578
  this._setCriteriaListeners(crit.criteria);
2552
2579
  }
2553
2580
  }
@@ -2585,7 +2612,9 @@
2585
2612
  this.s.criteria[i].criteria.dom.container.insertBefore(this.dom.add);
2586
2613
  // Set listeners for various points
2587
2614
  this._setCriteriaListeners(crit);
2615
+ this.s.criteria[i].criteria.s.preventRedraw = this.s.preventRedraw;
2588
2616
  this.s.criteria[i].criteria.rebuild(this.s.criteria[i].criteria.getDetails());
2617
+ this.s.criteria[i].criteria.s.preventRedraw = false;
2589
2618
  }
2590
2619
  else if (crit instanceof Group && crit.s.criteria.length > 0) {
2591
2620
  // Reset the index to the new value
@@ -2594,7 +2623,9 @@
2594
2623
  // Add the sub group to the group
2595
2624
  this.s.criteria[i].criteria.dom.container.insertBefore(this.dom.add);
2596
2625
  // Redraw the contents of the group
2626
+ crit.s.preventRedraw = this.s.preventRedraw;
2597
2627
  crit.redrawContents();
2628
+ crit.s.preventRedraw = false;
2598
2629
  this._setGroupListeners(crit);
2599
2630
  }
2600
2631
  else {
@@ -2611,8 +2642,8 @@
2611
2642
  Group.prototype.redrawLogic = function () {
2612
2643
  for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
2613
2644
  var crit = _a[_i];
2614
- if (crit instanceof Group) {
2615
- crit.redrawLogic();
2645
+ if (crit.criteria instanceof Group) {
2646
+ crit.criteria.redrawLogic();
2616
2647
  }
2617
2648
  }
2618
2649
  this.setupLogic();
@@ -2648,12 +2679,19 @@
2648
2679
  }
2649
2680
  return;
2650
2681
  }
2651
- // Set width, take 2 for the border
2652
- var height = this.dom.container.height() - 1;
2653
2682
  this.dom.clear.height('0px');
2654
- this.dom.logicContainer.append(this.dom.clear).width(height);
2683
+ this.dom.logicContainer.append(this.dom.clear);
2655
2684
  // Prepend logic button
2656
2685
  this.dom.container.prepend(this.dom.logicContainer);
2686
+ for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
2687
+ var crit = _a[_i];
2688
+ if (crit.criteria instanceof Criteria) {
2689
+ crit.criteria.setupButtons();
2690
+ }
2691
+ }
2692
+ // Set width, take 2 for the border
2693
+ var height = this.dom.container.outerHeight() - 1;
2694
+ this.dom.logicContainer.width(height);
2657
2695
  this._setLogicListener();
2658
2696
  // Set criteria left margin
2659
2697
  this.dom.container.css('margin-left', this.dom.logicContainer.outerHeight(true));
@@ -2702,11 +2740,10 @@
2702
2740
  *
2703
2741
  * @param crit Instance of Criteria to be added to the group
2704
2742
  */
2705
- Group.prototype.addCriteria = function (crit, redraw) {
2743
+ Group.prototype.addCriteria = function (crit) {
2706
2744
  if (crit === void 0) { crit = null; }
2707
- if (redraw === void 0) { redraw = true; }
2708
2745
  var index = crit === null ? this.s.criteria.length : crit.s.index;
2709
- var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, index, this.s.depth);
2746
+ var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, index, this.s.depth, this.s.serverData);
2710
2747
  // If a Criteria has been passed in then set the values to continue that
2711
2748
  if (crit !== null) {
2712
2749
  criteria.c = crit.c;
@@ -2742,7 +2779,7 @@
2742
2779
  for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
2743
2780
  var opt = _a[_i];
2744
2781
  if (opt.criteria instanceof Criteria) {
2745
- opt.criteria.updateArrows(this.s.criteria.length > 1, redraw);
2782
+ opt.criteria.updateArrows(this.s.criteria.length > 1);
2746
2783
  }
2747
2784
  }
2748
2785
  this._setCriteriaListeners(criteria);
@@ -2785,7 +2822,7 @@
2785
2822
  */
2786
2823
  Group.prototype._addPrevGroup = function (loadedGroup) {
2787
2824
  var idx = this.s.criteria.length;
2788
- var group = new Group(this.s.dt, this.c, this.s.topGroup, idx, true, this.s.depth + 1);
2825
+ var group = new Group(this.s.dt, this.c, this.s.topGroup, idx, true, this.s.depth + 1, this.s.serverData);
2789
2826
  // Add the new group to the criteria array
2790
2827
  this.s.criteria.push({
2791
2828
  criteria: group,
@@ -2805,7 +2842,7 @@
2805
2842
  */
2806
2843
  Group.prototype._addPrevCriteria = function (loadedCriteria) {
2807
2844
  var idx = this.s.criteria.length;
2808
- var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, idx, this.s.depth);
2845
+ var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, idx, this.s.depth, this.s.serverData);
2809
2846
  criteria.populate();
2810
2847
  // Add the new criteria to the criteria array
2811
2848
  this.s.criteria.push({
@@ -2813,9 +2850,13 @@
2813
2850
  index: idx
2814
2851
  });
2815
2852
  // Rebuild it with the previous conditions for that criteria
2853
+ criteria.s.preventRedraw = this.s.preventRedraw;
2816
2854
  criteria.rebuild(loadedCriteria);
2855
+ criteria.s.preventRedraw = false;
2817
2856
  this.s.criteria[idx].criteria = criteria;
2818
- this.s.topGroup.trigger('dtsb-redrawContents');
2857
+ if (!this.s.preventRedraw) {
2858
+ this.s.topGroup.trigger('dtsb-redrawContents');
2859
+ }
2819
2860
  };
2820
2861
  /**
2821
2862
  * Checks And the criteria using AND logic
@@ -2927,14 +2968,13 @@
2927
2968
  criteria.destroy();
2928
2969
  _this.s.dt.draw();
2929
2970
  _this.s.topGroup.trigger('dtsb-redrawContents');
2930
- _this.s.topGroup.trigger('dtsb-updateTitle');
2931
2971
  return false;
2932
2972
  });
2933
2973
  criteria.dom.right
2934
2974
  .unbind('click')
2935
2975
  .on('click.dtsb', function () {
2936
2976
  var idx = criteria.s.index;
2937
- var group = new Group(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index, true, _this.s.depth + 1);
2977
+ var group = new Group(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index, true, _this.s.depth + 1, _this.s.serverData);
2938
2978
  // Add the criteria that is to be moved to the new group
2939
2979
  group.addCriteria(criteria);
2940
2980
  // Update the details in the current groups criteria array
@@ -2947,7 +2987,7 @@
2947
2987
  criteria.dom.left
2948
2988
  .unbind('click')
2949
2989
  .on('click.dtsb', function () {
2950
- _this.s.toDrop = new Criteria(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index);
2990
+ _this.s.toDrop = new Criteria(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index, undefined, _this.s.serverData);
2951
2991
  _this.s.toDrop.s = criteria.s;
2952
2992
  _this.s.toDrop.c = criteria.c;
2953
2993
  _this.s.toDrop.classes = criteria.classes;
@@ -2977,7 +3017,6 @@
2977
3017
  return false;
2978
3018
  }
2979
3019
  _this.destroy();
2980
- _this.s.topGroup.trigger('dtsb-updateTitle');
2981
3020
  _this.s.topGroup.trigger('dtsb-redrawContents');
2982
3021
  return false;
2983
3022
  });
@@ -3017,8 +3056,8 @@
3017
3056
  .on('dtsb-dropCriteria.dtsb', function () {
3018
3057
  var toDrop = group.s.toDrop;
3019
3058
  toDrop.s.index = group.s.index;
3020
- toDrop.updateArrows(_this.s.criteria.length > 1, false);
3021
- _this.addCriteria(toDrop, false);
3059
+ toDrop.updateArrows(_this.s.criteria.length > 1);
3060
+ _this.addCriteria(toDrop);
3022
3061
  return false;
3023
3062
  });
3024
3063
  group.setListeners();
@@ -3028,8 +3067,8 @@
3028
3067
  */
3029
3068
  Group.prototype._setup = function () {
3030
3069
  this.setListeners();
3031
- this.dom.add.text(this.s.dt.i18n('searchBuilder.add', this.c.i18n.add));
3032
- this.dom.logic.children().first().text(this.c.logic === 'OR'
3070
+ this.dom.add.html(this.s.dt.i18n('searchBuilder.add', this.c.i18n.add));
3071
+ this.dom.logic.children().first().html(this.c.logic === 'OR'
3033
3072
  ? this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr)
3034
3073
  : this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));
3035
3074
  this.s.logic = this.c.logic === 'OR' ? 'OR' : 'AND';
@@ -3066,11 +3105,11 @@
3066
3105
  Group.prototype._toggleLogic = function () {
3067
3106
  if (this.s.logic === 'OR') {
3068
3107
  this.s.logic = 'AND';
3069
- this.dom.logic.children().first().text(this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));
3108
+ this.dom.logic.children().first().html(this.s.dt.i18n('searchBuilder.logicAnd', this.c.i18n.logicAnd));
3070
3109
  }
3071
3110
  else if (this.s.logic === 'AND') {
3072
3111
  this.s.logic = 'OR';
3073
- this.dom.logic.children().first().text(this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr));
3112
+ this.dom.logic.children().first().html(this.s.dt.i18n('searchBuilder.logicOr', this.c.i18n.logicOr));
3074
3113
  }
3075
3114
  };
3076
3115
  Group.version = '1.1.0';
@@ -3178,6 +3217,7 @@
3178
3217
  dt: table,
3179
3218
  opts: opts,
3180
3219
  search: undefined,
3220
+ serverData: undefined,
3181
3221
  topGroup: undefined
3182
3222
  };
3183
3223
  // If searchbuilder is already defined for this table then return
@@ -3185,6 +3225,20 @@
3185
3225
  return;
3186
3226
  }
3187
3227
  table.settings()[0]._searchBuilder = this;
3228
+ // If using SSP we want to include the previous state in the very first server call
3229
+ if (this.s.dt.page.info().serverSide) {
3230
+ this.s.dt.on('preXhr.dtsb', function (e, settings, data) {
3231
+ var loadedState = _this.s.dt.state.loaded();
3232
+ if (loadedState && loadedState.searchBuilder) {
3233
+ data.searchBuilder = _this._collapseArray(loadedState.searchBuilder);
3234
+ }
3235
+ });
3236
+ this.s.dt.on('xhr.dtsb', function (e, settings, json) {
3237
+ if (json && json.searchBuilder && json.searchBuilder.options) {
3238
+ _this.s.serverData = json.searchBuilder.options;
3239
+ }
3240
+ });
3241
+ }
3188
3242
  // Run the remaining setup when the table is initialised
3189
3243
  if (this.s.dt.settings()[0]._bInitComplete) {
3190
3244
  this._setUp();
@@ -3227,6 +3281,8 @@
3227
3281
  this.s.topGroup.s.preventRedraw = true;
3228
3282
  this.s.topGroup.rebuild(details);
3229
3283
  this.s.topGroup.s.preventRedraw = false;
3284
+ this._checkClear();
3285
+ this._updateTitle(this.s.topGroup.count());
3230
3286
  this.s.topGroup.redrawContents();
3231
3287
  this.s.dt.draw(false);
3232
3288
  this.s.topGroup.setListeners();
@@ -3308,11 +3364,16 @@
3308
3364
  }
3309
3365
  }
3310
3366
  }
3311
- this.s.topGroup = new Group(this.s.dt, this.c, undefined);
3367
+ this.s.topGroup = new Group(this.s.dt, this.c, undefined, undefined, undefined, undefined, this.s.serverData);
3312
3368
  this._setClearListener();
3313
3369
  this.s.dt.on('stateSaveParams.dtsb', function (e, settings, data) {
3314
3370
  data.searchBuilder = _this.getDetails();
3315
- data.page = _this.s.dt.page();
3371
+ if (!data.scroller) {
3372
+ data.page = _this.s.dt.page();
3373
+ }
3374
+ else {
3375
+ data.start = _this.s.dt.state().start;
3376
+ }
3316
3377
  });
3317
3378
  this.s.dt.on('stateLoadParams.dtsb', function (e, settings, data) {
3318
3379
  _this.rebuild(data.searchBuilder);
@@ -3323,13 +3384,25 @@
3323
3384
  data.searchBuilder = _this._collapseArray(_this.getDetails(true));
3324
3385
  }
3325
3386
  });
3387
+ this.s.dt.on('column-reorder', function () {
3388
+ _this.rebuild(_this.getDetails());
3389
+ });
3326
3390
  if (loadState) {
3327
3391
  var loadedState = this.s.dt.state.loaded();
3328
3392
  // If the loaded State is not null rebuild based on it for statesave
3329
3393
  if (loadedState !== null && loadedState.searchBuilder !== undefined) {
3330
3394
  this.s.topGroup.rebuild(loadedState.searchBuilder);
3331
3395
  this.s.topGroup.dom.container.trigger('dtsb-redrawContents');
3332
- this.s.dt.page(loadedState.page).draw('page');
3396
+ // If using SSP we want to restrict the amount of server calls that take place
3397
+ // and this information will already have been processed
3398
+ if (!this.s.dt.page.info().serverSide) {
3399
+ if (loadedState.page) {
3400
+ this.s.dt.page(loadedState.page).draw('page');
3401
+ }
3402
+ else if (this.s.dt.scroller && loadedState.scroller) {
3403
+ this.s.dt.scroller().scrollToRow(loadedState.scroller.topRow);
3404
+ }
3405
+ }
3333
3406
  this.s.topGroup.setListeners();
3334
3407
  }
3335
3408
  // Otherwise load any predefined options
@@ -3447,7 +3520,7 @@
3447
3520
  var _this = this;
3448
3521
  this.dom.clearAll.unbind('click');
3449
3522
  this.dom.clearAll.on('click.dtsb', function () {
3450
- _this.s.topGroup = new Group(_this.s.dt, _this.c, undefined);
3523
+ _this.s.topGroup = new Group(_this.s.dt, _this.c, undefined, undefined, undefined, undefined, _this.s.serverData);
3451
3524
  _this._build();
3452
3525
  _this.s.dt.draw();
3453
3526
  _this.s.topGroup.setListeners();
@@ -3471,9 +3544,25 @@
3471
3544
  var count = _this.s.topGroup.count();
3472
3545
  _this._updateTitle(count);
3473
3546
  _this._filterChanged(count);
3474
- _this.s.dt.draw();
3547
+ // If using SSP we want to restrict the amount of server calls that take place
3548
+ // and this information will already have been processed
3549
+ if (!_this.s.dt.page.info().serverSide) {
3550
+ _this.s.dt.draw();
3551
+ }
3475
3552
  _this.s.dt.state.save();
3476
3553
  });
3554
+ this.s.topGroup.dom.container.unbind('dtsb-redrawContents-noDraw');
3555
+ this.s.topGroup.dom.container.on('dtsb-redrawContents-noDraw.dtsb', function () {
3556
+ _this._checkClear();
3557
+ _this.s.topGroup.s.preventRedraw = true;
3558
+ _this.s.topGroup.redrawContents();
3559
+ _this.s.topGroup.s.preventRedraw = false;
3560
+ _this.s.topGroup.setupLogic();
3561
+ _this._setEmptyListener();
3562
+ var count = _this.s.topGroup.count();
3563
+ _this._updateTitle(count);
3564
+ _this._filterChanged(count);
3565
+ });
3477
3566
  this.s.topGroup.dom.container.unbind('dtsb-redrawLogic');
3478
3567
  this.s.topGroup.dom.container.on('dtsb-redrawLogic.dtsb', function () {
3479
3568
  _this.s.topGroup.redrawLogic();
@@ -3496,11 +3585,6 @@
3496
3585
  _this._filterChanged(0);
3497
3586
  _this.s.dt.draw();
3498
3587
  });
3499
- this.s.topGroup.dom.container.on('dtsb-updateTitle.dtsb', function () {
3500
- var count = _this.s.topGroup.count();
3501
- _this._updateTitle(count);
3502
- _this._filterChanged(count);
3503
- });
3504
3588
  };
3505
3589
  /**
3506
3590
  * Sets listeners to check whether clearAll should be added or removed
@@ -3514,7 +3598,7 @@
3514
3598
  _this.dom.clearAll.remove();
3515
3599
  });
3516
3600
  };
3517
- SearchBuilder.version = '1.3.0';
3601
+ SearchBuilder.version = '1.3.2';
3518
3602
  SearchBuilder.classes = {
3519
3603
  button: 'dtsb-button',
3520
3604
  clearAll: 'dtsb-clearAll',
@@ -3620,7 +3704,7 @@
3620
3704
  return SearchBuilder;
3621
3705
  }());
3622
3706
 
3623
- /*! SearchBuilder 1.3.0
3707
+ /*! SearchBuilder 1.3.2
3624
3708
  * ©SpryMedia Ltd - datatables.net/license/mit
3625
3709
  */
3626
3710
  // DataTables extensions common UMD. Note that this allows for AMD, CommonJS
@@ -3677,14 +3761,16 @@
3677
3761
  $.fn.dataTable.ext.buttons.searchBuilder = {
3678
3762
  action: function (e, dt, node, config) {
3679
3763
  this.popover(config._searchBuilder.getNode(), {
3680
- align: 'dt-container'
3764
+ align: 'container',
3765
+ span: 'container'
3681
3766
  });
3767
+ var topGroup = config._searchBuilder.s.topGroup;
3682
3768
  // Need to redraw the contents to calculate the correct positions for the elements
3683
- if (config._searchBuilder.s.topGroup !== undefined) {
3684
- config._searchBuilder.s.topGroup.dom.container.trigger('dtsb-redrawContents');
3769
+ if (topGroup !== undefined) {
3770
+ topGroup.dom.container.trigger('dtsb-redrawContents-noDraw');
3685
3771
  }
3686
- if (config._searchBuilder.s.topGroup.s.criteria.length === 0) {
3687
- $('.' + $.fn.dataTable.Group.classes.add).click();
3772
+ if (topGroup.s.criteria.length === 0) {
3773
+ $('.' + $.fn.dataTable.Group.classes.add.replace(/ /g, '.')).click();
3688
3774
  }
3689
3775
  },
3690
3776
  config: {},