datatables.net-searchbuilder 1.3.1 → 1.3.4

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.1
1
+ /*! SearchBuilder 1.3.4
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: []
@@ -80,6 +85,8 @@
80
85
  .addClass(this.classes.button)
81
86
  .attr('title', this.s.dt.i18n('searchBuilder.deleteTitle', i18n.deleteTitle))
82
87
  .attr('type', 'button'),
88
+ inputCont: $$2('<div/>')
89
+ .addClass(this.classes.inputCont),
83
90
  // eslint-disable-next-line no-useless-escape
84
91
  left: $$2('<button/>')
85
92
  .html(this.s.dt.i18n('searchBuilder.left', i18n.left))
@@ -114,15 +121,8 @@
114
121
  val.addClass(this.classes.greyscale);
115
122
  }
116
123
  }
117
- // For responsive design, adjust the criterias properties on the following events
118
- this.s.dt.on('draw.dtsb', function () {
119
- _this._adjustCriteria();
120
- });
121
- this.s.dt.on('buttons-action.dtsb', function () {
122
- _this._adjustCriteria();
123
- });
124
124
  $$2(window).on('resize.dtsb', dataTable$2.util.throttle(function () {
125
- _this._adjustCriteria();
125
+ _this.s.topGroup.trigger('dtsb-redrawLogic');
126
126
  }));
127
127
  this._buildCriteria();
128
128
  return this;
@@ -141,25 +141,33 @@
141
141
  .replace(/&gt;/g, '>')
142
142
  .replace(/&quot;/g, '"');
143
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
+ };
144
153
  /**
145
154
  * Adds the left button to the criteria
146
155
  */
147
- Criteria.prototype.updateArrows = function (hasSiblings, redraw) {
156
+ Criteria.prototype.updateArrows = function (hasSiblings) {
148
157
  if (hasSiblings === void 0) { hasSiblings = false; }
149
- if (redraw === void 0) { redraw = true; }
150
158
  // Empty the container and append all of the elements in the correct order
151
159
  this.dom.container.children().detach();
152
160
  this.dom.container
153
161
  .append(this.dom.data)
154
162
  .append(this.dom.condition)
155
- .append(this.dom.value[0]);
163
+ .append(this.dom.inputCont);
156
164
  this.setListeners();
157
165
  // Trigger the inserted events for the value elements as they are inserted
158
166
  if (this.dom.value[0] !== undefined) {
159
167
  this.dom.value[0].trigger('dtsb-inserted');
160
168
  }
161
169
  for (var i = 1; i < this.dom.value.length; i++) {
162
- this.dom.container.append(this.dom.value[i]);
170
+ this.dom.inputCont.append(this.dom.value[i]);
163
171
  this.dom.value[i].trigger('dtsb-inserted');
164
172
  }
165
173
  // If this is a top level criteria then don't let it move left
@@ -175,10 +183,6 @@
175
183
  }
176
184
  this.dom.buttons.append(this.dom["delete"]);
177
185
  this.dom.container.append(this.dom.buttons);
178
- if (redraw) {
179
- // A different combination of arrows and selectors may lead to a need for responsive to be triggered
180
- this._adjustCriteria();
181
- }
182
186
  };
