@syncfusion/ej2-dropdowns 34.1.29 → 34.1.32

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.
@@ -266,6 +266,7 @@ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _argume
266
266
  };
267
267
  class VirtualScroll {
268
268
  constructor(parent) {
269
+ this.previousScrollTop = 0;
269
270
  this.sentinelInfo = {
270
271
  'up': {
271
272
  check: (rect, info) => {
@@ -325,9 +326,14 @@ class VirtualScroll {
325
326
  getModuleName() {
326
327
  return 'VirtualScroll';
327
328
  }
329
+ isFilterScrollScenario() {
330
+ return this.component === 'dropdownlist' && this.parent.allowFiltering;
331
+ }
328
332
  popupScrollHandler() {
329
333
  this.parent.isMouseScrollAction = true;
330
- this.parent.isPreventScrollAction = false;
334
+ if (!(this.isFilterScrollScenario() && this.parent.isVirtualScrolling)) {
335
+ this.parent.isPreventScrollAction = false;
336
+ }
331
337
  }
332
338
  getPageQuery(query, virtualStartIndex, virtualEndIndex) {
333
339
  if (virtualEndIndex !== 0 && !this.parent.allowFiltering && this.component !== 'autocomplete') {
@@ -685,7 +691,8 @@ class VirtualScroll {
685
691
  });
686
692
  }
687
693
  scrollListener(scrollArgs) {
688
- if (!this.parent.isPreventScrollAction && !this.parent.isVirtualTrackHeight) {
694
+ const preventReentrant = this.isFilterScrollScenario() && this.parent.isVirtualScrolling;
695
+ if (!this.parent.isPreventScrollAction && !this.parent.isVirtualTrackHeight && !preventReentrant) {
689
696
  this.parent.preventSetCurrentData = false;
690
697
  const info = scrollArgs.sentinel;
691
698
  const pStartIndex = this.parent.previousStartIndex;
@@ -697,6 +704,8 @@ class VirtualScroll {
697
704
  this.parent.virtualListInfo = Object.assign({}, this.parent.viewPortInfo);
698
705
  this.parent.isPreventKeyAction = true;
699
706
  this.parent.isVirtualScrolling = true;
707
+ const savedScrollTop = this.parent.popupContentElement ?
708
+ this.parent.popupContentElement.scrollTop : 0;
700
709
  setTimeout(() => {
701
710
  this.parent.pageCount = this.parent.getPageCount();
702
711
  this.parent.isRequesting = false;
@@ -706,9 +715,16 @@ class VirtualScroll {
706
715
  this.parent.updateSelectionList();
707
716
  this.parent.liCollections = this.parent.getItems();
708
717
  }
718
+ if (this.isFilterScrollScenario()) {
719
+ const scrollContainer = this.parent.popupContentElement || this.parent.list;
720
+ if (scrollContainer && scrollContainer.scrollTop < savedScrollTop) {
721
+ scrollContainer.scrollTop = savedScrollTop;
722
+ }
723
+ this.previousScrollTop = scrollContainer ? scrollContainer.scrollTop : savedScrollTop;
724
+ }
709
725
  this.parent.isKeyBoardAction = false;
710
- this.parent.isVirtualScrolling = false;
711
726
  this.parent.isPreventKeyAction = false;
727
+ this.parent.isVirtualScrolling = false;
712
728
  });
713
729
  }, 5);
714
730
  }
@@ -781,14 +797,17 @@ class VirtualScroll {
781
797
  }
782
798
  virtualScrollHandler(callback) {
783
799
  const delay = Browser.info.name === 'chrome' ? 200 : 100;
784
- let prevTop = 0;
785
800
  const debounced100 = debounce(callback, delay);
786
801
  const debounced50 = debounce(callback, 50);
787
802
  return (e) => {
788
803
  const top = e.target.scrollTop;
789
804
  const left = e.target.scrollLeft;
790
- const direction = prevTop < top && !this.parent.isUpwardScrolling ? 'down' : 'up';
791
- prevTop = top;
805
+ if (this.isFilterScrollScenario() && (this.parent.isVirtualScrolling || this.parent.isPreventScrollAction)) {
806
+ this.previousScrollTop = top;
807
+ return;
808
+ }
809
+ const direction = this.previousScrollTop < top && !this.parent.isUpwardScrolling ? 'down' : 'up';
810
+ this.previousScrollTop = top;
792
811
  const current = this.sentinelInfo[direction];
793
812
  const pstartIndex = this.parent.scrollPreStartIndex;
794
813
  const scrollOffsetargs = {
@@ -3256,6 +3275,7 @@ let DropDownList = class DropDownList extends DropDownBase {
3256
3275
  this.initialRemoteRender = false;
3257
3276
  this.isNotSearchList = false;
3258
3277
  this.isTyped = false;
3278
+ this.isProgrammaticValueUpdate = false;
3259
3279
  this.isSelected = false;
3260
3280
  this.preventFocus = false;
3261
3281
  this.preventAutoFill = false;
@@ -4726,7 +4746,7 @@ let DropDownList = class DropDownList extends DropDownBase {
4726
4746
  }
4727
4747
  }
4728
4748
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
4729
- setValue(e) {
4749
+ setValue(e, autofill) {
4730
4750
  const dataItem = this.getItemData();
4731
4751
  this.isTouched = !isNullOrUndefined(e);
4732
4752
  if (dataItem.value === null) {
@@ -4758,7 +4778,7 @@ let DropDownList = class DropDownList extends DropDownBase {
4758
4778
  (this.previousValue != null && this.isObjectInArray(this.previousValue, [this.allowCustom &&
4759
4779
  this.isObjectCustomValue ? this.value ? this.value : dataItem : dataItem.value ?
4760
4780
  this.getDataByValue(dataItem.value) : dataItem])))) {
4761
- if (this.getModuleName() === 'combobox' && this.autoFill && e && (e.type === 'click' || e.action === 'enter')) {
4781
+ if (this.getModuleName() === 'combobox' && autofill && e && (e.type === 'click' || e.action === 'enter')) {
4762
4782
  return false;
4763
4783
  }
4764
4784
  this.isSelected = false;
@@ -5542,6 +5562,9 @@ let DropDownList = class DropDownList extends DropDownBase {
5542
5562
  }
5543
5563
  this.initial = false;
5544
5564
  }
5565
+ if (this.isProgrammaticValueUpdate && !isNullOrUndefined(this.value) && this.getModuleName() === 'combobox') {
5566
+ this.detachChangeEvent(null);
5567
+ }
5545
5568
  else if (this.getModuleName() === 'autocomplete' && this.value) {
5546
5569
  this.setInputValue();
5547
5570
  }
@@ -5646,8 +5669,11 @@ let DropDownList = class DropDownList extends DropDownBase {
5646
5669
  }
5647
5670
  checkAndFetchItemData(list, value, checkField, isOffline = false) {
5648
5671
  const fieldValue = this.fields.value.split('.');
5649
- let checkVal = list.some((x) => isNullOrUndefined(x[checkField]) && fieldValue.length > 1 ?
5650
- this.checkFieldValue(x, fieldValue) === value : x[checkField] === value);
5672
+ let checkVal = false;
5673
+ if (!isNullOrUndefined(list) && list.length > 0) {
5674
+ checkVal = list.some((x) => isNullOrUndefined(x[checkField]) && fieldValue.length > 1 ?
5675
+ this.checkFieldValue(x, fieldValue) === value : x[checkField] === value);
5676
+ }
5651
5677
  if (this.enableVirtualization && this.virtualGroupDataSource) {
5652
5678
  checkVal = this.virtualGroupDataSource.some((x) => isNullOrUndefined(x[checkField]) && fieldValue.length > 1 ?
5653
5679
  this.checkFieldValue(x, fieldValue) === value : x[checkField] === value);
@@ -7169,6 +7195,9 @@ let DropDownList = class DropDownList extends DropDownBase {
7169
7195
  this.isObjectInArray(newProp.value, [oldProp.value])) {
7170
7196
  return;
7171
7197
  }
7198
+ if (!this.initial && this.dataSource instanceof DataManager) {
7199
+ this.isProgrammaticValueUpdate = true;
7200
+ }
7172
7201
  if (this.enableVirtualization) {
7173
7202
  const isOfflineMode = this.dataSource instanceof DataManager &&
7174
7203
  this.dataSource.dataSource.offline === true;
@@ -12017,7 +12046,7 @@ let ComboBox = class ComboBox extends DropDownList {
12017
12046
  return false;
12018
12047
  }
12019
12048
  else {
12020
- return super.setValue(e);
12049
+ return super.setValue(e, this.autofill);
12021
12050
  }
12022
12051
  }
12023
12052
  checkCustomValue() {
@@ -13869,49 +13898,154 @@ let MultiSelect = class MultiSelect extends DropDownBase {
13869
13898
  getForQuery(valuecheck, isCheckbox) {
13870
13899
  let predicate;
13871
13900
  const field = this.isPrimitiveData ? '' : this.fields.value;
13872
- if (this.enableVirtualization && valuecheck) {
13873
- if (isCheckbox) {
13874
- const startindex = this.viewPortInfo.startIndex;
13875
- const endindex = (((startindex + this.viewPortInfo.endIndex) <= (valuecheck.length)) &&
13876
- valuecheck[(startindex + this.viewPortInfo.endIndex)]) &&
13877
- (this.dataSource instanceof DataManager && this.totalItemCount !== 0 && this.totalItemCount > (this.itemCount * 2))
13878
- ? (startindex + this.viewPortInfo.endIndex)
13879
- : (valuecheck.length);
13880
- for (let i = startindex; i < endindex; i++) {
13881
- const value = this.allowObjectBinding ? getValue((this.fields.value) ?
13882
- this.fields.value : '', valuecheck[i]) : valuecheck[i];
13883
- if (i === startindex) {
13884
- predicate = new Predicate(field, 'equal', (value));
13901
+ if (valuecheck && valuecheck.length >= 3000) {
13902
+ // Batch size to prevent stack overflow with large preselected values (EJ2-Fix-MaxCallStack)
13903
+ const BATCH_SIZE = 100;
13904
+ if (this.enableVirtualization) {
13905
+ if (isCheckbox) {
13906
+ const startindex = this.viewPortInfo.startIndex;
13907
+ const endindex = (((startindex + this.viewPortInfo.endIndex) <= (valuecheck.length)) &&
13908
+ valuecheck[(startindex + this.viewPortInfo.endIndex)]) &&
13909
+ (this.dataSource instanceof DataManager && this.totalItemCount !== 0 && this.totalItemCount > (this.itemCount * 2))
13910
+ ? (startindex + this.viewPortInfo.endIndex)
13911
+ : (valuecheck.length);
13912
+ // Build predicates in batches to prevent stack overflow
13913
+ const predicateBatches = [];
13914
+ for (let batchStart = startindex; batchStart < endindex; batchStart += BATCH_SIZE) {
13915
+ let batchPredicate;
13916
+ const batchEnd = Math.min(batchStart + BATCH_SIZE, endindex);
13917
+ for (let i = batchStart; i < batchEnd; i++) {
13918
+ const itemAtIndex = valuecheck[i];
13919
+ const value = this.allowObjectBinding ? getValue((this.fields.value) ?
13920
+ this.fields.value : '', itemAtIndex) : itemAtIndex;
13921
+ if (i === batchStart) {
13922
+ batchPredicate = new Predicate(field, 'equal', (value));
13923
+ }
13924
+ else {
13925
+ batchPredicate = batchPredicate.or(field, 'equal', (value));
13926
+ }
13927
+ }
13928
+ predicateBatches.push(batchPredicate);
13885
13929
  }
13886
- else {
13887
- predicate = predicate.or(field, 'equal', (value));
13930
+ // Combine all batch predicates
13931
+ predicate = predicateBatches[0];
13932
+ for (let i = 1; i < predicateBatches.length; i++) {
13933
+ predicate = predicate.or(predicateBatches[i]);
13888
13934
  }
13935
+ return new Query().where(predicate);
13936
+ }
13937
+ else {
13938
+ // Build predicates in batches to prevent stack overflow
13939
+ const predicateBatches = [];
13940
+ const isAddNonPresentItems = this.isaddNonPresentItems;
13941
+ for (let batchStart = 0; batchStart < valuecheck.length; batchStart += BATCH_SIZE) {
13942
+ let batchPredicate;
13943
+ const batchEnd = Math.min(batchStart + BATCH_SIZE, valuecheck.length);
13944
+ for (let i = batchStart; i < batchEnd; i++) {
13945
+ const itemAtIndex = valuecheck[i];
13946
+ const value = this.allowObjectBinding ? getValue((this.fields.value) ?
13947
+ this.fields.value : '', itemAtIndex) : itemAtIndex;
13948
+ if (i === batchStart) {
13949
+ if (isAddNonPresentItems) {
13950
+ batchPredicate = new Predicate(field, 'equal', itemAtIndex);
13951
+ }
13952
+ else {
13953
+ batchPredicate = new Predicate(field, 'notequal', (value));
13954
+ }
13955
+ }
13956
+ else {
13957
+ if (isAddNonPresentItems) {
13958
+ batchPredicate = batchPredicate.or(field, 'equal', itemAtIndex);
13959
+ }
13960
+ else {
13961
+ batchPredicate = batchPredicate.and(field, 'notequal', (value));
13962
+ }
13963
+ }
13964
+ }
13965
+ predicateBatches.push(batchPredicate);
13966
+ }
13967
+ // Combine batch predicates
13968
+ predicate = predicateBatches[0];
13969
+ for (let i = 1; i < predicateBatches.length; i++) {
13970
+ if (isAddNonPresentItems) {
13971
+ predicate = predicate.or(predicateBatches[i]);
13972
+ }
13973
+ else {
13974
+ predicate = predicate.and(predicateBatches[i]);
13975
+ }
13976
+ }
13977
+ return new Query().where(predicate);
13889
13978
  }
13890
- return new Query().where(predicate);
13891
13979
  }
13892
13980
  else {
13893
- for (let i = 0; i < valuecheck.length; i++) {
13894
- const value = this.allowObjectBinding ? getValue((this.fields.value) ?
13895
- this.fields.value : '', valuecheck[i]) : valuecheck[i];
13896
- if (this.isaddNonPresentItems) {
13897
- predicate = i === 0 ? new Predicate(field, 'equal', valuecheck[i])
13898
- : predicate.or(field, 'equal', valuecheck[i]);
13899
- }
13900
- else {
13901
- predicate = i === 0 ? predicate = new Predicate(field, 'notequal', (value))
13902
- : predicate.and(field, 'notequal', (value));
13981
+ // Build predicates in batches to prevent stack overflow with large preselected values
13982
+ const predicateBatches = [];
13983
+ for (let batchStart = 0; batchStart < valuecheck.length; batchStart += BATCH_SIZE) {
13984
+ let batchPredicate;
13985
+ const batchEnd = Math.min(batchStart + BATCH_SIZE, valuecheck.length);
13986
+ for (let i = batchStart; i < batchEnd; i++) {
13987
+ const itemAtIndex = valuecheck[i];
13988
+ if (i === batchStart) {
13989
+ batchPredicate = new Predicate(field, 'equal', itemAtIndex);
13990
+ }
13991
+ else {
13992
+ batchPredicate = batchPredicate.or(field, 'equal', itemAtIndex);
13993
+ }
13903
13994
  }
13995
+ predicateBatches.push(batchPredicate);
13996
+ }
13997
+ // Combine all batch predicates
13998
+ predicate = predicateBatches[0];
13999
+ for (let i = 1; i < predicateBatches.length; i++) {
14000
+ predicate = predicate.or(predicateBatches[i]);
13904
14001
  }
13905
- return new Query().where(predicate);
13906
14002
  }
13907
14003
  }
13908
14004
  else {
13909
- for (let i = 0; i < valuecheck.length; i++) {
13910
- if (i === 0) {
13911
- predicate = new Predicate(field, 'equal', valuecheck[i]);
14005
+ if (this.enableVirtualization && valuecheck) {
14006
+ if (isCheckbox) {
14007
+ const startindex = this.viewPortInfo.startIndex;
14008
+ const endindex = (((startindex + this.viewPortInfo.endIndex) <= (valuecheck.length)) &&
14009
+ valuecheck[(startindex + this.viewPortInfo.endIndex)]) &&
14010
+ (this.dataSource instanceof DataManager && this.totalItemCount !== 0 && this.totalItemCount > (this.itemCount * 2))
14011
+ ? (startindex + this.viewPortInfo.endIndex)
14012
+ : (valuecheck.length);
14013
+ for (let i = startindex; i < endindex; i++) {
14014
+ const value = this.allowObjectBinding ? getValue((this.fields.value) ?
14015
+ this.fields.value : '', valuecheck[i]) : valuecheck[i];
14016
+ if (i === startindex) {
14017
+ predicate = new Predicate(field, 'equal', (value));
14018
+ }
14019
+ else {
14020
+ predicate = predicate.or(field, 'equal', (value));
14021
+ }
14022
+ }
14023
+ return new Query().where(predicate);
13912
14024
  }
13913
14025
  else {
13914
- predicate = predicate.or(field, 'equal', valuecheck[i]);
14026
+ for (let i = 0; i < valuecheck.length; i++) {
14027
+ const value = this.allowObjectBinding ? getValue((this.fields.value) ?
14028
+ this.fields.value : '', valuecheck[i]) : valuecheck[i];
14029
+ if (this.isaddNonPresentItems) {
14030
+ predicate = i === 0 ? new Predicate(field, 'equal', valuecheck[i])
14031
+ : predicate.or(field, 'equal', valuecheck[i]);
14032
+ }
14033
+ else {
14034
+ predicate = i === 0 ? predicate = new Predicate(field, 'notequal', (value))
14035
+ : predicate.and(field, 'notequal', (value));
14036
+ }
14037
+ }
14038
+ return new Query().where(predicate);
14039
+ }
14040
+ }
14041
+ else {
14042
+ for (let i = 0; i < valuecheck.length; i++) {
14043
+ if (i === 0) {
14044
+ predicate = new Predicate(field, 'equal', valuecheck[i]);
14045
+ }
14046
+ else {
14047
+ predicate = predicate.or(field, 'equal', valuecheck[i]);
14048
+ }
13915
14049
  }
13916
14050
  }
13917
14051
  }
@@ -16171,6 +16305,9 @@ let MultiSelect = class MultiSelect extends DropDownBase {
16171
16305
  }
16172
16306
  }
16173
16307
  }
16308
+ isFilteringWithRemoteData() {
16309
+ return !isNullOrUndefined(this.mainData) && this.mainData.length > 0 && this.allowFiltering;
16310
+ }
16174
16311
  removeChip(value, isClearAll) {
16175
16312
  if (this.chipCollectionWrapper) {
16176
16313
  if (!(this.enableVirtualization && isClearAll)) {
@@ -17366,6 +17503,9 @@ let MultiSelect = class MultiSelect extends DropDownBase {
17366
17503
  getValue(((this.fields.value) ? this.fields.value : ''), this.value[index]) :
17367
17504
  this.value[index];
17368
17505
  element = this.findListElement(this.hideSelectedItem ? this.ulElement : this.list, 'li', 'data-value', value);
17506
+ if (!element && !isNullOrUndefined(this.mainList) && this.isFilteringWithRemoteData()) {
17507
+ element = this.findListElement(this.mainList, 'li', 'data-value', value);
17508
+ }
17369
17509
  let isCustomData = false;
17370
17510
  if (this.enableVirtualization) {
17371
17511
  text = null;
@@ -17412,6 +17552,12 @@ let MultiSelect = class MultiSelect extends DropDownBase {
17412
17552
  }
17413
17553
  else {
17414
17554
  text = this.getTextByValue(value);
17555
+ if (text === value && this.isFilteringWithRemoteData()) {
17556
+ const savedListData = this.listData;
17557
+ this.listData = this.mainData;
17558
+ text = this.getTextByValue(value);
17559
+ this.listData = savedListData;
17560
+ }
17415
17561
  }
17416
17562
  if (((element && (element.getAttribute('aria-selected') !== 'true')) ||
17417
17563
  (element && (element.getAttribute('aria-selected') === 'true' && this.hideSelectedItem) &&
@@ -19680,6 +19826,8 @@ let MultiSelect = class MultiSelect extends DropDownBase {
19680
19826
  this.chipCollectionWrapper = this.createElement('span', {
19681
19827
  className: CHIP_WRAPPER$1
19682
19828
  });
19829
+ this.chipCollectionWrapper.setAttribute('role', 'listbox');
19830
+ this.chipCollectionWrapper.setAttribute('aria-label', 'multiselect');
19683
19831
  this.chipCollectionWrapper.style.display = 'none';
19684
19832
  if (this.mode === 'Default') {
19685
19833
  this.chipCollectionWrapper.setAttribute('id', getUniqueID('chip_default'));