igniteui-angular 12.3.40 → 12.3.42

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.
@@ -39241,6 +39241,9 @@
39241
39241
  };
39242
39242
  IgxComboAPIService.prototype.set_selected_item = function (itemID, event) {
39243
39243
  var selected = this.combo.isItemSelected(itemID);
39244
+ if (itemID === undefined) {
39245
+ return;
39246
+ }
39244
39247
  if (!selected) {
39245
39248
  this.combo.select([itemID], false, event);
39246
39249
  }
@@ -39853,7 +39856,13 @@
39853
39856
  return this._data;
39854
39857
  },
39855
39858
  set: function (val) {
39856
- this._data = (val) ? val : [];
39859
+ // igxFor directive ignores undefined values
39860
+ // if the combo uses simple data and filtering is applied
39861
+ // an error will occur due to the mismatch of the length of the data
39862
+ // this can occur during filtering for the igx-combo and
39863
+ // during filtering & selection for the igx-simple-combo
39864
+ // since the simple combo's input is both a container for the selection and a filter
39865
+ this._data = (val) ? val.filter(function (x) { return x !== undefined; }) : [];
39857
39866
  },
39858
39867
  enumerable: false,
39859
39868
  configurable: true
@@ -40463,6 +40472,18 @@
40463
40472
  this.registerRemoteEntries(removedItems, false);
40464
40473
  return Object.keys(this._remoteSelection).map(function (e) { return _this._remoteSelection[e]; }).join(', ');
40465
40474
  };
40475
+ Object.defineProperty(IgxComboBaseDirective.prototype, "required", {
40476
+ get: function () {
40477
+ if (this.ngControl && this.ngControl.control && this.ngControl.control.validator) {
40478
+ // Run the validation with empty object to check if required is enabled.
40479
+ var error = this.ngControl.control.validator({});
40480
+ return error && error.required;
40481
+ }
40482
+ return false;
40483
+ },
40484
+ enumerable: false,
40485
+ configurable: true
40486
+ });
40466
40487
  return IgxComboBaseDirective;
40467
40488
  }(DisplayDensityBase));