183
187
  /**
184
188
  * Destroys the criteria, removing listeners and container from the dom
@@ -287,12 +291,20 @@
287
291
  }
288
292
  else if (this.s.type.includes('moment')) {
289
293
  for (var i = 0; i < this.s.value.length; i++) {
290
- this.s.value[i] = moment(this.s.value[i], this.s.dateFormat).toISOString();
294
+ if (this.s.value[i] &&
295
+ this.s.value[i].length > 0 &&
296
+ moment()(this.s.value[i], this.s.dateFormat, true).isValid()) {
297
+ this.s.value[i] = moment()(this.s.value[i], this.s.dateFormat).format('YYYY-MM-DD HH:mm:ss');
298
+ }
291
299
  }
292
300
  }
293
301
  else if (this.s.type.includes('luxon')) {
294
302
  for (var i = 0; i < this.s.value.length; i++) {
295
- this.s.value[i] = luxon.DateTime.fromFormat(this.s.value[i], this.s.dateFormat).toISO();
303
+ if (this.s.value[i] &&
304
+ this.s.value[i].length > 0 &&
305
+ luxon().DateTime.fromFormat(this.s.value[i], this.s.dateFormat).invalid === null) {
306
+ this.s.value[i] = luxon().DateTime.fromFormat(this.s.value[i], this.s.dateFormat).toFormat('yyyy-MM-dd HH:mm:ss');
307
+ }
296
308
  }
297
309
  }
298
310
  }
@@ -306,7 +318,7 @@
306
318
  data: this.s.data,
307
319
  origData: this.s.origData,
308
320
  type: this.s.type,
309
- value: this.s.value.map(function (a) { return a.toString(); })
321
+ value: this.s.value.map(function (a) { return a !== null && a !== undefined ? a.toString() : a; })
310
322
  };
311
323
  };
312
324
  /**
@@ -473,7 +485,7 @@
473
485
  var val = _c[_b];
474
486
  // If this criteria was previously active in the search then remove
475
487
  // it from the search and trigger a new search
476
- if (_this.s.filled && val !== undefined && _this.dom.container.has(val[0]).length !== 0) {
488
+ if (_this.s.filled && val !== undefined && _this.dom.inputCont.has(val[0]).length !== 0) {
477
489
  _this.s.filled = false;
478
490
  _this.s.dt.draw();
479
491
  _this.setListeners();
@@ -490,52 +502,16 @@
490
502
  }
491
503
  });
492
504
  };
493
- /**
494
- * Adjusts the criteria to make SearchBuilder responsive
495
- */
496
- Criteria.prototype._adjustCriteria = function () {
497
- // If this criteria is not present then don't bother adjusting it
498
- if ($$2(document).has(this.dom.container).length === 0) {
499
- return;
500
- }
501
- var valRight;
502
- var valWidth;
503
- var outmostval = this.dom.value[this.dom.value.length - 1];
504
- // Calculate the width and right value of the outmost value element
505
- if (outmostval !== undefined && this.dom.container.has(outmostval[0]).length !== 0) {
506
- valWidth = outmostval.outerWidth(true);
507
- valRight = outmostval.offset().left + valWidth;
508
- }
509
- else {
505
+ Criteria.prototype.setupButtons = function () {
506
+ if (window.innerWidth > 550) {
507
+ this.dom.container.removeClass(this.classes.vertical);
508
+ this.dom.buttons.css('left', null);
509
+ this.dom.buttons.css('top', null);
510
510
  return;
511
511
  }
512
- var leftOffset = this.dom.left.offset();
513
- var rightOffset = this.dom.right.offset();
514
- var clearOffset = this.dom["delete"].offset();
515
- var hasLeft = this.dom.container.has(this.dom.left[0]).length !== 0;
516
- var hasRight = this.dom.container.has(this.dom.right[0]).length !== 0;
517
- var buttonsLeft = hasLeft ?
518
- leftOffset.left :
519
- hasRight ?
520
- rightOffset.left :
521
- clearOffset.left;
522
- // Perform the responsive calculations and redraw where necessary
523
- if ((buttonsLeft - valRight < 15 ||
524
- hasLeft && leftOffset.top !== clearOffset.top ||
525
- hasRight && rightOffset.top !== clearOffset.top) &&
526
- !this.dom.container.parent().hasClass(this.classes.vertical)) {
527
- this.dom.container.parent().addClass(this.classes.vertical);
528
- this.s.topGroup.trigger('dtsb-redrawContents');
529
- }
530
- else if (buttonsLeft -
531
- (this.dom.data.offset().left +
532
- this.dom.data.outerWidth(true) +
533
- this.dom.condition.outerWidth(true) +
534
- valWidth) > 15
535
- && this.dom.container.parent().hasClass(this.classes.vertical)) {
536
- this.dom.container.parent().removeClass(this.classes.vertical);
537
- this.s.topGroup.trigger('dtsb-redrawContents');
538
- }
512
+ this.dom.container.addClass(this.classes.vertical);
513
+ this.dom.buttons.css('left', this.dom.data.innerWidth());
514
+ this.dom.buttons.css('top', this.dom.data.position().top);
539
515
  };
540
516
  /**
541
517
  * Builds the elements of the dom together
@@ -548,15 +524,17 @@
548
524
  this.dom.container
549
525
  .append(this.dom.data)
550
526
  .append(this.dom.condition);
527
+ this.dom.inputCont.empty();
551
528
  for (var _i = 0, _a = this.dom.value; _i < _a.length; _i++) {
552
529
  var val = _a[_i];
553
530
  val.append(this.dom.valueTitle);
554
- this.dom.container.append(val);
531
+ this.dom.inputCont.append(val);
555
532
  }
556
533
  // Add buttons to container
557
- this.dom.container
534
+ this.dom.buttons
558
535
  .append(this.dom["delete"])
559
536
  .append(this.dom.right);
537
+ this.dom.container.append(this.dom.inputCont).append(this.dom.buttons);
560
538
  this.setListeners();
561
539
  };
562
540
  /**
@@ -592,10 +570,15 @@
592
570
  // Call the init function to get the value elements for this condition
593
571
  this.dom.value = [].concat(this.s.conditions[this.s.condition].init(this, Criteria.updateListener));
594
572
  if (this.dom.value.length > 0 && this.dom.value[0] !== undefined) {
595
- this.dom.value[0].insertAfter(this.dom.condition).trigger('dtsb-inserted');
573
+ this.dom.inputCont
574
+ .empty()
575
+ .append(this.dom.value[0])
576
+ .insertAfter(this.dom.condition);
577
+ this.dom.value[0].trigger('dtsb-inserted');
596
578
  // Insert all of the value elements
597
579
  for (var i = 1; i < this.dom.value.length; i++) {
598
- this.dom.value[i].insertAfter(this.dom.value[i - 1]).trigger('dtsb-inserted');
580
+ this.dom.inputCont.append(this.dom.value[i]);
581
+ this.dom.value[i].trigger('dtsb-inserted');
599
582
  }
600
583
  }
601
584
  }
@@ -645,11 +628,11 @@
645
628
  Criteria.prototype._populateCondition = function () {
646
629
  var conditionOpts = [];
647
630
  var conditionsLength = Object.keys(this.s.conditions).length;
631
+ var colInits = this.s.dt.settings()[0].aoColumns;
632
+ var column = +this.dom.data.children('option:selected').val();
648
633
  // If there are no conditions stored then we need to get them from the appropriate type
649
634
  if (conditionsLength === 0) {
650
- var column = +this.dom.data.children('option:selected').val();
651
635
  this.s.type = this.s.dt.columns().type().toArray()[column];
652
- var colInits = this.s.dt.settings()[0].aoColumns;
653
636
  if (colInits !== undefined) {
654
637
  var colInit = colInits[column];
655
638
  if (colInit.searchBuilderType !== undefined && colInit.searchBuilderType !== null) {
@@ -704,9 +687,17 @@
704
687
  // Serverside processing does not supply the options for the select elements
705
688
  // Instead input elements need to be used for these instead
706
689
  if (this.s.dt.page.info().serverSide && conditionObj[condition].init === Criteria.initSelect) {
707
- conditionObj[condition].init = Criteria.initInput;
708
- conditionObj[condition].inputValue = Criteria.inputValueInput;
709
- conditionObj[condition].isInputValid = Criteria.isInputValidInput;
690
+ var col = colInits[column];
691
+ if (this.s.serverData && this.s.serverData[col.data]) {
692
+ conditionObj[condition].init = Criteria.initSelectSSP;
693
+ conditionObj[condition].inputValue = Criteria.inputValueSelect;
694
+ conditionObj[condition].isInputValid = Criteria.isInputValidSelect;
695
+ }
696
+ else {
697
+ conditionObj[condition].init = Criteria.initInput;
698
+ conditionObj[condition].inputValue = Criteria.inputValueInput;
699
+ conditionObj[condition].isInputValid = Criteria.isInputValidInput;
700
+ }
710
701
  }
711
702
  this.s.conditions[condition] = conditionObj[condition];
712
703
  var condName = conditionObj[condition].conditionName;
@@ -754,7 +745,44 @@
754
745
  var opt = conditionOpts_1[_d];
755
746
  this.dom.condition.append(opt);
756
747
  }
757
- this.dom.condition.prop('selectedIndex', 0);
748
+ // Selecting a default condition if one is set
749
+ if (colInits[column].searchBuilder && colInits[column].searchBuilder.defaultCondition) {
750
+ var defaultCondition = colInits[column].searchBuilder.defaultCondition;
751
+ // If it is a number just use it as an index
752
+ if (typeof defaultCondition === 'number') {
753
+ this.dom.condition.prop('selectedIndex', defaultCondition);
754
+ this.dom.condition.trigger('change');
755
+ }
756
+ // If it is a string then things get slightly more tricly
757
+ else if (typeof defaultCondition === 'string') {
758
+ // We need to check each condition option to see if any will match
759
+ for (var i = 0; i < conditionOpts.length; i++) {
760
+ // Need to check against the stored conditions so we can match the token "cond" to the option
761
+ for (var _e = 0, _f = Object.keys(this.s.conditions); _e < _f.length; _e++) {
762
+ var cond = _f[_e];
763
+ var condName = this.s.conditions[cond].conditionName;
764
+ if (
765
+ // If the conditionName matches the text of the option
766
+ (typeof condName === 'string' ? condName : condName(this.s.dt, this.c.i18n)) ===
767
+ conditionOpts[i].text() &&
768
+ // and the tokens match
769
+ cond === defaultCondition) {
770
+ // Select that option
771
+ this.dom.condition
772
+ .prop('selectedIndex', this.dom.condition.children().toArray().indexOf(conditionOpts[i][0]))
773
+ .removeClass(this.classes.italic);
774
+ this.dom.condition.trigger('change');
775
+ i = conditionOpts.length;
776
+ break;
777
+ }
778
+ }
779
+ }
780
+ }
781
+ }
782
+ // If not default set then default to 0, the title
783
+ else {
784
+ this.dom.condition.prop('selectedIndex', 0);
785
+ }
758
786
  };
759
787
  /**
760
788
  * Populates the data select element
@@ -861,9 +889,10 @@
861
889
  var val = _a[_i];
862
890
  _loop_4(val);
863
891
  }
864
- var children = this.dom.container.children();
865
- if (children.length > 3) {
866
- for (var i = 2; i < children.length - 1; i++) {
892
+ var children = this.dom.inputCont.children();
893
+ if (children.length > 1) {
894
+ // eslint-disable-next-line @typescript-eslint/prefer-for-of
895
+ for (var i = 0; i < children.length; i++) {
867
896
  $$2(children[i]).remove();
868
897
  }
869
898
  }
@@ -880,10 +909,11 @@
880
909
  if (loadedCriteria !== undefined && loadedCriteria.value !== undefined) {
881
910
  this.s.value = loadedCriteria.value;
882
911
  }
912
+ this.dom.inputCont.empty();
883
913
  // Insert value elements and trigger the inserted event
884
914
  if (this.dom.value[0] !== undefined) {
885
915
  this.dom.value[0]
886
- .insertAfter(this.dom.condition)
916
+ .appendTo(this.dom.inputCont)
887
917
  .trigger('dtsb-inserted');
888
918
  }
889
919
  for (var i = 1; i < this.dom.value.length; i++) {
@@ -895,7 +925,7 @@
895
925
  this.s.filled = this.s.conditions[this.s.condition].isInputValid(this.dom.value, this);
896
926
  this.setListeners();
897
927
  // If it can and this is different to before then trigger a draw
898
- if (prevFilled !== this.s.filled) {
928
+ if (!this.s.preventRedraw && prevFilled !== this.s.filled) {
899
929
  // If using SSP we want to restrict the amount of server calls that take place
900
930
  // and this will already have taken place
901
931
  if (!this.s.dt.page.info().serverSide) {
@@ -948,6 +978,7 @@
948
978
  dropDown: 'dtsb-dropDown',
949
979
  greyscale: 'dtsb-greyscale',
950
980
  input: 'dtsb-input',
981
+ inputCont: 'dtsb-inputCont',
951
982
  italic: 'dtsb-italic',
952
983
  joiner: 'dtsp-joiner',
953
984
  left: 'dtsb-left',
@@ -1093,6 +1124,64 @@
1093
1124
  }
1094
1125
  return el;
1095
1126
  };
1127
+ /**
1128
+ * Default initialisation function for select conditions
1129
+ */
1130
+ Criteria.initSelectSSP = function (that, fn, preDefined) {
1131
+ if (preDefined === void 0) { preDefined = null; }
1132
+ that.dom.valueTitle.prop('selected', true);
1133
+ // Declare select element to be used with all of the default classes and listeners.
1134
+ var el = $$2('<select/>')
1135
+ .addClass(Criteria.classes.value)
1136
+ .addClass(Criteria.classes.dropDown)
1137
+ .addClass(Criteria.classes.italic)
1138
+ .addClass(Criteria.classes.select)
1139
+ .append(that.dom.valueTitle)
1140
+ .on('change.dtsb', function () {
1141
+ $$2(this).removeClass(Criteria.classes.italic);
1142
+ fn(that, this);
1143
+ });
1144
+ if (that.c.greyscale) {
1145
+ el.addClass(Criteria.classes.greyscale);
1146
+ }
1147
+ var options = [];
1148
+ for (var _i = 0, _a = that.s.serverData[that.s.origData]; _i < _a.length; _i++) {
1149
+ var option = _a[_i];
1150
+ var value = option.value;
1151
+ var label = option.label;
1152
+ // Function to add an option to the select element
1153
+ var addOption = function (filt, text) {
1154
+ if (that.s.type.includes('html') && filt !== null && typeof filt === 'string') {
1155
+ filt.replace(/(<([^>]+)>)/ig, '');
1156
+ }
1157
+ // Add text and value, stripping out any html if that is the column type
1158
+ var opt = $$2('<option>', {
1159
+ type: Array.isArray(filt) ? 'Array' : 'String',
1160
+ value: filt
1161
+ })
1162
+ .data('sbv', filt)
1163
+ .addClass(that.classes.option)
1164
+ .addClass(that.classes.notItalic)
1165
+ // Have to add the text this way so that special html characters are not escaped - &amp; etc.
1166
+ .html(typeof text === 'string' ?
1167
+ text.replace(/(<([^>]+)>)/ig, '') :
1168
+ text);
1169
+ options.push(opt);
1170
+ // If this value was previously selected as indicated by preDefined, then select it again
1171
+ if (preDefined !== null && opt.val() === preDefined[0]) {
1172
+ opt.prop('selected', true);
1173
+ el.removeClass(Criteria.classes.italic);
1174
+ that.dom.valueTitle.removeProp('selected');
1175
+ }
1176
+ };
1177
+ addOption(value, label);
1178
+ }
1179
+ for (var _b = 0, options_2 = options; _b < options_2.length; _b++) {
1180
+ var opt = options_2[_b];
1181
+ el.append(opt);
1182
+ }
1183
+ return el;
1184
+ };
1096
1185
  /**
1097
1186
  * Default initialisation function for select array conditions
1098
1187
  *
@@ -1114,12 +1203,7 @@
1114
1203
  .addClass(Criteria.classes.input)
1115
1204
  .on('input.dtsb keypress.dtsb', that._throttle(function (e) {
1116
1205
  var code = e.keyCode || e.which;
1117
- if (!that.c.enterSearch &&
1118
- !(that.s.dt.settings()[0].oInit.search !== undefined &&
1119
- that.s.dt.settings()[0].oInit.search["return"]) ||
1120
- code === 13) {
1121
- return fn(that, this);
1122
- }
1206
+ return fn(that, this, code);
1123
1207
  }, searchDelay === null ? 100 : searchDelay));
1124
1208
  if (that.c.greyscale) {
1125
1209
  el.addClass(Criteria.classes.greyscale);
@@ -1147,12 +1231,7 @@
1147
1231
  .addClass(Criteria.classes.input)
1148
1232
  .on('input.dtsb keypress.dtsb', that._throttle(function (e) {
1149
1233
  var code = e.keyCode || e.which;
1150
- if (!that.c.enterSearch &&
1151
- !(that.s.dt.settings()[0].oInit.search !== undefined &&
1152
- that.s.dt.settings()[0].oInit.search["return"]) ||
1153
- code === 13) {
1154
- return fn(that, this);
1155
- }
1234
+ return fn(that, this, code);
1156
1235
  }, searchDelay === null ? 100 : searchDelay)),
1157
1236
  $$2('<span>')
1158
1237
  .addClass(that.classes.joiner)
@@ -1162,12 +1241,7 @@
1162
1241
  .addClass(Criteria.classes.input)
1163
1242
  .on('input.dtsb keypress.dtsb', that._throttle(function (e) {
1164
1243
  var code = e.keyCode || e.which;
1165
- if (!that.c.enterSearch &&
1166
- !(that.s.dt.settings()[0].oInit.search !== undefined &&
1167
- that.s.dt.settings()[0].oInit.search["return"]) ||
1168
- code === 13) {
1169
- return fn(that, this);
1170
- }
1244
+ return fn(that, this, code);
1171
1245
  }, searchDelay === null ? 100 : searchDelay))
1172
1246
  ];
1173
1247
  if (that.c.greyscale) {
@@ -1202,20 +1276,12 @@
1202
1276
  .on('change.dtsb', that._throttle(function () {
1203
1277
  return fn(that, this);
1204
1278
  }, searchDelay === null ? 100 : searchDelay))
1205
- .on('input.dtsb keypress.dtsb', that.c.enterSearch ||
1206
- that.s.dt.settings()[0].oInit.search !== undefined &&
1207
- that.s.dt.settings()[0].oInit.search["return"] ?
1208
- function (e) {
1209
- that._throttle(function () {
1210
- var code = e.keyCode || e.which;
1211
- if (code === 13) {
1212
- return fn(that, this);
1213
- }
1214
- }, searchDelay === null ? 100 : searchDelay);
1215
- } :
1279
+ .on('input.dtsb keypress.dtsb', function (e) {
1216
1280
  that._throttle(function () {
1217
- return fn(that, this);
1218
- }, searchDelay === null ? 100 : searchDelay));
1281
+ var code = e.keyCode || e.which;
1282
+ return fn(that, this, code);
1283
+ }, searchDelay === null ? 100 : searchDelay);
1284
+ });
1219
1285
  if (that.c.greyscale) {
1220
1286
  el.addClass(Criteria.classes.greyscale);
1221
1287
  }
@@ -1255,25 +1321,12 @@
1255
1321
  function () {
1256
1322
  fn(that, _this);
1257
1323
  })
1258
- .on('input.dtsb keypress.dtsb', !that.c.enterSearch &&
1259
- !(that.s.dt.settings()[0].oInit.search !== undefined &&
1260
- that.s.dt.settings()[0].oInit.search["return"]) &&
1261
- searchDelay !== null ?
1324
+ .on('input.dtsb keypress.dtsb', function (e) {
1262
1325
  that.s.dt.settings()[0].oApi._fnThrottle(function () {
1263
- return fn(that, this);
1264
- }, searchDelay) :
1265
- that.c.enterSearch ||
1266
- that.s.dt.settings()[0].oInit.search !== undefined &&
1267
- that.s.dt.settings()[0].oInit.search["return"] ?
1268
- function (e) {
1269
- var code = e.keyCode || e.which;
1270
- if (code === 13) {
1271
- fn(that, _this);
1272
- }
1273
- } :
1274
- function () {
1275
- fn(that, _this);
1276
- }),
1326
+ var code = e.keyCode || e.which;
1327
+ return fn(that, this, code);
1328
+ }, searchDelay === null ? 0 : searchDelay);
1329
+ }),
1277
1330
  $$2('<span>')
1278
1331
  .addClass(that.classes.joiner)
1279
1332
  .html(that.s.dt.i18n('searchBuilder.valueJoiner', that.c.i18n.valueJoiner)),
@@ -1298,18 +1351,10 @@
1298
1351
  that.s.dt.settings()[0].oApi._fnThrottle(function () {
1299
1352
  return fn(that, this);
1300
1353
  }, searchDelay) :
1301
- that.c.enterSearch ||
1302
- that.s.dt.settings()[0].oInit.search !== undefined &&
1303
- that.s.dt.settings()[0].oInit.search["return"] ?
1304
- function (e) {
1305
- var code = e.keyCode || e.which;
1306
- if (code === 13) {
1307
- fn(that, _this);
1308
- }
1309
- } :
1310
- function () {
1311
- fn(that, _this);
1312
- })
1354
+ function (e) {
1355
+ var code = e.keyCode || e.which;
1356
+ fn(that, _this, code);
1357
+ })
1313
1358
  ];
1314
1359
  if (that.c.greyscale) {
1315
1360
  els[0].addClass(Criteria.classes.greyscale);
@@ -1389,14 +1434,19 @@
1389
1434
  /**
1390
1435
  * Function that is run on each element as a call back when a search should be triggered
1391
1436
  */
1392
- Criteria.updateListener = function (that, el) {
1437
+ Criteria.updateListener = function (that, el, code) {
1393
1438
  // When the value is changed the criteria is now complete so can be included in searches
1394
1439
  // Get the condition from the map based on the key that has been selected for the condition
1395
1440
  var condition = that.s.conditions[that.s.condition];
1396
1441
  that.s.filled = condition.isInputValid(that.dom.value, that);
1397
1442
  that.s.value = condition.inputValue(that.dom.value, that);
1398
1443
  if (!that.s.filled) {
1399
- that.s.dt.draw();
1444
+ if (!that.c.enterSearch &&
1445
+ !(that.s.dt.settings()[0].oInit.search !== undefined &&
1446
+ that.s.dt.settings()[0].oInit.search["return"]) ||
1447
+ code === 13) {
1448
+ that.s.dt.draw();
1449
+ }
1400
1450
  return;
1401
1451
  }
1402
1452
  if (!Array.isArray(that.s.value)) {
@@ -1434,8 +1484,13 @@
1434
1484
  }
1435
1485
  }
1436
1486
  }
1437
- // Trigger a search
1438
- that.s.dt.draw();
1487
+ if (!that.c.enterSearch &&
1488
+ !(that.s.dt.settings()[0].oInit.search !== undefined &&
1489
+ that.s.dt.settings()[0].oInit.search["return"]) ||
1490
+ code === 13) {
1491
+ // Trigger a search
1492
+ that.s.dt.draw();
1493
+ }
1439
1494
  // Refocus the element and set the correct cursor position
1440
1495
  if (idx !== null) {
1441
1496
  that.dom.value[idx].removeClass(that.classes.italic);
@@ -1579,8 +1634,8 @@
1579
1634
  inputValue: Criteria.inputValueInput,
1580
1635
  isInputValid: Criteria.isInputValidInput,
1581
1636
  search: function (value, comparison, that) {
1582
- return moment(value, that.s.dateFormat).valueOf() ===
1583
- moment(comparison[0], that.s.dateFormat).valueOf();
1637
+ return moment()(value, that.s.dateFormat).valueOf() ===
1638
+ moment()(comparison[0], that.s.dateFormat).valueOf();
1584
1639
  }
1585
1640
  },
1586
1641
  // eslint-disable-next-line sort-keys
@@ -1592,8 +1647,8 @@
1592
1647
  inputValue: Criteria.inputValueInput,
1593
1648
  isInputValid: Criteria.isInputValidInput,
1594
1649
  search: function (value, comparison, that) {
1595
- return moment(value, that.s.dateFormat).valueOf() !==
1596
- moment(comparison[0], that.s.dateFormat).valueOf();
1650
+ return moment()(value, that.s.dateFormat).valueOf() !==
1651
+ moment()(comparison[0], that.s.dateFormat).valueOf();
1597
1652
  }
1598
1653
  },
1599
1654
  '<': {
@@ -1604,7 +1659,7 @@
1604
1659
  inputValue: Criteria.inputValueInput,
1605
1660
  isInputValid: Criteria.isInputValidInput,
1606
1661
  search: function (value, comparison, that) {
1607
- return moment(value, that.s.dateFormat).valueOf() < moment(comparison[0], that.s.dateFormat).valueOf();
1662
+ return moment()(value, that.s.dateFormat).valueOf() < moment()(comparison[0], that.s.dateFormat).valueOf();
1608
1663
  }
1609
1664
  },
1610
1665
  '>': {
@@ -1615,7 +1670,7 @@
1615
1670
  inputValue: Criteria.inputValueInput,
1616
1671
  isInputValid: Criteria.isInputValidInput,
1617
1672
  search: function (value, comparison, that) {
1618
- return moment(value, that.s.dateFormat).valueOf() > moment(comparison[0], that.s.dateFormat).valueOf();
1673
+ return moment()(value, that.s.dateFormat).valueOf() > moment()(comparison[0], that.s.dateFormat).valueOf();
1619
1674
  }
1620
1675
  },
1621
1676
  'between': {
@@ -1626,9 +1681,9 @@
1626
1681
  inputValue: Criteria.inputValueInput,
1627
1682
  isInputValid: Criteria.isInputValidInput,
1628
1683
  search: function (value, comparison, that) {
1629
- var val = moment(value, that.s.dateFormat).valueOf();
1630
- var comp0 = moment(comparison[0], that.s.dateFormat).valueOf();
1631
- var comp1 = moment(comparison[1], that.s.dateFormat).valueOf();
1684
+ var val = moment()(value, that.s.dateFormat).valueOf();
1685
+ var comp0 = moment()(comparison[0], that.s.dateFormat).valueOf();
1686
+ var comp1 = moment()(comparison[1], that.s.dateFormat).valueOf();
1632
1687
  if (comp0 < comp1) {
1633
1688
  return comp0 <= val && val <= comp1;
1634
1689
  }
@@ -1646,9 +1701,9 @@
1646
1701
  inputValue: Criteria.inputValueInput,
1647
1702
  isInputValid: Criteria.isInputValidInput,
1648
1703
  search: function (value, comparison, that) {
1649
- var val = moment(value, that.s.dateFormat).valueOf();
1650
- var comp0 = moment(comparison[0], that.s.dateFormat).valueOf();
1651
- var comp1 = moment(comparison[1], that.s.dateFormat).valueOf();
1704
+ var val = moment()(value, that.s.dateFormat).valueOf();
1705
+ var comp0 = moment()(comparison[0], that.s.dateFormat).valueOf();
1706
+ var comp1 = moment()(comparison[1], that.s.dateFormat).valueOf();
1652
1707
  if (comp0 < comp1) {
1653
1708
  return !(+comp0 <= +val && +val <= +comp1);
1654
1709
  }
@@ -1702,8 +1757,8 @@
1702
1757
  inputValue: Criteria.inputValueInput,
1703
1758
  isInputValid: Criteria.isInputValidInput,
1704
1759
  search: function (value, comparison, that) {
1705
- return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts
1706
- === luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1760
+ return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
1761
+ === luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1707
1762
  }
1708
1763
  },
1709
1764
  // eslint-disable-next-line sort-keys
@@ -1715,8 +1770,8 @@
1715
1770
  inputValue: Criteria.inputValueInput,
1716
1771
  isInputValid: Criteria.isInputValidInput,
1717
1772
  search: function (value, comparison, that) {
1718
- return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts
1719
- !== luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1773
+ return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
1774
+ !== luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1720
1775
  }
1721
1776
  },
1722
1777
  '<': {
@@ -1727,8 +1782,8 @@
1727
1782
  inputValue: Criteria.inputValueInput,
1728
1783
  isInputValid: Criteria.isInputValidInput,
1729
1784
  search: function (value, comparison, that) {
1730
- return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts
1731
- < luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1785
+ return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
1786
+ < luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1732
1787
  }
1733
1788
  },
1734
1789
  '>': {
@@ -1739,8 +1794,8 @@
1739
1794
  inputValue: Criteria.inputValueInput,
1740
1795
  isInputValid: Criteria.isInputValidInput,
1741
1796
  search: function (value, comparison, that) {
1742
- return luxon.DateTime.fromFormat(value, that.s.dateFormat).ts
1743
- > luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1797
+ return luxon().DateTime.fromFormat(value, that.s.dateFormat).ts
1798
+ > luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1744
1799
  }
1745
1800
  },
1746
1801
  'between': {
@@ -1751,9 +1806,9 @@
1751
1806
  inputValue: Criteria.inputValueInput,
1752
1807
  isInputValid: Criteria.isInputValidInput,
1753
1808
  search: function (value, comparison, that) {
1754
- var val = luxon.DateTime.fromFormat(value, that.s.dateFormat).ts;
1755
- var comp0 = luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1756
- var comp1 = luxon.DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;
1809
+ var val = luxon().DateTime.fromFormat(value, that.s.dateFormat).ts;
1810
+ var comp0 = luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1811
+ var comp1 = luxon().DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;
1757
1812
  if (comp0 < comp1) {
1758
1813
  return comp0 <= val && val <= comp1;
1759
1814
  }
@@ -1771,9 +1826,9 @@
1771
1826
  inputValue: Criteria.inputValueInput,
1772
1827
  isInputValid: Criteria.isInputValidInput,
1773
1828
  search: function (value, comparison, that) {
1774
- var val = luxon.DateTime.fromFormat(value, that.s.dateFormat).ts;
1775
- var comp0 = luxon.DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1776
- var comp1 = luxon.DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;
1829
+ var val = luxon().DateTime.fromFormat(value, that.s.dateFormat).ts;
1830
+ var comp0 = luxon().DateTime.fromFormat(comparison[0], that.s.dateFormat).ts;
1831
+ var comp1 = luxon().DateTime.fromFormat(comparison[1], that.s.dateFormat).ts;
1777
1832
  if (comp0 < comp1) {
1778
1833
  return !(+comp0 <= +val && +val <= +comp1);
1779
1834
  }
@@ -1965,13 +2020,7 @@
1965
2020
  inputValue: Criteria.inputValueSelect,
1966
2021
  isInputValid: Criteria.isInputValidSelect,
1967
2022
  search: function (value, comparison) {
1968
- var val = value.indexOf('-') === 0 ?
1969
- '-' + value.replace(/[^0-9.]/g, '') :
1970
- value.replace(/[^0-9.]/g, '');
1971
- var comp = comparison[0].indexOf('-') === 0 ?
1972
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
1973
- comparison[0].replace(/[^0-9.]/g, '');
1974
- return +val === +comp;
2023
+ return Criteria.parseNumFmt(value) === Criteria.parseNumFmt(comparison[0]);
1975
2024
  }
1976
2025
  },
1977
2026
  // eslint-disable-next-line sort-keys
@@ -1983,13 +2032,7 @@
1983
2032
  inputValue: Criteria.inputValueSelect,
1984
2033
  isInputValid: Criteria.isInputValidSelect,
1985
2034
  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;
2035
+ return Criteria.parseNumFmt(value) !== Criteria.parseNumFmt(comparison[0]);
1993
2036
  }
1994
2037
  },
1995
2038
  '<': {
@@ -2000,13 +2043,7 @@
2000
2043
  inputValue: Criteria.inputValueInput,
2001
2044
  isInputValid: Criteria.isInputValidInput,
2002
2045
  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;
2046
+ return Criteria.parseNumFmt(value) < Criteria.parseNumFmt(comparison[0]);
2010
2047
  }
2011
2048
  },
2012
2049
  '<=': {
@@ -2017,13 +2054,7 @@
2017
2054
  inputValue: Criteria.inputValueInput,
2018
2055
  isInputValid: Criteria.isInputValidInput,
2019
2056
  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;
2057
+ return Criteria.parseNumFmt(value) <= Criteria.parseNumFmt(comparison[0]);
2027
2058
  }
2028
2059
  },
2029
2060
  '>=': {
@@ -2034,13 +2065,7 @@
2034
2065
  inputValue: Criteria.inputValueInput,
2035
2066
  isInputValid: Criteria.isInputValidInput,
2036
2067
  search: function (value, comparison) {
2037
- var val = value.indexOf('-') === 0 ?
2038
- '-' + value.replace(/[^0-9.]/g, '') :
2039
- value.replace(/[^0-9.]/g, '');
2040
- var comp = comparison[0].indexOf('-') === 0 ?
2041
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
2042
- comparison[0].replace(/[^0-9.]/g, '');
2043
- return +val >= +comp;
2068
+ return Criteria.parseNumFmt(value) >= Criteria.parseNumFmt(comparison[0]);
2044
2069
  }
2045
2070
  },
2046
2071
  // eslint-disable-next-line sort-keys
@@ -2052,13 +2077,7 @@
2052
2077
  inputValue: Criteria.inputValueInput,
2053
2078
  isInputValid: Criteria.isInputValidInput,
2054
2079
  search: function (value, comparison) {
2055
- var val = value.indexOf('-') === 0 ?
2056
- '-' + value.replace(/[^0-9.]/g, '') :
2057
- value.replace(/[^0-9.]/g, '');
2058
- var comp = comparison[0].indexOf('-') === 0 ?
2059
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
2060
- comparison[0].replace(/[^0-9.]/g, '');
2061
- return +val > +comp;
2080
+ return Criteria.parseNumFmt(value) > Criteria.parseNumFmt(comparison[0]);
2062
2081
  }