40468
40489
  IgxComboBaseDirective.decorators = [
@@ -40679,7 +40700,7 @@
40679
40700
  * @hidden
40680
40701
  */
40681
40702
  IgxComboDropDownComponent.prototype.navigateFirst = function () {
40682
- this.navigateItem(this.virtDir.igxForOf.findIndex(function (e) { return !e.isHeader; }));
40703
+ this.navigateItem(this.virtDir.igxForOf.findIndex(function (e) { return !(e === null || e === void 0 ? void 0 : e.isHeader); }));
40683
40704
  };
40684
40705
  /**
40685
40706
  * @hidden
@@ -40818,8 +40839,8 @@
40818
40839
  });
40819
40840
  }
40820
40841
  else {
40821
- return collection.filter(function (e) { return filteringOptions.caseSensitive ? e.includes(searchTerm_1) :
40822
- e.toString().toLowerCase().includes(searchTerm_1); });
40842
+ return collection.filter(function (e) { return filteringOptions.caseSensitive ? e === null || e === void 0 ? void 0 : e.includes(searchTerm_1) :
40843
+ e === null || e === void 0 ? void 0 : e.toString().toLowerCase().includes(searchTerm_1); });
40823
40844
  }
40824
40845
  }
40825
40846
  };
@@ -40835,6 +40856,7 @@
40835
40856
  }
40836
40857
  IgxComboGroupingPipe.prototype.transform = function (collection, groupKey, valueKey) {
40837
40858
  var _c;
40859
+ // TODO: should filteredData be changed here?
40838
40860
  this.combo.filteredData = collection;
40839
40861
  if ((!groupKey && groupKey !== 0) || !collection.length) {
40840
40862
  return collection;
@@ -41024,7 +41046,7 @@
41024
41046
  * @hidden @internal
41025
41047
  */
41026
41048
  IgxComboComponent.prototype.writeValue = function (value) {
41027
- var selection = Array.isArray(value) ? value : [];
41049
+ var selection = Array.isArray(value) ? value.filter(function (x) { return x !== undefined; }) : [];
41028
41050
  var oldSelection = this.selection;
41029
41051
  this.selectionService.select_items(this.id, selection, true);
41030
41052
  this.cdr.markForCheck();
@@ -41142,6 +41164,9 @@
41142
41164
  */
41143
41165
  IgxComboComponent.prototype.setSelectedItem = function (itemID, select, event) {
41144
41166
  if (select === void 0) { select = true; }
41167
+ if (itemID === undefined) {
41168
+ return;
41169
+ }
41145
41170
  if (select) {
41146
41171
  this.select([itemID], false, event);
41147
41172
  }
@@ -41227,7 +41252,7 @@
41227
41252
  IgxComboComponent.decorators = [
41228
41253
  { type: i0.Component, args: [{
41229
41254
  selector: 'igx-combo',
41230
- template: "<igx-input-group #inputGroup [displayDensity]=\"displayDensity\" [type]=\"type\" (click)=\"onClick($event)\">\n <ng-container ngProjectAs=\"[igxLabel]\">\n <ng-content select=\"[igxLabel]\"></ng-content>\n </ng-container>\n <ng-container ngProjectAs=\"igx-prefix\">\n <ng-content select=\"igx-prefix\"></ng-content>\n </ng-container>\n <ng-container ngProjectAs=\"igx-hint, [igxHint]\">\n <ng-content select=\"igx-hint, [igxHint]\"></ng-content>\n </ng-container>\n <input igxInput #comboInput name=\"comboInput\" type=\"text\" [value]=\"value\" readonly [attr.placeholder]=\"placeholder\"\n [disabled]=\"disabled\" (blur)=\"onBlur()\" />\n <ng-container ngProjectAs=\"igx-suffix\">\n <ng-content select=\"igx-suffix\"></ng-content>\n </ng-container>\n <igx-suffix *ngIf=\"value.length\" aria-label=\"Clear Selection\" class=\"igx-combo__clear-button\"\n (click)=\"handleClearItems($event)\">\n <ng-container *ngIf=\"clearIconTemplate\">\n <ng-container *ngTemplateOutlet=\"clearIconTemplate\"></ng-container>\n </ng-container>\n <igx-icon *ngIf=\"!clearIconTemplate\">\n clear\n </igx-icon>\n </igx-suffix>\n <igx-suffix class=\"igx-combo__toggle-button\">\n <ng-container *ngIf=\"toggleIconTemplate\">\n <ng-container *ngTemplateOutlet=\"toggleIconTemplate; context: {$implicit: this.collapsed}\"></ng-container>\n </ng-container>\n <igx-icon *ngIf=\"!toggleIconTemplate\">\n {{ dropdown.collapsed ? 'arrow_drop_down' : 'arrow_drop_up'}}\n </igx-icon>\n </igx-suffix>\n</igx-input-group>\n<igx-combo-drop-down #igxComboDropDown class=\"igx-combo__drop-down\" [displayDensity]=\"displayDensity\"\n [width]=\"itemsWidth || '100%'\" (opening)=\"handleOpening($event)\" (closing)=\"handleClosing($event)\"\n (opened)=\"handleOpened()\" (closed)=\"handleClosed()\">\n <igx-input-group *ngIf=\"displaySearchInput\" [displayDensity]=\"displayDensity\" theme=\"material\" class=\"igx-combo__search\">\n <input class=\"igx-combo-input\" igxInput #searchInput name=\"searchInput\" autocomplete=\"off\" type=\"text\"\n [(ngModel)]=\"searchValue\" (ngModelChange)=\"handleInputChange($event)\" (keyup)=\"handleKeyUp($event)\"\n (keydown)=\"handleKeyDown($event)\" (focus)=\"dropdown.onBlur($event)\" [attr.placeholder]=\"searchPlaceholder\"\n aria-autocomplete=\"both\" [attr.aria-owns]=\"dropdown.id\" [attr.aria-labelledby]=\"ariaLabelledBy\" />\n <igx-suffix *ngIf=\"showSearchCaseIcon\">\n <igx-icon family=\"imx-icons\" name=\"case-sensitive\" [active]=\"filteringOptions.caseSensitive\"\n (click)=\"toggleCaseSensitive()\">\n </igx-icon>\n </igx-suffix>\n </igx-input-group>\n <ng-container *ngTemplateOutlet=\"headerTemplate\">\n </ng-container>\n <div #dropdownItemContainer class=\"igx-combo__content\" [style.overflow]=\"'hidden'\"\n [style.maxHeight.px]=\"itemsMaxHeight\" [igxDropDownItemNavigation]=\"dropdown\" (focus)=\"dropdown.onFocus()\"\n [tabindex]=\"dropdown.collapsed ? -1 : 0\" role=\"listbox\" [attr.id]=\"dropdown.id\">\n <igx-combo-item role=\"option\" [itemHeight]='itemHeight' *igxFor=\"let item of data\n | comboFiltering:filterValue:displayKey:filteringOptions:filterable\n | comboGrouping:groupKey:valueKey\n index as rowIndex; containerSize: itemsMaxHeight; scrollOrientation: 'vertical'; itemSize: itemHeight\"\n [value]=\"item\" [isHeader]=\"item.isHeader\" [index]=\"rowIndex\">\n <ng-container *ngIf=\"item.isHeader\">\n <ng-container\n *ngTemplateOutlet=\"headerItemTemplate ? headerItemTemplate : headerItemBase;\n context: {$implicit: item, data: data, valueKey: valueKey, groupKey: groupKey, displayKey: displayKey}\">\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!item.isHeader\">\n <ng-container #listItem\n *ngTemplateOutlet=\"template; context: {$implicit: item, data: data, valueKey: valueKey, displayKey: displayKey};\">\n </ng-container>\n </ng-container>\n </igx-combo-item>\n </div>\n <div class=\"igx-combo__add\" *ngIf=\"filteredData.length === 0 || isAddButtonVisible()\">\n <div class=\"igx-combo__empty\" *ngIf=\"filteredData.length === 0\">\n <ng-container *ngTemplateOutlet=\"emptyTemplate ? emptyTemplate : empty\">\n </ng-container>\n </div>\n <igx-combo-add-item [itemHeight]=\"itemHeight\" *ngIf=\"isAddButtonVisible()\"\n [tabindex]=\"dropdown.collapsed ? -1 : customValueFlag ? 1 : -1\" class=\"igx-combo__add-item\" role=\"button\"\n aria-label=\"Add Item\" [index]=\"virtualScrollContainer.igxForOf.length\">\n <ng-container *ngTemplateOutlet=\"addItemTemplate ? addItemTemplate : addItemDefault\">\n </ng-container>\n </igx-combo-add-item>\n </div>\n <ng-container *ngTemplateOutlet=\"footerTemplate\">\n </ng-container>\n</igx-combo-drop-down>\n<ng-template #complex let-display let-data=\"data\" let-key=\"displayKey\">\n {{display[key]}}\n</ng-template>\n<ng-template #primitive let-display>\n {{display}}\n</ng-template>\n<ng-template #empty>\n <span>{{resourceStrings.igx_combo_empty_message}}</span>\n</ng-template>\n<ng-template #addItemDefault let-control>\n <button igxButton=\"flat\" igxRipple>Add item</button>\n</ng-template>\n<ng-template #headerItemBase let-item let-key=\"valueKey\" let-groupKey=\"groupKey\">\n {{ item[key] }}\n</ng-template>\n",
41255
+ template: "<igx-input-group #inputGroup [displayDensity]=\"displayDensity\" [type]=\"type\" (click)=\"onClick($event)\">\n <ng-container ngProjectAs=\"[igxLabel]\">\n <ng-content select=\"[igxLabel]\"></ng-content>\n </ng-container>\n <ng-container ngProjectAs=\"igx-prefix\">\n <ng-content select=\"igx-prefix\"></ng-content>\n </ng-container>\n <ng-container ngProjectAs=\"igx-hint, [igxHint]\">\n <ng-content select=\"igx-hint, [igxHint]\"></ng-content>\n </ng-container>\n <input igxInput #comboInput name=\"comboInput\" type=\"text\" [value]=\"value\" readonly [attr.placeholder]=\"placeholder\"\n [disabled]=\"disabled\" (blur)=\"onBlur()\" />\n <ng-container ngProjectAs=\"igx-suffix\">\n <ng-content select=\"igx-suffix\"></ng-content>\n </ng-container>\n <igx-suffix *ngIf=\"value.length\" aria-label=\"Clear Selection\" class=\"igx-combo__clear-button\"\n (click)=\"handleClearItems($event)\">\n <ng-container *ngIf=\"clearIconTemplate\">\n <ng-container *ngTemplateOutlet=\"clearIconTemplate\"></ng-container>\n </ng-container>\n <igx-icon *ngIf=\"!clearIconTemplate\">\n clear\n </igx-icon>\n </igx-suffix>\n <igx-suffix class=\"igx-combo__toggle-button\">\n <ng-container *ngIf=\"toggleIconTemplate\">\n <ng-container *ngTemplateOutlet=\"toggleIconTemplate; context: {$implicit: this.collapsed}\"></ng-container>\n </ng-container>\n <igx-icon *ngIf=\"!toggleIconTemplate\">\n {{ dropdown.collapsed ? 'arrow_drop_down' : 'arrow_drop_up'}}\n </igx-icon>\n </igx-suffix>\n</igx-input-group>\n<igx-combo-drop-down #igxComboDropDown class=\"igx-combo__drop-down\" [displayDensity]=\"displayDensity\"\n [width]=\"itemsWidth || '100%'\" (opening)=\"handleOpening($event)\" (closing)=\"handleClosing($event)\"\n (opened)=\"handleOpened()\" (closed)=\"handleClosed()\">\n <igx-input-group *ngIf=\"displaySearchInput\" [displayDensity]=\"displayDensity\" theme=\"material\" class=\"igx-combo__search\">\n <input class=\"igx-combo-input\" igxInput #searchInput name=\"searchInput\" autocomplete=\"off\" type=\"text\"\n [(ngModel)]=\"searchValue\" (ngModelChange)=\"handleInputChange($event)\" (keyup)=\"handleKeyUp($event)\"\n (keydown)=\"handleKeyDown($event)\" (focus)=\"dropdown.onBlur($event)\" [attr.placeholder]=\"searchPlaceholder\"\n aria-autocomplete=\"both\" [attr.aria-owns]=\"dropdown.id\" [attr.aria-labelledby]=\"ariaLabelledBy\" />\n <igx-suffix *ngIf=\"showSearchCaseIcon\">\n <igx-icon family=\"imx-icons\" name=\"case-sensitive\" [active]=\"filteringOptions.caseSensitive\"\n (click)=\"toggleCaseSensitive()\">\n </igx-icon>\n </igx-suffix>\n </igx-input-group>\n <ng-container *ngTemplateOutlet=\"headerTemplate\">\n </ng-container>\n <div #dropdownItemContainer class=\"igx-combo__content\" [style.overflow]=\"'hidden'\"\n [style.maxHeight.px]=\"itemsMaxHeight\" [igxDropDownItemNavigation]=\"dropdown\" (focus)=\"dropdown.onFocus()\"\n [tabindex]=\"dropdown.collapsed ? -1 : 0\" role=\"listbox\" [attr.id]=\"dropdown.id\">\n <igx-combo-item role=\"option\" [itemHeight]='itemHeight' *igxFor=\"let item of data\n | comboFiltering:filterValue:displayKey:filteringOptions:filterable\n | comboGrouping:groupKey:valueKey\n index as rowIndex; containerSize: itemsMaxHeight; scrollOrientation: 'vertical'; itemSize: itemHeight\"\n [value]=\"item\" [isHeader]=\"item?.isHeader\" [index]=\"rowIndex\">\n <ng-container *ngIf=\"item?.isHeader\">\n <ng-container\n *ngTemplateOutlet=\"headerItemTemplate ? headerItemTemplate : headerItemBase;\n context: {$implicit: item, data: data, valueKey: valueKey, groupKey: groupKey, displayKey: displayKey}\">\n </ng-container>\n </ng-container>\n <!-- if item is 'null' it should be displayed and !!(item?.isHeader) would resolve it to 'false' and not display it -->\n <ng-container *ngIf=\"!item?.isHeader\">\n <ng-container #listItem\n *ngTemplateOutlet=\"template; context: {$implicit: item, data: data, valueKey: valueKey, displayKey: displayKey};\">\n </ng-container>\n </ng-container>\n </igx-combo-item>\n </div>\n <div class=\"igx-combo__add\" *ngIf=\"filteredData.length === 0 || isAddButtonVisible()\">\n <div class=\"igx-combo__empty\" *ngIf=\"filteredData.length === 0\">\n <ng-container *ngTemplateOutlet=\"emptyTemplate ? emptyTemplate : empty\">\n </ng-container>\n </div>\n <igx-combo-add-item [itemHeight]=\"itemHeight\" *ngIf=\"isAddButtonVisible()\"\n [tabindex]=\"dropdown.collapsed ? -1 : customValueFlag ? 1 : -1\" class=\"igx-combo__add-item\" role=\"button\"\n aria-label=\"Add Item\" [index]=\"virtualScrollContainer.igxForOf.length\">\n <ng-container *ngTemplateOutlet=\"addItemTemplate ? addItemTemplate : addItemDefault\">\n </ng-container>\n </igx-combo-add-item>\n </div>\n <ng-container *ngTemplateOutlet=\"footerTemplate\">\n </ng-container>\n</igx-combo-drop-down>\n<ng-template #complex let-display let-data=\"data\" let-key=\"displayKey\">\n {{display[key]}}\n</ng-template>\n<ng-template #primitive let-display>\n {{display}}\n</ng-template>\n<ng-template #empty>\n <span>{{resourceStrings.igx_combo_empty_message}}</span>\n</ng-template>\n<ng-template #addItemDefault let-control>\n <button igxButton=\"flat\" igxRipple>Add item</button>\n</ng-template>\n<ng-template #headerItemBase let-item let-key=\"valueKey\" let-groupKey=\"groupKey\">\n {{ item[key] }}\n</ng-template>\n",
41231
41256
  providers: [
41232
41257
  IgxComboAPIService,
41233
41258
  { provide: IGX_COMBO_COMPONENT, useExisting: IgxComboComponent },
@@ -41334,6 +41359,7 @@
41334
41359
  _this._updateInput = true;
41335
41360
  // stores the last filtered value - move to common?
41336
41361
  _this._internalFilter = '';
41362
+ _this._collapsing = false;
41337
41363
  _this.findAllMatches = function (element) {
41338
41364
  var value = _this.displayKey ? element[_this.displayKey] : element;
41339
41365
  if (value === null || value === undefined || value === '') {
@@ -41403,7 +41429,7 @@
41403
41429
  * ```
41404
41430
  */
41405
41431
  IgxSimpleComboComponent.prototype.select = function (item) {
41406
- if (item !== null && item !== undefined) {
41432
+ if (item !== undefined) {
41407
41433
  var newSelection = this.selectionService.add_items(this.id, item instanceof Array ? item : [item], true);
41408
41434
  this.setSelection(newSelection);
41409
41435
  }
@@ -41421,10 +41447,12 @@
41421
41447
  };
41422
41448
  /** @hidden @internal */
41423
41449
  IgxSimpleComboComponent.prototype.writeValue = function (value) {
41450
+ var _a;
41424
41451
  var oldSelection = this.selection;
41425
- this.selectionService.select_items(this.id, value ? [value] : [], true);
41452
+ this.selectionService.select_items(this.id, this.isValid(value) ? [value] : [], true);
41426
41453
  this.cdr.markForCheck();
41427
41454
  this._value = this.createDisplayText(this.selection, oldSelection);
41455
+ this.filterValue = this._internalFilter = (_a = this._value) === null || _a === void 0 ? void 0 : _a.toString();
41428
41456
  };
41429
41457
  /** @hidden @internal */
41430
41458
  IgxSimpleComboComponent.prototype.ngAfterViewInit = function () {
@@ -41432,7 +41460,7 @@
41432
41460
  this.virtDir.contentSizeChange.pipe(operators.takeUntil(this.destroy$)).subscribe(function () {
41433
41461
  if (_this.selection.length > 0) {
41434
41462
  var index = _this.virtDir.igxForOf.findIndex(function (e) {
41435
- var current = e[_this.valueKey];
41463
+ var current = e ? e[_this.valueKey] : undefined;
41436
41464
  if (_this.valueKey === null || _this.valueKey === undefined) {
41437
41465
  current = e;
41438
41466
  }
@@ -41446,7 +41474,11 @@
41446
41474
  }
41447
41475
  }
41448
41476
  });
41449
- this.dropdown.opening.pipe(operators.takeUntil(this.destroy$)).subscribe(function () {
41477
+ this.dropdown.opening.pipe(operators.takeUntil(this.destroy$)).subscribe(function (args) {
41478
+ if (args.cancel) {
41479
+ return;
41480
+ }
41481
+ _this._collapsing = false;
41450
41482
  var filtered = _this.filteredData.find(_this.findAllMatches);
41451
41483
  if (filtered === undefined || filtered === null) {
41452
41484
  _this.filterValue = _this.searchValue = _this.comboInput.value;
@@ -41461,17 +41493,27 @@
41461
41493
  _this._internalFilter = _this.comboInput.value;
41462
41494
  });
41463
41495
  this.dropdown.closing.pipe(operators.takeUntil(this.destroy$)).subscribe(function (args) {
41496
+ if (args.cancel) {
41497
+ return;
41498
+ }
41464
41499
  if (_this.getEditElement() && !args.event) {
41465
- _this.comboInput.focus();
41500
+ _this._collapsing = true;
41466
41501
  }
41467
41502
  else {
41468
41503
  _this.clearOnBlur();
41469
41504
  _this._onTouchedCallback();
41470
41505
  }
41506
+ _this.comboInput.focus();
41471
41507
  });
41472
41508
  this.dropdown.closed.pipe(operators.takeUntil(this.destroy$)).subscribe(function () {
41473
41509
  _this.filterValue = _this._internalFilter = _this.comboInput.value;
41474
41510
  });
41511
+ // in reactive form the control is not present initially
41512
+ // and sets the selection to an invalid value in writeValue method
41513
+ if (!this.isValid(this.selectedItem)) {
41514
+ this.selectionService.clear(this.id);
41515
+ this._value = '';
41516
+ }
41475
41517
  _super.prototype.ngAfterViewInit.call(this);
41476
41518
  };
41477
41519
  /** @hidden @internal */
@@ -41483,7 +41525,7 @@
41483
41525
  if (this.collapsed && this.comboInput.focused) {
41484
41526
  this.open();
41485
41527
  }
41486
- if (!this.comboInput.value.trim() && this.selectionService.size(this.id) > 0) {
41528
+ if (!this.comboInput.value.trim() && this.selection.length) {
41487
41529
  // handle clearing of input by space
41488
41530
  this.clearSelection();
41489
41531
  this._onChangeCallback(null);
@@ -41518,6 +41560,7 @@
41518
41560
  }
41519
41561
  if (!this.collapsed && event.key === this.platformUtil.KEYMAP.TAB) {
41520
41562
  this.clearOnBlur();
41563
+ this.close();
41521
41564
  }
41522
41565
  this.composing = false;
41523
41566
  _super.prototype.handleKeyDown.call(this, event);
@@ -41549,6 +41592,15 @@
41549
41592
  this.comboInput.focus();
41550
41593
  };
41551
41594
  /** @hidden @internal */
41595
+ IgxSimpleComboComponent.prototype.onBlur = function () {
41596
+ // when clicking the toggle button to close the combo and immediately clicking outside of it
41597
+ // the collapsed state is not modified as the dropdown is still not closed
41598
+ if (this.collapsed || this._collapsing) {
41599
+ this.clearOnBlur();
41600
+ }
41601
+ _super.prototype.onBlur.call(this);
41602
+ };
41603
+ /** @hidden @internal */
41552
41604
  IgxSimpleComboComponent.prototype.onFocus = function () {
41553
41605
  this._internalFilter = this.comboInput.value || '';
41554
41606
  };
@@ -41622,17 +41674,12 @@
41622
41674
  owner: this,
41623
41675
  cancel: false
41624
41676
  };
41625
- // additional checks when selecting and clearing an item with valueKey=undefined
41626
- // as the event should emit when args.newSelection differs from args.oldSelection
41627
- // however in this case both args.newSelection and args.oldSelection are 'undefined'
41628
- if (args.newSelection !== args.oldSelection
41629
- || args.newSelection === undefined && (newSelection === null || newSelection === void 0 ? void 0 : newSelection.size) > 0
41630
- || args.oldSelection === undefined && oldSelectionAsArray.length > 0) {
41677
+ if (args.newSelection !== args.oldSelection) {
41631
41678
  this.selectionChanging.emit(args);
41632
41679
  }
41633
41680
  // TODO: refactor below code as it sets the selection and the display text
41634
41681
  if (!args.cancel) {
41635
- var argsSelection = (newSelection === null || newSelection === void 0 ? void 0 : newSelection.size) > 0
41682
+ var argsSelection = this.isValid(args.newSelection)
41636
41683
  ? args.newSelection
41637
41684
  : [];
41638
41685
  argsSelection = Array.isArray(argsSelection) ? argsSelection : [argsSelection];
@@ -41670,33 +41717,32 @@
41670
41717
  };
41671
41718
  IgxSimpleComboComponent.prototype.clearOnBlur = function () {
41672
41719
  var filtered = this.filteredData.find(this.findMatch);
41673
- if (filtered === undefined || filtered === null || this.getElementKey(filtered) !== this.selectedItem) {
41674
- this.clearAndClose();
41720
+ // selecting null in primitive data returns undefined as the search text is '', but the item is null
41721
+ if (filtered === undefined && this.selectedItem !== null || !this.selection.length) {
41722
+ this.clear();
41675
41723
  return;
41676
41724
  }
41677
41725
  };
41678
- IgxSimpleComboComponent.prototype.getElementKey = function (element) {
41679
- var elementVal = this.valueKey ? element[this.valueKey] : element;
41680
- return elementVal;
41681
- };
41682
41726
  IgxSimpleComboComponent.prototype.getElementVal = function (element) {
41683
41727
  var elementVal = this.displayKey ? element[this.displayKey] : element;
41684
41728
  return String(elementVal);
41685
41729
  };
41686
- IgxSimpleComboComponent.prototype.clearAndClose = function () {
41730
+ IgxSimpleComboComponent.prototype.clear = function () {
41687
41731
  this.clearSelection(true);
41688
41732
  this._internalFilter = '';
41689
41733
  this.searchValue = '';
41690
- if (!this.collapsed) {
41691
- this.close();
41692
- }
41734
+ };
41735
+ IgxSimpleComboComponent.prototype.isValid = function (value) {
41736
+ return this.required
41737
+ ? value !== null && value !== '' && value !== undefined
41738
+ : value !== undefined;
41693
41739
  };
41694
41740
  return IgxSimpleComboComponent;
41695
41741
  }(IgxComboBaseDirective));
41696
41742
  IgxSimpleComboComponent.decorators = [
41697
41743
  { type: i0.Component, args: [{
41698
41744
  selector: 'igx-simple-combo',
41699
- template: "<igx-input-group #inputGroup [displayDensity]=\"displayDensity\" [suppressInputAutofocus]=\"true\" [type]=\"type\">\n <ng-container ngProjectAs=\"[igxLabel]\">\n <ng-content select=\"[igxLabel]\"></ng-content>\n </ng-container>\n <ng-container ngProjectAs=\"igx-prefix\">\n <ng-content select=\"igx-prefix\"></ng-content>\n </ng-container>\n <ng-container ngProjectAs=\"igx-hint, [igxHint]\">\n <ng-content select=\"igx-hint, [igxHint]\"></ng-content>\n </ng-container>\n\n <input #comboInput igxInput [value]=\"value\" (focus)=\"onFocus()\" (input)=\"handleInputChange($event)\" (keyup)=\"handleKeyUp($event)\"\n (keydown)=\"handleKeyDown($event)\" (blur)=\"onBlur()\" [attr.placeholder]=\"placeholder\" aria-autocomplete=\"both\"\n [attr.aria-owns]=\"dropdown.id\" [attr.aria-labelledby]=\"ariaLabelledBy\" [disabled]=\"disabled\"\n [igxTextSelection]=\"!composing\" />\n\n <ng-container ngProjectAs=\"igx-suffix\">\n <ng-content select=\"igx-suffix\"></ng-content>\n </ng-container>\n <igx-suffix *ngIf=\"comboInput.value.length\" aria-label=\"Clear Selection\" class=\"igx-combo__clear-button\"\n (click)=\"handleClear($event)\">\n <ng-container *ngIf=\"clearIconTemplate\">\n <ng-container *ngTemplateOutlet=\"clearIconTemplate\"></ng-container>\n </ng-container>\n <igx-icon *ngIf=\"!clearIconTemplate\">\n clear\n </igx-icon>\n </igx-suffix>\n <igx-suffix *ngIf=\"showSearchCaseIcon\">\n <igx-icon family=\"imx-icons\" name=\"case-sensitive\" [active]=\"filteringOptions.caseSensitive\"\n (click)=\"toggleCaseSensitive()\">\n </igx-icon>\n </igx-suffix>\n <igx-suffix class=\"igx-combo__toggle-button\">\n <ng-container *ngIf=\"toggleIconTemplate\">\n <ng-container *ngTemplateOutlet=\"toggleIconTemplate; context: {$implicit: collapsed}\"></ng-container>\n </ng-container>\n <igx-icon (click)=\"onClick($event)\" *ngIf=\"!toggleIconTemplate\">\n {{ dropdown.collapsed ? 'arrow_drop_down' : 'arrow_drop_up'}}\n </igx-icon>\n </igx-suffix>\n</igx-input-group>\n\n<igx-combo-drop-down #igxComboDropDown class=\"igx-combo__drop-down\" [displayDensity]=\"displayDensity\"\n [width]=\"itemsWidth || '100%'\" (opening)=\"handleOpening($event)\" (closing)=\"handleClosing($event)\"\n (opened)=\"handleOpened()\" (closed)=\"handleClosed()\" [singleMode]=\"true\">\n <ng-container *ngTemplateOutlet=\"headerTemplate\">\n </ng-container>\n <div #dropdownItemContainer class=\"igx-combo__content\" [style.overflow]=\"'hidden'\"\n [style.maxHeight.px]=\"itemsMaxHeight\" [igxDropDownItemNavigation]=\"dropdown\" (focus)=\"dropdown.onFocus()\"\n [tabindex]=\"dropdown.collapsed ? -1 : 0\" role=\"listbox\" [attr.id]=\"dropdown.id\"\n (keydown)=\"handleItemKeyDown($event)\">\n <igx-combo-item role=\"option\" [singleMode]=\"true\" [itemHeight]='itemHeight' (click)=\"handleItemClick()\" *igxFor=\"let item of data\n | comboFiltering:filterValue:displayKey:filteringOptions:true\n | comboGrouping:groupKey:valueKey\n index as rowIndex; containerSize: itemsMaxHeight; scrollOrientation: 'vertical'; itemSize: itemHeight\"\n [value]=\"item\" [isHeader]=\"item.isHeader\" [index]=\"rowIndex\">\n <ng-container *ngIf=\"item.isHeader\">\n <ng-container\n *ngTemplateOutlet=\"headerItemTemplate ? headerItemTemplate : headerItemBase;\n context: {$implicit: item, data: data, valueKey: valueKey, groupKey: groupKey, displayKey: displayKey}\">\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!item.isHeader\">\n <ng-container #listItem\n *ngTemplateOutlet=\"template; context: {$implicit: item, data: data, valueKey: valueKey, displayKey: displayKey};\">\n </ng-container>\n </ng-container>\n </igx-combo-item>\n </div>\n\n <div class=\"igx-combo__add\" *ngIf=\"filteredData.length === 0 || isAddButtonVisible()\">\n <div class=\"igx-combo__empty\" *ngIf=\"filteredData.length === 0\">\n <ng-container *ngTemplateOutlet=\"emptyTemplate ? emptyTemplate : empty\">\n </ng-container>\n </div>\n <igx-combo-add-item #addItem [itemHeight]=\"itemHeight\" *ngIf=\"isAddButtonVisible()\"\n [tabindex]=\"dropdown.collapsed ? -1 : customValueFlag ? 1 : -1\" class=\"igx-combo__add-item\" role=\"button\"\n aria-label=\"Add Item\" [index]=\"virtualScrollContainer.igxForOf.length\">\n <ng-container *ngTemplateOutlet=\"addItemTemplate ? addItemTemplate : addItemDefault\">\n </ng-container>\n </igx-combo-add-item>\n </div>\n <ng-container *ngTemplateOutlet=\"footerTemplate\">\n </ng-container>\n</igx-combo-drop-down>\n\n<ng-template #complex let-display let-data=\"data\" let-key=\"displayKey\">\n {{display[key]}}\n</ng-template>\n<ng-template #primitive let-display>\n {{display}}\n</ng-template>\n<ng-template #empty>\n <span>{{resourceStrings.igx_combo_empty_message}}</span>\n</ng-template>\n<ng-template #addItemDefault let-control>\n <button igxButton=\"flat\" igxRipple>Add item</button>\n</ng-template>\n<ng-template #headerItemBase let-item let-key=\"valueKey\" let-groupKey=\"groupKey\">\n {{ item[key] }}\n</ng-template>\n",
41745
+ template: "<igx-input-group #inputGroup [displayDensity]=\"displayDensity\" [suppressInputAutofocus]=\"true\" [type]=\"type\">\n <ng-container ngProjectAs=\"[igxLabel]\">\n <ng-content select=\"[igxLabel]\"></ng-content>\n </ng-container>\n <ng-container ngProjectAs=\"igx-prefix\">\n <ng-content select=\"igx-prefix\"></ng-content>\n </ng-container>\n <ng-container ngProjectAs=\"igx-hint, [igxHint]\">\n <ng-content select=\"igx-hint, [igxHint]\"></ng-content>\n </ng-container>\n\n <input #comboInput igxInput [value]=\"value\" (focus)=\"onFocus()\" (input)=\"handleInputChange($event)\" (keyup)=\"handleKeyUp($event)\"\n (keydown)=\"handleKeyDown($event)\" (blur)=\"onBlur()\" [attr.placeholder]=\"placeholder\" aria-autocomplete=\"both\"\n [attr.aria-owns]=\"dropdown.id\" [attr.aria-labelledby]=\"ariaLabelledBy\" [disabled]=\"disabled\"\n [igxTextSelection]=\"!composing\" />\n\n <ng-container ngProjectAs=\"igx-suffix\">\n <ng-content select=\"igx-suffix\"></ng-content>\n </ng-container>\n <igx-suffix *ngIf=\"comboInput.value.length\" aria-label=\"Clear Selection\" class=\"igx-combo__clear-button\"\n (click)=\"handleClear($event)\">\n <ng-container *ngIf=\"clearIconTemplate\">\n <ng-container *ngTemplateOutlet=\"clearIconTemplate\"></ng-container>\n </ng-container>\n <igx-icon *ngIf=\"!clearIconTemplate\">\n clear\n </igx-icon>\n </igx-suffix>\n <igx-suffix *ngIf=\"showSearchCaseIcon\">\n <igx-icon family=\"imx-icons\" name=\"case-sensitive\" [active]=\"filteringOptions.caseSensitive\"\n (click)=\"toggleCaseSensitive()\">\n </igx-icon>\n </igx-suffix>\n <igx-suffix class=\"igx-combo__toggle-button\">\n <ng-container *ngIf=\"toggleIconTemplate\">\n <ng-container *ngTemplateOutlet=\"toggleIconTemplate; context: {$implicit: collapsed}\"></ng-container>\n </ng-container>\n <igx-icon (click)=\"onClick($event)\" *ngIf=\"!toggleIconTemplate\">\n {{ dropdown.collapsed ? 'arrow_drop_down' : 'arrow_drop_up'}}\n </igx-icon>\n </igx-suffix>\n</igx-input-group>\n\n<igx-combo-drop-down #igxComboDropDown class=\"igx-combo__drop-down\" [displayDensity]=\"displayDensity\"\n [width]=\"itemsWidth || '100%'\" (opening)=\"handleOpening($event)\" (closing)=\"handleClosing($event)\"\n (opened)=\"handleOpened()\" (closed)=\"handleClosed()\" [singleMode]=\"true\">\n <ng-container *ngTemplateOutlet=\"headerTemplate\">\n </ng-container>\n <div #dropdownItemContainer class=\"igx-combo__content\" [style.overflow]=\"'hidden'\"\n [style.maxHeight.px]=\"itemsMaxHeight\" [igxDropDownItemNavigation]=\"dropdown\" (focus)=\"dropdown.onFocus()\"\n [tabindex]=\"dropdown.collapsed ? -1 : 0\" role=\"listbox\" [attr.id]=\"dropdown.id\"\n (keydown)=\"handleItemKeyDown($event)\">\n <igx-combo-item role=\"option\" [singleMode]=\"true\" [itemHeight]='itemHeight' (click)=\"handleItemClick()\" *igxFor=\"let item of data\n | comboFiltering:filterValue:displayKey:filteringOptions:true\n | comboGrouping:groupKey:valueKey\n index as rowIndex; containerSize: itemsMaxHeight; scrollOrientation: 'vertical'; itemSize: itemHeight\"\n [value]=\"item\" [isHeader]=\"item?.isHeader\" [index]=\"rowIndex\">\n <ng-container *ngIf=\"item?.isHeader\">\n <ng-container\n *ngTemplateOutlet=\"headerItemTemplate ? headerItemTemplate : headerItemBase;\n context: {$implicit: item, data: data, valueKey: valueKey, groupKey: groupKey, displayKey: displayKey}\">\n </ng-container>\n </ng-container>\n <!-- if item is 'null' it should be displayed and !!(item?.isHeader) would resolve it to 'false' and not display it -->\n <ng-container *ngIf=\"!item?.isHeader\">\n <ng-container #listItem\n *ngTemplateOutlet=\"template; context: {$implicit: item, data: data, valueKey: valueKey, displayKey: displayKey};\">\n </ng-container>\n </ng-container>\n </igx-combo-item>\n </div>\n\n <div class=\"igx-combo__add\" *ngIf=\"filteredData.length === 0 || isAddButtonVisible()\">\n <div class=\"igx-combo__empty\" *ngIf=\"filteredData.length === 0\">\n <ng-container *ngTemplateOutlet=\"emptyTemplate ? emptyTemplate : empty\">\n </ng-container>\n </div>\n <igx-combo-add-item #addItem [itemHeight]=\"itemHeight\" *ngIf=\"isAddButtonVisible()\"\n [tabindex]=\"dropdown.collapsed ? -1 : customValueFlag ? 1 : -1\" class=\"igx-combo__add-item\" role=\"button\"\n aria-label=\"Add Item\" [index]=\"virtualScrollContainer.igxForOf.length\">\n <ng-container *ngTemplateOutlet=\"addItemTemplate ? addItemTemplate : addItemDefault\">\n </ng-container>\n </igx-combo-add-item>\n </div>\n <ng-container *ngTemplateOutlet=\"footerTemplate\">\n </ng-container>\n</igx-combo-drop-down>\n\n<ng-template #complex let-display let-data=\"data\" let-key=\"displayKey\">\n {{display[key]}}\n</ng-template>\n<ng-template #primitive let-display>\n {{display}}\n</ng-template>\n<ng-template #empty>\n <span>{{resourceStrings.igx_combo_empty_message}}</span>\n</ng-template>\n<ng-template #addItemDefault let-control>\n <button igxButton=\"flat\" igxRipple>Add item</button>\n</ng-template>\n<ng-template #headerItemBase let-item let-key=\"valueKey\" let-groupKey=\"groupKey\">\n {{ item[key] }}\n</ng-template>\n",
41700
41746
  providers: [
41701
41747
  IgxComboAPIService,
41702
41748
  { provide: IGX_COMBO_COMPONENT, useExisting: IgxSimpleComboComponent },