2063
2082
  },
2064
2083
  'between': {
@@ -2069,15 +2088,9 @@
2069
2088
  inputValue: Criteria.inputValueInput,
2070
2089
  isInputValid: Criteria.isInputValidInput,
2071
2090
  search: function (value, comparison) {
2072
- var val = value.indexOf('-') === 0 ?
2073
- '-' + value.replace(/[^0-9.]/g, '') :
2074
- value.replace(/[^0-9.]/g, '');
2075
- var comp0 = comparison[0].indexOf('-') === 0 ?
2076
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
2077
- comparison[0].replace(/[^0-9.]/g, '');
2078
- var comp1 = comparison[1].indexOf('-') === 0 ?
2079
- '-' + comparison[1].replace(/[^0-9.]/g, '') :
2080
- comparison[1].replace(/[^0-9.]/g, '');
2091
+ var val = Criteria.parseNumFmt(value);
2092
+ var comp0 = Criteria.parseNumFmt(comparison[0]);
2093
+ var comp1 = Criteria.parseNumFmt(comparison[1]);
2081
2094
  if (+comp0 < +comp1) {
2082
2095
  return +comp0 <= +val && +val <= +comp1;
2083
2096
  }
@@ -2095,15 +2108,9 @@
2095
2108
  inputValue: Criteria.inputValueInput,
2096
2109
  isInputValid: Criteria.isInputValidInput,
2097
2110
  search: function (value, comparison) {
2098
- var val = value.indexOf('-') === 0 ?
2099
- '-' + value.replace(/[^0-9.]/g, '') :
2100
- value.replace(/[^0-9.]/g, '');
2101
- var comp0 = comparison[0].indexOf('-') === 0 ?
2102
- '-' + comparison[0].replace(/[^0-9.]/g, '') :
2103
- comparison[0].replace(/[^0-9.]/g, '');
2104
- var comp1 = comparison[1].indexOf('-') === 0 ?
2105
- '-' + comparison[1].replace(/[^0-9.]/g, '') :
2106
- comparison[1].replace(/[^0-9.]/g, '');
2111
+ var val = Criteria.parseNumFmt(value);
2112
+ var comp0 = Criteria.parseNumFmt(comparison[0]);
2113
+ var comp1 = Criteria.parseNumFmt(comparison[1]);
2107
2114
  if (+comp0 < +comp1) {
2108
2115
  return !(+comp0 <= +val && +val <= +comp1);
2109
2116
  }
@@ -2442,10 +2449,11 @@
2442
2449
  * The Group class is used within SearchBuilder to represent a group of criteria
2443
2450
  */
2444
2451
  var Group = /** @class */ (function () {
2445
- function Group(table, opts, topGroup, index, isChild, depth) {
2452
+ function Group(table, opts, topGroup, index, isChild, depth, serverData) {
2446
2453
  if (index === void 0) { index = 0; }
2447
2454
  if (isChild === void 0) { isChild = false; }
2448
2455
  if (depth === void 0) { depth = 1; }
2456
+ if (serverData === void 0) { serverData = undefined; }
2449
2457
  // Check that the required version of DataTables is included
2450
2458
  if (!dataTable$1 || !dataTable$1.versionCheck || !dataTable$1.versionCheck('1.10.0')) {
2451
2459
  throw new Error('SearchBuilder requires DataTables 1.10 or newer');
@@ -2462,6 +2470,7 @@
2462
2470
  logic: undefined,
2463
2471
  opts: opts,
2464
2472
  preventRedraw: false,
2473
+ serverData: serverData,
2465
2474
  toDrop: undefined,
2466
2475
  topGroup: topGroup
2467
2476
  };
@@ -2564,7 +2573,7 @@
2564
2573
  for (var _b = 0, _c = this.s.criteria; _b < _c.length; _b++) {
2565
2574
  var crit = _c[_b];
2566
2575
  if (crit.criteria instanceof Criteria) {
2567
- crit.criteria.updateArrows(this.s.criteria.length > 1, false);
2576
+ crit.criteria.updateArrows(this.s.criteria.length > 1);
2568
2577
  this._setCriteriaListeners(crit.criteria);
2569
2578
  }
2570
2579
  }
@@ -2602,7 +2611,9 @@
2602
2611
  this.s.criteria[i].criteria.dom.container.insertBefore(this.dom.add);
2603
2612
  // Set listeners for various points
2604
2613
  this._setCriteriaListeners(crit);
2614
+ this.s.criteria[i].criteria.s.preventRedraw = this.s.preventRedraw;
2605
2615
  this.s.criteria[i].criteria.rebuild(this.s.criteria[i].criteria.getDetails());
2616
+ this.s.criteria[i].criteria.s.preventRedraw = false;
2606
2617
  }
2607
2618
  else if (crit instanceof Group && crit.s.criteria.length > 0) {
2608
2619
  // Reset the index to the new value
@@ -2611,7 +2622,9 @@
2611
2622
  // Add the sub group to the group
2612
2623
  this.s.criteria[i].criteria.dom.container.insertBefore(this.dom.add);
2613
2624
  // Redraw the contents of the group
2625
+ crit.s.preventRedraw = this.s.preventRedraw;
2614
2626
  crit.redrawContents();
2627
+ crit.s.preventRedraw = false;
2615
2628
  this._setGroupListeners(crit);
2616
2629
  }
2617
2630
  else {
@@ -2628,8 +2641,8 @@
2628
2641
  Group.prototype.redrawLogic = function () {
2629
2642
  for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
2630
2643
  var crit = _a[_i];
2631
- if (crit instanceof Group) {
2632
- crit.redrawLogic();
2644
+ if (crit.criteria instanceof Group) {
2645
+ crit.criteria.redrawLogic();
2633
2646
  }
2634
2647
  }
2635
2648
  this.setupLogic();
@@ -2665,12 +2678,19 @@
2665
2678
  }
2666
2679
  return;
2667
2680
  }
2668
- // Set width, take 2 for the border
2669
- var height = this.dom.container.height() - 1;
2670
2681
  this.dom.clear.height('0px');
2671
- this.dom.logicContainer.append(this.dom.clear).width(height);
2682
+ this.dom.logicContainer.append(this.dom.clear);
2672
2683
  // Prepend logic button
2673
2684
  this.dom.container.prepend(this.dom.logicContainer);
2685
+ for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
2686
+ var crit = _a[_i];
2687
+ if (crit.criteria instanceof Criteria) {
2688
+ crit.criteria.setupButtons();
2689
+ }
2690
+ }
2691
+ // Set width, take 2 for the border
2692
+ var height = this.dom.container.outerHeight() - 1;
2693
+ this.dom.logicContainer.width(height);
2674
2694
  this._setLogicListener();
2675
2695
  // Set criteria left margin
2676
2696
  this.dom.container.css('margin-left', this.dom.logicContainer.outerHeight(true));
@@ -2719,11 +2739,10 @@
2719
2739
  *
2720
2740
  * @param crit Instance of Criteria to be added to the group
2721
2741
  */
2722
- Group.prototype.addCriteria = function (crit, redraw) {
2742
+ Group.prototype.addCriteria = function (crit) {
2723
2743
  if (crit === void 0) { crit = null; }
2724
- if (redraw === void 0) { redraw = true; }
2725
2744
  var index = crit === null ? this.s.criteria.length : crit.s.index;
2726
- var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, index, this.s.depth);
2745
+ var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, index, this.s.depth, this.s.serverData);
2727
2746
  // If a Criteria has been passed in then set the values to continue that
2728
2747
  if (crit !== null) {
2729
2748
  criteria.c = crit.c;
@@ -2759,7 +2778,7 @@
2759
2778
  for (var _i = 0, _a = this.s.criteria; _i < _a.length; _i++) {
2760
2779
  var opt = _a[_i];
2761
2780
  if (opt.criteria instanceof Criteria) {
2762
- opt.criteria.updateArrows(this.s.criteria.length > 1, redraw);
2781
+ opt.criteria.updateArrows(this.s.criteria.length > 1);
2763
2782
  }
2764
2783
  }
2765
2784
  this._setCriteriaListeners(criteria);
@@ -2802,7 +2821,7 @@
2802
2821
  */
2803
2822
  Group.prototype._addPrevGroup = function (loadedGroup) {
2804
2823
  var idx = this.s.criteria.length;
2805
- var group = new Group(this.s.dt, this.c, this.s.topGroup, idx, true, this.s.depth + 1);
2824
+ var group = new Group(this.s.dt, this.c, this.s.topGroup, idx, true, this.s.depth + 1, this.s.serverData);
2806
2825
  // Add the new group to the criteria array
2807
2826
  this.s.criteria.push({
2808
2827
  criteria: group,
@@ -2822,7 +2841,7 @@
2822
2841
  */
2823
2842
  Group.prototype._addPrevCriteria = function (loadedCriteria) {
2824
2843
  var idx = this.s.criteria.length;
2825
- var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, idx, this.s.depth);
2844
+ var criteria = new Criteria(this.s.dt, this.s.opts, this.s.topGroup, idx, this.s.depth, this.s.serverData);
2826
2845
  criteria.populate();
2827
2846
  // Add the new criteria to the criteria array
2828
2847
  this.s.criteria.push({
@@ -2830,9 +2849,13 @@
2830
2849
  index: idx
2831
2850
  });
2832
2851
  // Rebuild it with the previous conditions for that criteria
2852
+ criteria.s.preventRedraw = this.s.preventRedraw;
2833
2853
  criteria.rebuild(loadedCriteria);
2854
+ criteria.s.preventRedraw = false;
2834
2855
  this.s.criteria[idx].criteria = criteria;
2835
- this.s.topGroup.trigger('dtsb-redrawContents');
2856
+ if (!this.s.preventRedraw) {
2857
+ this.s.topGroup.trigger('dtsb-redrawContents');
2858
+ }
2836
2859
  };
2837
2860
  /**
2838
2861
  * Checks And the criteria using AND logic
@@ -2950,7 +2973,7 @@
2950
2973
  .unbind('click')
2951
2974
  .on('click.dtsb', function () {
2952
2975
  var idx = criteria.s.index;
2953
- var group = new Group(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index, true, _this.s.depth + 1);
2976
+ var group = new Group(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index, true, _this.s.depth + 1, _this.s.serverData);
2954
2977
  // Add the criteria that is to be moved to the new group
2955
2978
  group.addCriteria(criteria);
2956
2979
  // Update the details in the current groups criteria array
@@ -2963,7 +2986,7 @@
2963
2986
  criteria.dom.left
2964
2987
  .unbind('click')
2965
2988
  .on('click.dtsb', function () {
2966
- _this.s.toDrop = new Criteria(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index);
2989
+ _this.s.toDrop = new Criteria(_this.s.dt, _this.s.opts, _this.s.topGroup, criteria.s.index, undefined, _this.s.serverData);
2967
2990
  _this.s.toDrop.s = criteria.s;
2968
2991
  _this.s.toDrop.c = criteria.c;
2969
2992
  _this.s.toDrop.classes = criteria.classes;
@@ -3032,8 +3055,8 @@
3032
3055
  .on('dtsb-dropCriteria.dtsb', function () {
3033
3056
  var toDrop = group.s.toDrop;
3034
3057
  toDrop.s.index = group.s.index;
3035
- toDrop.updateArrows(_this.s.criteria.length > 1, false);
3036
- _this.addCriteria(toDrop, false);
3058
+ toDrop.updateArrows(_this.s.criteria.length > 1);
3059
+ _this.addCriteria(toDrop);
3037
3060
  return false;
3038
3061
  });
3039
3062
  group.setListeners();
@@ -3193,6 +3216,7 @@
3193
3216
  dt: table,
3194
3217
  opts: opts,
3195
3218
  search: undefined,
3219
+ serverData: undefined,
3196
3220
  topGroup: undefined
3197
3221
  };
3198
3222
  // If searchbuilder is already defined for this table then return
@@ -3208,6 +3232,11 @@
3208
3232
  data.searchBuilder = _this._collapseArray(loadedState.searchBuilder);
3209
3233
  }
3210
3234
  });
3235
+ this.s.dt.on('xhr.dtsb', function (e, settings, json) {
3236
+ if (json && json.searchBuilder && json.searchBuilder.options) {
3237
+ _this.s.serverData = json.searchBuilder.options;
3238
+ }
3239
+ });
3211
3240
  }
3212
3241
  // Run the remaining setup when the table is initialised
3213
3242
  if (this.s.dt.settings()[0]._bInitComplete) {
@@ -3251,6 +3280,8 @@
3251
3280
  this.s.topGroup.s.preventRedraw = true;
3252
3281
  this.s.topGroup.rebuild(details);
3253
3282
  this.s.topGroup.s.preventRedraw = false;
3283
+ this._checkClear();
3284
+ this._updateTitle(this.s.topGroup.count());
3254
3285
  this.s.topGroup.redrawContents();
3255
3286
  this.s.dt.draw(false);
3256
3287
  this.s.topGroup.setListeners();
@@ -3332,11 +3363,16 @@
3332
3363
  }
3333
3364
  }
3334
3365
  }
3335
- this.s.topGroup = new Group(this.s.dt, this.c, undefined);
3366
+ this.s.topGroup = new Group(this.s.dt, this.c, undefined, undefined, undefined, undefined, this.s.serverData);
3336
3367
  this._setClearListener();
3337
3368
  this.s.dt.on('stateSaveParams.dtsb', function (e, settings, data) {
3338
3369
  data.searchBuilder = _this.getDetails();
3339
- data.page = _this.s.dt.page();
3370
+ if (!data.scroller) {
3371
+ data.page = _this.s.dt.page();
3372
+ }
3373
+ else {
3374
+ data.start = _this.s.dt.state().start;
3375
+ }
3340
3376
  });
3341
3377
  this.s.dt.on('stateLoadParams.dtsb', function (e, settings, data) {
3342
3378
  _this.rebuild(data.searchBuilder);
@@ -3359,7 +3395,12 @@
3359
3395
  // If using SSP we want to restrict the amount of server calls that take place
3360
3396
  // and this information will already have been processed
3361
3397
  if (!this.s.dt.page.info().serverSide) {
3362
- this.s.dt.page(loadedState.page).draw('page');
3398
+ if (loadedState.page) {
3399
+ this.s.dt.page(loadedState.page).draw('page');
3400
+ }
3401
+ else if (this.s.dt.scroller && loadedState.scroller) {
3402
+ this.s.dt.scroller().scrollToRow(loadedState.scroller.topRow);
3403
+ }
3363
3404
  }
3364
3405
  this.s.topGroup.setListeners();
3365
3406
  }
@@ -3478,7 +3519,7 @@
3478
3519
  var _this = this;
3479
3520
  this.dom.clearAll.unbind('click');
3480
3521
  this.dom.clearAll.on('click.dtsb', function () {
3481
- _this.s.topGroup = new Group(_this.s.dt, _this.c, undefined);
3522
+ _this.s.topGroup = new Group(_this.s.dt, _this.c, undefined, undefined, undefined, undefined, _this.s.serverData);
3482
3523
  _this._build();
3483
3524
  _this.s.dt.draw();
3484
3525
  _this.s.topGroup.setListeners();
@@ -3509,6 +3550,18 @@
3509
3550
  }
3510
3551
  _this.s.dt.state.save();
3511
3552
  });
3553
+ this.s.topGroup.dom.container.unbind('dtsb-redrawContents-noDraw');
3554
+ this.s.topGroup.dom.container.on('dtsb-redrawContents-noDraw.dtsb', function () {
3555
+ _this._checkClear();
3556
+ _this.s.topGroup.s.preventRedraw = true;
3557
+ _this.s.topGroup.redrawContents();
3558
+ _this.s.topGroup.s.preventRedraw = false;
3559
+ _this.s.topGroup.setupLogic();
3560
+ _this._setEmptyListener();
3561
+ var count = _this.s.topGroup.count();
3562
+ _this._updateTitle(count);
3563
+ _this._filterChanged(count);
3564
+ });
3512
3565
  this.s.topGroup.dom.container.unbind('dtsb-redrawLogic');
3513
3566
  this.s.topGroup.dom.container.on('dtsb-redrawLogic.dtsb', function () {
3514
3567
  _this.s.topGroup.redrawLogic();
@@ -3544,7 +3597,7 @@
3544
3597
  _this.dom.clearAll.remove();
3545
3598
  });
3546
3599
  };
3547
- SearchBuilder.version = '1.3.1';
3600
+ SearchBuilder.version = '1.3.4';
3548
3601
  SearchBuilder.classes = {
3549
3602
  button: 'dtsb-button',
3550
3603
  clearAll: 'dtsb-clearAll',
@@ -3650,7 +3703,7 @@
3650
3703
  return SearchBuilder;
3651
3704
  }());
3652
3705
 
3653
- /*! SearchBuilder 1.3.1
3706
+ /*! SearchBuilder 1.3.4
3654
3707
  * ©SpryMedia Ltd - datatables.net/license/mit
3655
3708
  */
3656
3709
  // DataTables extensions common UMD. Note that this allows for AMD, CommonJS
@@ -3710,12 +3763,13 @@
3710
3763
  align: 'container',
3711
3764
  span: 'container'
3712
3765
  });
3766
+ var topGroup = config._searchBuilder.s.topGroup;
3713
3767
  // Need to redraw the contents to calculate the correct positions for the elements
3714
- if (config._searchBuilder.s.topGroup !== undefined) {
3715
- config._searchBuilder.s.topGroup.dom.container.trigger('dtsb-redrawContents');
3768
+ if (topGroup !== undefined) {
3769
+ topGroup.dom.container.trigger('dtsb-redrawContents-noDraw');
3716
3770
  }
3717
- if (config._searchBuilder.s.topGroup.s.criteria.length === 0) {
3718
- $('.' + $.fn.dataTable.Group.classes.add).click();
3771
+ if (topGroup.s.criteria.length === 0) {
3772
+ $('.' + $.fn.dataTable.Group.classes.add.replace(/ /g, '.')).click();
3719
3773
  }
3720
3774
  },
3721
3775
  config: {},