UNPKG

@catull/igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

1,443 lines 153 kB
import { __decorate, __extends, __metadata, __param, __read, __spread, __values } from "tslib"; import { ConnectedPositioningStrategy } from './../services/overlay/position/connected-positioning-strategy'; import { CommonModule } from '@angular/common'; import { AfterViewInit, ChangeDetectorRef, Component, ContentChild, ElementRef, EventEmitter, HostBinding, HostListener, Input, NgModule, OnInit, OnDestroy, Output, TemplateRef, ViewChild, Optional, Inject, Injector, Type } from '@angular/core'; import { IgxComboItemDirective, IgxComboEmptyDirective, IgxComboHeaderItemDirective, IgxComboHeaderDirective, IgxComboFooterDirective, IgxComboAddItemDirective, IgxComboToggleIconDirective, IgxComboClearIconDirective } from './combo.directives'; import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR, NgControl } from '@angular/forms'; import { IgxCheckboxModule } from '../checkbox/checkbox.component'; import { IgxSelectionAPIService } from '../core/selection'; import { cloneArray } from '../core/utils'; import { IgxStringFilteringOperand, IgxBooleanFilteringOperand } from '../data-operations/filtering-condition'; import { FilteringLogic } from '../data-operations/filtering-expression.interface'; import { IgxForOfModule, IgxForOfDirective } from '../directives/for-of/for_of.directive'; import { IgxIconModule } from '../icon/index'; import { IgxRippleModule } from '../directives/ripple/ripple.directive'; import { IgxToggleModule } from '../directives/toggle/toggle.directive'; import { IgxButtonModule } from '../directives/button/button.directive'; import { IgxDropDownModule } from '../drop-down/index'; import { IgxInputGroupModule, IgxInputGroupComponent } from '../input-group/input-group.component'; import { IgxComboItemComponent } from './combo-item.component'; import { IgxComboDropDownComponent } from './combo-dropdown.component'; import { IgxComboFilteringPipe, IgxComboGroupingPipe } from './combo.pipes'; import { AbsoluteScrollStrategy } from '../services'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { DisplayDensityBase, DisplayDensityToken } from '../core/density'; import { IGX_COMBO_COMPONENT } from './combo.common'; import { IgxComboAddItemComponent } from './combo-add-item.component'; import { IgxComboAPIService } from './combo.api'; import { IgxInputState, IgxInputDirective } from '../directives/input/input.directive'; /** * @hidden */ var DataTypes; (function (DataTypes) { DataTypes["EMPTY"] = "empty"; DataTypes["PRIMITIVE"] = "primitive"; DataTypes["COMPLEX"] = "complex"; DataTypes["PRIMARYKEY"] = "valueKey"; })(DataTypes || (DataTypes = {})); /** * @hidden */ var ItemHeights = { 'comfortable': 40, 'cosy': 32, 'compact': 28, }; /** * @hidden * The default number of items that should be in the combo's * drop-down list if no `[itemsMaxHeight]` is specified */ var itemsInContainer = 10; export var IgxComboState; (function (IgxComboState) { /** * Combo with initial state. */ IgxComboState[IgxComboState["INITIAL"] = 0] = "INITIAL"; /** * Combo with valid state. */ IgxComboState[IgxComboState["VALID"] = 1] = "VALID"; /** * Combo with invalid state. */ IgxComboState[IgxComboState["INVALID"] = 2] = "INVALID"; })(IgxComboState || (IgxComboState = {})); /** * When called with sets A & B, returns A - B (as array); * @hidden */ function diffInSets(set1, set2) { var results = []; set1.forEach(function (entry) { if (!set2.has(entry)) { results.push(entry); } }); return results; } var NEXT_ID = 0; var noop = function () { }; var ɵ0 = noop; var IgxComboComponent = /** @class */ (function (_super) { __extends(IgxComboComponent, _super); function IgxComboComponent(elementRef, cdr, selection, comboAPI, _displayDensityOptions, _injector) { var _this = _super.call(this, _displayDensityOptions) || this; _this.elementRef = elementRef; _this.cdr = cdr; _this.selection = selection; _this.comboAPI = comboAPI; _this._displayDensityOptions = _displayDensityOptions; _this._injector = _injector; /** * @hidden @internal */ _this.customValueFlag = true; /** * @hidden @internal */ _this.defaultFallbackGroup = 'Other'; _this.stringFilters = IgxStringFilteringOperand; _this.booleanFilters = IgxBooleanFilteringOperand; _this._groupKey = ''; _this._prevInputValue = ''; _this._dataType = ''; _this.ngControl = null; _this.destroy$ = new Subject(); _this._data = []; _this._filteredData = []; _this._itemHeight = null; _this._itemsMaxHeight = null; _this._remoteSelection = {}; _this._onChangeCallback = noop; _this._overlaySettings = { scrollStrategy: new AbsoluteScrollStrategy(), positionStrategy: new ConnectedPositioningStrategy(), modal: false, closeOnOutsideClick: true, excludePositionTarget: true }; _this._value = ''; _this._valid = IgxComboState.INITIAL; /** * Set custom overlay settings that control how the combo's list of items is displayed. * Set: * ```html * <igx-combo [overlaySettings] = "customOverlaySettings"></igx-combo> * ``` * * ```typescript * const customSettings = { positionStrategy: { settings: { target: myTarget } } }; * combo.overlaySettings = customSettings; * ``` * Get any custom overlay settings used by the combo: * ```typescript * const comboOverlaySettings: OverlaySettings = myCombo.overlaySettings; * ``` */ _this.overlaySettings = null; /** * @hidden @internal */ _this.searchInput = null; /** * The custom template, if any, that should be used when rendering ITEMS in the combo list * * ```typescript * // Set in typescript * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate; * myComponent.combo.itemTemplate = myCustomTemplate; * ``` * ```html * <!-- Set in markup --> * <igx-combo #combo> * ... * <ng-template igxComboItem> * <div class="custom-item" let-item let-key="valueKey"> * <div class="custom-item__name">{{ item[key] }}</div> * <div class="custom-item__cost">{{ item.cost }}</div> * </div> * </ng-template> * </igx-combo> * ``` */ _this.itemTemplate = null; /** * The custom template, if any, that should be used when rendering the HEADER for the combo items list * * ```typescript * // Set in typescript * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate; * myComponent.combo.headerTemplate = myCustomTemplate; * ``` * ```html * <!-- Set in markup --> * <igx-combo #combo> * ... * <ng-template igxComboHeader> * <div class="combo__header"> * This is a custom header * </div> * </ng-template> * </igx-combo> * ``` */ _this.headerTemplate = null; /** * The custom template, if any, that should be used when rendering the FOOTER for the combo items list * * ```typescript * // Set in typescript * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate; * myComponent.combo.footerTemplate = myCustomTemplate; * ``` * ```html * <!-- Set in markup --> * <igx-combo #combo> * ... * <ng-template igxComboFooter> * <div class="combo__footer"> * This is a custom footer * </div> * </ng-template> * </igx-combo> * ``` */ _this.footerTemplate = null; /** * The custom template, if any, that should be used when rendering HEADER ITEMS for groups in the combo list * * ```typescript * // Set in typescript * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate; * myComponent.combo.headerItemTemplate = myCustomTemplate; * ``` * ```html * <!-- Set in markup --> * <igx-combo #combo> * ... * <ng-template igxComboHeaderItem let-item let-key="groupKey"> * <div class="custom-item--group">Group header for {{ item[key] }}</div> * </ng-template> * </igx-combo> * ``` */ _this.headerItemTemplate = null; /** * The custom template, if any, that should be used when rendering the ADD BUTTON in the combo drop down * * ```typescript * // Set in typescript * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate; * myComponent.combo.addItemTemplate = myCustomTemplate; * ``` * ```html * <!-- Set in markup --> * <igx-combo #combo> * ... * <ng-template igxComboAddItem> * <button class="combo__add-button"> * Click to add item * </button> * </ng-template> * </igx-combo> * ``` */ _this.addItemTemplate = null; /** * The custom template, if any, that should be used when rendering the ADD BUTTON in the combo drop down * * ```typescript * // Set in typescript * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate; * myComponent.combo.emptyTemplate = myCustomTemplate; * ``` * ```html * <!-- Set in markup --> * <igx-combo #combo> * ... * <ng-template igxComboEmpty> * <div class="combo--empty"> * There are no items to display * </div> * </ng-template> * </igx-combo> * ``` */ _this.emptyTemplate = null; /** * The custom template, if any, that should be used when rendering the combo TOGGLE(open/close) button * * ```typescript * // Set in typescript * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate; * myComponent.combo.toggleIconTemplate = myCustomTemplate; * ``` * ```html * <!-- Set in markup --> * <igx-combo #combo> * ... * <ng-template igxComboToggleIcon let-collapsed> * <igx-icon>{{ collapsed ? 'remove_circle' : 'remove_circle_outline'}}</igx-icon> * </ng-template> * </igx-combo> * ``` */ _this.toggleIconTemplate = null; /** * The custom template, if any, that should be used when rendering the combo CLEAR button * * ```typescript * // Set in typescript * const myCustomTemplate: TemplateRef<any> = myComponent.customTemplate; * myComponent.combo.clearIconTemplate = myCustomTemplate; * ``` * ```html * <!-- Set in markup --> * <igx-combo #combo> * ... * <ng-template igxComboClearIcon> * <igx-icon>clear</igx-icon> * </ng-template> * </igx-combo> * ``` */ _this.clearIconTemplate = null; _this.dropdownContainer = null; /** * Emitted when item selection is changing, before the selection completes * * ```html * <igx-combo (onSelectionChange)='handleSelection()'></igx-combo> * ``` */ _this.onSelectionChange = new EventEmitter(); /** * Emitted before the dropdown is opened * * ```html * <igx-combo onOpening='handleOpening($event)'></igx-combo> * ``` */ _this.onOpening = new EventEmitter(); /** * Emitted after the dropdown is opened * * ```html * <igx-combo (onOpened)='handleOpened()'></igx-combo> * ``` */ _this.onOpened = new EventEmitter(); /** * Emitted before the dropdown is closed * * ```html * <igx-combo (onClosing)='handleClosing($event)'></igx-combo> * ``` */ _this.onClosing = new EventEmitter(); /** * Emitted after the dropdown is closed * * ```html * <igx-combo (onClosed)='handleClosed()'></igx-combo> * ``` */ _this.onClosed = new EventEmitter(); /** * Emitted when an item is being added to the data collection * * ```html * <igx-combo (onAddition)='handleAdditionEvent()'></igx-combo> * ``` */ _this.onAddition = new EventEmitter(); /** * Emitted when the value of the search input changes (e.g. typing, pasting, clear, etc.) * * ```html * <igx-combo (onSearchInput)='handleSearchInputEvent()'></igx-combo> * ``` */ _this.onSearchInput = new EventEmitter(); /** * Emitted when new chunk of data is loaded from the virtualization * * ```html * <igx-combo (onDataPreLoad)='handleDataPreloadEvent()'></igx-combo> * ``` */ _this.onDataPreLoad = new EventEmitter(); /** * Gets/gets combo id. * * ```typescript * // get * let id = this.combo.id; * ``` * * ```html * <!--set--> * <igx-combo [id]='combo1'></igx-combo> * ``` */ _this.id = "igx-combo-" + NEXT_ID++; /** * @hidden @internal */ _this.cssClass = 'igx-combo'; // Independent of display density, at the time being /** * @hidden @internal */ _this.role = 'combobox'; /** * Controls whether custom values can be added to the collection * * ```typescript * // get * let comboAllowsCustomValues = this.combo.allowCustomValues; * ``` * * ```html * <!--set--> * <igx-combo [allowCustomValues]='true'></igx-combo> * ``` */ _this.allowCustomValues = false; /** * @hidden @internal */ _this.filteringLogic = FilteringLogic.Or; /** * Defines the placeholder value for the combo dropdown search field * * ```typescript * // get * let myComboSearchPlaceholder = this.combo.searchPlaceholder; * ``` * * ```html * <!--set--> * <igx-combo [searchPlaceholder]='newPlaceHolder'></igx-combo> * ``` */ _this.searchPlaceholder = 'Enter a Search Term'; /** * Combo value data source property. * * ```typescript * // get * let myComboValueKey = this.combo.valueKey; * ``` * * ```html * <!--set--> * <igx-combo [valueKey]='myKey'></igx-combo> * ``` */ _this.valueKey = null; /** * An @Input property that enabled/disables filtering in the list. The default is `true`. * ```html *<igx-combo [filterable]="false"> * ``` */ _this.filterable = true; /** * An @Input property that enabled/disables combo. The default is `false`. * ```html *<igx-combo [disabled]="'true'"> * ``` */ _this.disabled = false; /** * An @Input property that sets how the combo will be styled. * The allowed values are `line`, `box`, `border` and `search`. The default is `box`. * ```html *<igx-combo [type]="'line'"> * ``` */ _this.type = 'box'; /** * @hidden @internal */ _this.searchValue = ''; _this.onStatusChanged = function () { if ((_this.ngControl.control.touched || _this.ngControl.control.dirty) && (_this.ngControl.control.validator || _this.ngControl.control.asyncValidator)) { _this.valid = _this.ngControl.valid ? IgxComboState.VALID : IgxComboState.INVALID; } _this.manageRequiredAsterisk(); }; _this.comboAPI.register(_this); return _this; } IgxComboComponent_1 = IgxComboComponent; Object.defineProperty(IgxComboComponent.prototype, "displaySearchInput", { /** * @hidden @internal */ get: function () { return this.filterable || this.allowCustomValues; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "ariaExpanded", { /** * @hidden @internal */ get: function () { return !this.dropdown.collapsed; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "hasPopUp", { /** * @hidden @internal */ get: function () { return 'listbox'; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "ariaOwns", { /** * @hidden @internal */ get: function () { return this.dropdown.id; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "itemsMaxHeight", { /** * Configures the drop down list height * * ```typescript * // get * let myComboItemsMaxHeight = this.combo.itemsMaxHeight; * ``` * * ```html * <!--set--> * <igx-combo [itemsMaxHeight]='320'></igx-combo> * ``` */ get: function () { if (this._itemsMaxHeight === null || this._itemsMaxHeight === undefined) { return this.itemHeight * itemsInContainer; } return this._itemsMaxHeight; }, set: function (val) { this._itemsMaxHeight = val; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "itemHeight", { /** * Configures the drop down list item height * * ```typescript * // get * let myComboItemHeight = this.combo.itemHeight; * ``` * * ```html * <!--set--> * <igx-combo [itemHeight]='32'></igx-combo> * ``` */ get: function () { if (this._itemHeight === null || this._itemHeight === undefined) { return ItemHeights[this.displayDensity]; } return this._itemHeight; }, set: function (val) { this._itemHeight = val; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "inputEmpty", { /** * @hidden @internal */ get: function () { return !this.value && !this.placeholder; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "data", { /** * Combo data source. * * ```html * <!--set--> * <igx-combo [data]='items'></igx-combo> * ``` */ get: function () { return this._data; }, set: function (val) { this._data = (val) ? val : []; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "displayKey", { /** * Combo text data source property. * * ```typescript * // get * let myComboDisplayKey = this.combo.displayKey; * * // set * this.combo.displayKey = 'val'; * * ``` * * ```html * <!--set--> * <igx-combo [displayKey]='myDisplayKey'></igx-combo> * ``` */ get: function () { return this._displayKey ? this._displayKey : this.valueKey; }, set: function (val) { this._displayKey = val; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "groupKey", { /** * The item property by which items should be grouped inside the items list. Not usable if data is not of type Object[]. * * ```typescript * // get * let currentGroupKey = this.combo.groupKey; * ``` */ get: function () { return this._groupKey; }, /** * The item property by which items should be grouped inside the items list. Not usable if data is not of type Object[]. * * ```html * <!--set--> * <igx-combo [groupKey]='newGroupKey'></igx-combo> * ``` */ set: function (val) { this._groupKey = val; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "valid", { /** * Gets if control is valid, when used in a form * * ```typescript * // get * let valid = this.combo.valid; * ``` * */ get: function () { return this._valid; }, /** * Sets if control is valid, when used in a form * * ```typescript * // set * this.combo.valid = IgxComboState.INVALID; * ``` */ set: function (valid) { this._valid = valid; this.comboInput.valid = IgxInputState[IgxComboState[valid]]; }, enumerable: true, configurable: true }); /** * @hidden @internal */ IgxComboComponent.prototype.onArrowDown = function (event) { event.preventDefault(); event.stopPropagation(); this.open(); }; /** * @hidden @internal */ IgxComboComponent.prototype.onInputClick = function (event) { event.stopPropagation(); event.preventDefault(); this.toggle(); }; Object.defineProperty(IgxComboComponent.prototype, "virtualizationState", { /** * Defines the current state of the virtualized data. It contains `startIndex` and `chunkSize` * * ```typescript * // get * let state = this.combo.virtualizationState; * ``` */ get: function () { return this.virtDir.state; }, /** * Sets the current state of the virtualized data. * * ```typescript * // set * this.combo.virtualizationState(state); * ``` */ set: function (state) { this.virtDir.state = state; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "totalItemCount", { /** * Gets total count of the virtual data items, when using remote service. * * ```typescript * // get * let count = this.combo.totalItemCount; * ``` */ get: function () { return this.virtDir.totalItemCount; }, /** * Sets total count of the virtual data items, when using remote service. * * ```typescript * // set * this.combo.totalItemCount(remoteService.count); * ``` */ set: function (count) { this.virtDir.totalItemCount = count; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "value", { /** * The text displayed in the combo input * * ```typescript * // get * let comboValue = this.combo.value; * ``` */ get: function () { return this._value; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "filteredData", { /** * @hidden @internal */ get: function () { return this.filterable ? this._filteredData : this.data; }, /** * @hidden @internal */ set: function (val) { this._filteredData = this.groupKey ? (val || []).filter(function (e) { return e.isHeader !== true; }) : val; this.checkMatch(); }, enumerable: true, configurable: true }); /** * @hidden @internal */ IgxComboComponent.prototype.handleKeyUp = function (event) { if (event.key === 'ArrowDown' || event.key === 'Down') { this.dropdown.focusedItem = this.dropdown.items[0]; this.dropdownContainer.nativeElement.focus(); } else if (event.key === 'Escape' || event.key === 'Esc') { this.toggle(); } }; /** * @hidden @internal */ IgxComboComponent.prototype.handleKeyDown = function (event) { if (event.key === 'ArrowUp' || event.key === 'Up') { event.preventDefault(); event.stopPropagation(); this.close(); } }; IgxComboComponent.prototype.checkMatch = function () { var _this = this; var displayKey = this.displayKey; var matchFn = function (e) { var value = displayKey ? e[displayKey] : e; return value.toString().toLowerCase() === _this.searchValue.trim().toLowerCase(); }; var itemMatch = this.filteredData.some(matchFn); this.customValueFlag = this.allowCustomValues && !itemMatch; }; /** * @hidden @internal */ IgxComboComponent.prototype.handleInputChange = function (event) { if (event !== undefined) { this.onSearchInput.emit(event); } this.checkMatch(); }; Object.defineProperty(IgxComboComponent.prototype, "dataType", { /** * @hidden @internal */ get: function () { if (this.displayKey) { return DataTypes.COMPLEX; } return DataTypes.PRIMITIVE; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "isRemote", { /** * @hidden @internal */ get: function () { return this.totalItemCount > 0 && this.valueKey && this.dataType === DataTypes.COMPLEX; }, enumerable: true, configurable: true }); /** Contains key-value pairs of the selected valueKeys and their resp. displayKeys */ IgxComboComponent.prototype.registerRemoteEntries = function (ids, add) { var e_1, _a, e_2, _b; if (add === void 0) { add = true; } if (add) { var selection = this.getValueDisplayPairs(ids); try { for (var selection_1 = __values(selection), selection_1_1 = selection_1.next(); !selection_1_1.done; selection_1_1 = selection_1.next()) { var entry = selection_1_1.value; this._remoteSelection[entry[this.valueKey]] = entry[this.displayKey]; } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (selection_1_1 && !selection_1_1.done && (_a = selection_1.return)) _a.call(selection_1); } finally { if (e_1) throw e_1.error; } } } else { try { for (var ids_1 = __values(ids), ids_1_1 = ids_1.next(); !ids_1_1.done; ids_1_1 = ids_1.next()) { var entry = ids_1_1.value; delete this._remoteSelection[entry]; } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (ids_1_1 && !ids_1_1.done && (_b = ids_1.return)) _b.call(ids_1); } finally { if (e_2) throw e_2.error; } } } }; /** For `id: any[]` returns a mapped `{ [combo.valueKey]: any, [combo.displayKey]: any }[]`*/ IgxComboComponent.prototype.getValueDisplayPairs = function (ids) { var _this = this; return this.data.filter(function (entry) { return ids.indexOf(entry[_this.valueKey]) > -1; }).map(function (e) { var _a; return _a = {}, _a[_this.valueKey] = e[_this.valueKey], _a[_this.displayKey] = e[_this.displayKey], _a; }); }; /** * Returns if the specified itemID is selected * @hidden * @internal */ IgxComboComponent.prototype.isItemSelected = function (item) { return this.selection.is_item_selected(this.id, item); }; /** * Triggers change detection on the combo view */ IgxComboComponent.prototype.triggerCheck = function () { this.cdr.detectChanges(); }; /** * @hidden @internal */ IgxComboComponent.prototype.isAddButtonVisible = function () { // This should always return a boolean value. If this.searchValue was '', it returns '' instead of false; return this.searchValue !== '' && this.customValueFlag; }; /** * @hidden @internal */ IgxComboComponent.prototype.handleSelectAll = function (evt) { if (evt.checked) { this.selectAllItems(); } else { this.deselectAllItems(); } }; /** * @hidden @internal */ IgxComboComponent.prototype.addItemToCollection = function () { var _a, _b; if (!this.searchValue) { return; } var newValue = this.searchValue.trim(); var addedItem = this.displayKey ? (_a = {}, _a[this.valueKey] = newValue, _a[this.displayKey] = newValue, _a) : newValue; if (this.groupKey) { Object.assign(addedItem, (_b = {}, _b[this.groupKey] = this.defaultFallbackGroup, _b)); } var oldCollection = this.data; var newCollection = __spread(this.data); newCollection.push(addedItem); var args = { oldCollection: oldCollection, addedItem: addedItem, newCollection: newCollection }; this.onAddition.emit(args); this.data.push(addedItem); // If you mutate the array, no pipe is invoked and the display isn't updated; // if you replace the array, the pipe executes and the display is updated. this.data = cloneArray(this.data); this.selectItems(this.comboAPI.valueKey !== null ? [addedItem[this.valueKey]] : [addedItem], false); this.customValueFlag = false; this.searchInput.nativeElement.focus(); this.dropdown.focusedItem = null; this.virtDir.scrollTo(0); }; /** * @hidden @internal */ IgxComboComponent.prototype.focusSearchInput = function (opening) { if (this.displaySearchInput && this.searchInput) { this.searchInput.nativeElement.focus(); } else { if (opening) { this.dropdownContainer.nativeElement.focus(); } else { this.comboInput.nativeElement.focus(); this.toggle(); } } }; IgxComboComponent.prototype.manageRequiredAsterisk = function () { if (this.ngControl && this.ngControl.control.validator) { // Run the validation with empty object to check if required is enabled. var error = this.ngControl.control.validator({}); this.inputGroup.isRequired = error && error.required; } }; /** * @hidden @internal */ IgxComboComponent.prototype.onBlur = function () { if (this.collapsed) { if (this.ngControl && !this.ngControl.valid) { this.valid = IgxComboState.INVALID; } else { this.valid = IgxComboState.INITIAL; } } }; /** * @hidden @internal */ IgxComboComponent.prototype.ngOnInit = function () { this.ngControl = this._injector.get(NgControl, null); this._overlaySettings.positionStrategy.settings.target = this.elementRef.nativeElement; this.selection.set(this.id, new Set()); }; /** * @hidden @internal */ IgxComboComponent.prototype.ngAfterViewInit = function () { var _this = this; this.filteredData = __spread(this.data); if (this.ngControl) { this.ngControl.statusChanges.pipe(takeUntil(this.destroy$)).subscribe(this.onStatusChanged); this.manageRequiredAsterisk(); this.cdr.detectChanges(); } this.virtDir.onChunkPreload.pipe(takeUntil(this.destroy$)).subscribe(function (e) { _this.onDataPreLoad.emit(e); }); }; /** * @hidden @internal */ IgxComboComponent.prototype.ngOnDestroy = function () { this.destroy$.next(); this.destroy$.complete(); this.comboAPI.clear(); this.selection.clear(this.id); }; /** * @hidden @internal */ IgxComboComponent.prototype.writeValue = function (value) { this.selectItems(value, true); this.cdr.markForCheck(); }; /** * @hidden @internal */ IgxComboComponent.prototype.registerOnChange = function (fn) { this._onChangeCallback = fn; }; /** * @hidden @internal */ IgxComboComponent.prototype.registerOnTouched = function (fn) { }; /** * @hidden @internal */ IgxComboComponent.prototype.setDisabledState = function (isDisabled) { this.disabled = isDisabled; }; /** * @hidden */ IgxComboComponent.prototype.getEditElement = function () { return this.comboInput.nativeElement; }; Object.defineProperty(IgxComboComponent.prototype, "template", { /** * @hidden @internal */ get: function () { this._dataType = this.dataType; if (this.itemTemplate) { return this.itemTemplate; } if (this._dataType === DataTypes.COMPLEX) { return this.complexTemplate; } return this.primitiveTemplate; }, enumerable: true, configurable: true }); Object.defineProperty(IgxComboComponent.prototype, "context", { /** * @hidden @internal */ get: function () { return { $implicit: this }; }, enumerable: true, configurable: true }); /** * @hidden @internal */ IgxComboComponent.prototype.handleClearItems = function (event) { this.deselectAllItems(true, event); event.stopPropagation(); }; /** * A method that opens/closes the combo. * *```html *<button (click)="combo.toggle()">Toggle Combo</button> *<igx-combo #combo></igx-combo> *``` */ IgxComboComponent.prototype.toggle = function () { var overlaySettings = Object.assign({}, this._overlaySettings, this.overlaySettings); this.dropdown.toggle(overlaySettings); }; /** * A method that opens the combo. * *```html *<button (click)="combo.open()">Open Combo</button> *<igx-combo #combo></igx-combo> *``` */ IgxComboComponent.prototype.open = function () { var overlaySettings = Object.assign({}, this._overlaySettings, this.overlaySettings); this.dropdown.open(overlaySettings); }; /** * A method that closes the combo. * *```html *<button (click)="combo.close()">Close Combo</button> *<igx-combo #combo></igx-combo> *``` */ IgxComboComponent.prototype.close = function () { this.dropdown.close(); }; Object.defineProperty(IgxComboComponent.prototype, "collapsed", { /** * Gets drop down state. * * ```typescript * let state = this.combo.collapsed; * ``` */ get: function () { return this.dropdown.collapsed; }, enumerable: true, configurable: true }); /** * Get current selection state * @returns Array of selected items * ```typescript * let selectedItems = this.combo.selectedItems(); * ``` */ IgxComboComponent.prototype.selectedItems = function () { var items = Array.from(this.selection.get(this.id)); return items; }; /** * Select defined items * @param newItems new items to be selected * @param clearCurrentSelection if true clear previous selected items * ```typescript * this.combo.selectItems(["New York", "New Jersey"]); * ``` */ IgxComboComponent.prototype.selectItems = function (newItems, clearCurrentSelection, event) { if (newItems) { var newSelection = this.selection.add_items(this.id, newItems, clearCurrentSelection); this.setSelection(newSelection, event); } }; /** * Deselect defined items * @param items items to deselected * ```typescript * this.combo.deselectItems(["New York", "New Jersey"]); * ``` */ IgxComboComponent.prototype.deselectItems = function (items, event) { if (items) { var newSelection = this.selection.delete_items(this.id, items); this.setSelection(newSelection, event); } }; /** * Select all (filtered) items * @param ignoreFilter if set to true, selects all items, otherwise selects only the filtered ones. * ```typescript * this.combo.selectAllItems(); * ``` */ IgxComboComponent.prototype.selectAllItems = function (ignoreFilter, event) { var allVisible = this.selection.get_all_ids(ignoreFilter ? this.data : this.filteredData, this.valueKey); var newSelection = this.selection.add_items(this.id, allVisible); this.setSelection(newSelection, event); }; /** * Deselect all (filtered) items * @param ignoreFilter if set to true, deselects all items, otherwise deselects only the filtered ones. * ```typescript * this.combo.deselectAllItems(); * ``` */ IgxComboComponent.prototype.deselectAllItems = function (ignoreFilter, event) { var newSelection = this.selection.get_empty(); if (this.filteredData.length !== this.data.length && !ignoreFilter) { newSelection = this.selection.delete_items(this.id, this.selection.get_all_ids(this.filteredData, this.valueKey)); } this.setSelection(newSelection, event); }; /** * Selects/Deselects a single item * @param itemID the itemID of the specific item * @param select If the item should be selected (true) or deselected (false) * * Without specified valueKey; * ```typescript * this.combo.valueKey = null; * const items: { field: string, region: string}[] = data; * this.combo.setSelectedItem(items[0], true); * ``` * With specified valueKey; * ```typescript * this.combo.valueKey = 'field'; * const items: { field: string, region: string}[] = data; * this.combo.setSelectedItem('Connecticut', true); * ``` */ IgxComboComponent.prototype.setSelectedItem = function (itemID, select, event) { if (select === void 0) { select = true; } if (itemID === null || itemID === undefined) { return; } if (select) { this.selectItems([itemID], false, event); } else { this.deselectItems([itemID], event); } }; IgxComboComponent.prototype.setSelection = function (newSelection, event) { var _this = this; var removed = diffInSets(this.selection.get(this.id), newSelection); var added = diffInSets(newSelection, this.selection.get(this.id)); var args = { newSelection: Array.from(newSelection), oldSelection: Array.from(this.selection.get(this.id) || []), added: added, removed: removed, event: event, cancel: false }; this.onSelectionChange.emit(args); if (!args.cancel) { this.selection.select_items(this.id, args.newSelection, true); var value = ''; if (this.isRemote) { if (args.newSelection.length) { var removedItems = args.oldSelection.filter(function (e) { return args.newSelection.indexOf(e) < 0; }); var addedItems = args.newSelection.filter(function (e) { return args.oldSelection.indexOf(e) < 0; }); this.registerRemoteEntries(addedItems); this.registerRemoteEntries(removedItems, false); value = Object.keys(this._remoteSelection).map(function (e) { return _this._remoteSelection[e]; }).join(', '); } else { // If new selection is empty, clear all items this.registerRemoteEntries(args.oldSelection, false); } } else { value = this.displayKey !== null && this.displayKey !== undefined ? this.convertKeysToItems(args.newSelection).map(function (entry) { return entry[_this.displayKey]; }).join(', ') : args.newSelection.join(', '); } this._value = value; this._onChangeCallback(args.newSelection); } }; /** if there is a valueKey - map the keys to data items, else - just return the keys */ IgxComboComponent.prototype.convertKeysToItems = function (keys) { var _this = this; if (this.comboAPI.valueKey === null) { return keys; } // map keys vs. filter data to retain the order of the selected items return keys.map(function (key) { return _this.data.find(function (entry) { return entry[_this.valueKey] === key; }); }).filter(function (e) { return e !== undefined; }); }; /** * Event handlers * @hidden * @internal */ IgxComboComponent.prototype.handleOpening = function (event) { this.onOpening.emit(event); if (event.cancel) { return; } }; /** * @hidden @internal */ IgxComboComponent.prototype.handleOpened = function () { this.triggerCheck(); this.focusSearchInput(true); this.onOpened.emit(); }; /** * @hidden @internal */ IgxComboComponent.prototype.handleClosing = function (event) { this.onClosing.emit(event); if (event.cancel) { return; } this.searchValue = ''; this.comboInput.nativeElement.focus(); }; /** * @hidden @internal */ IgxComboComponent.prototype.handleClosed = function () { this.onClosed.emit(); }; var IgxComboComponent_1; IgxComboComponent.ctorParameters = function () { return [ { type: ElementRef }, { type: ChangeDetectorRef }, { type: IgxSelectionAPIService }, { type: IgxComboAPIService }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DisplayDensityToken,] }] }, { type: Injector, decorators: [{ type: Optional }] } ]; }; __decorate([ ViewChild(IgxForOfDirective, { read: IgxForOfDirective, static: true }), __metadata("design:type", IgxForOfDirective) ], IgxComboComponent.prototype, "virtDir", void 0); __decorate([ Input(), __metadata("design:type", Object) ], IgxComboComponent.prototype, "overlaySettings", void 0); __decorate([ ViewChild('inputGroup', { read: IgxInputGroupComponent, static: true }), __metadata("design:type", IgxInputGroupComponent) ], IgxComboComponent.prototype, "inputGroup", void 0); __decorate([ ViewChild('comboInput', { read: IgxInputDirective, static: true }), __metadata("design:type", IgxInputDirective) ], IgxComboComponent.prototype, "comboInput", void 0); __decorate([ ViewChild(IgxComboDropDownComponent, { read: IgxComboDropDownComponent, static: true }), __metadata("design:type", IgxComboDropDownComponent) ], IgxComboComponent.prototype, "dropdown", void 0); __decorate([ ViewChild('searchInput'), __metadata("design:type", ElementRef) ], IgxComboComponent.prototype, "searchInput", void 0); __decorate([ ContentChild(IgxComboItemDirective, { read: TemplateRef }), __metadata("design:type", TemplateRef) ], IgxComboComponent.prototype, "itemTemplate", void 0); __decorate([ ContentChild(IgxComboHeaderDirective, { read: TemplateRef }), __metadata("design:type", TemplateRef) ], IgxComboComponent.prototype, "headerTemplate", void 0); __decorate([ ContentChild(IgxComboFooterDirective, { read: TemplateRef }), __metadata("design:type", TemplateRef) ], IgxComboComponent.prototype, "footerTemplate", void 0); __decorate([ ContentChild(IgxComboHeaderItemDirective, { read: TemplateRef }), __metadata("design:type", TemplateRef) ], IgxComboComponent.prototype, "headerItemTemplate", void 0); __decorate([ ContentChild(IgxComboAddItemDirective, { read: TemplateRef }), __metadata("design:type", TemplateRef) ], IgxComboComponent.prototype, "addItemTemplate", void 0); __decorate([ ContentChild(IgxComboEmptyDirective, { read: TemplateRef }), __metadata("design:type", TemplateRef) ], IgxComboComponent.prototype, "emptyTemplate", void 0); __decorate([ ContentChild(IgxComboToggleIconDirective, { read: TemplateRef }), __metadata("design:type", TemplateRef) ], IgxComboComponent.prototype, "toggleIconTemplate", void 0); __decorate([ ContentChild(IgxComboClearIconDirective, { read: TemplateRef }), __metadata("design:type", TemplateRef) ], IgxComboComponent.prototype, "clearIconTemplate", void 0); __decorate([ ViewChild('primitive', { read: TemplateRef, static: true }), __metadata("design:type", TemplateRef) ], IgxComboComponent.prototype, "primitiveTemplate", void 0); __decorate([ ViewChild('complex', { read: TemplateRef, static: true }), __metadata("design:type", TemplateRef) ], IgxComboComponent.prototype, "complexTemplate", void 0); __decorate([ ViewChild(IgxForOfDirective, { static: true }), __metadata("design:type", IgxForOfDirective) ], IgxComboComponent.prototype, "virtualScrollContainer", void 0); __decorate([ ViewChild('dropdownItemContainer', { static: true }), __metadata("design:type", ElementRef) ], IgxComboComponent.prototype, "dropdownContainer", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxComboComponent.prototype, "onSelectionChange", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxComboComponent.prototype, "onOpening", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxComboComponent.prototype, "onOpened", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxComboComponent.prototype, "onClosing", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxComboComponent.prototype, "onClosed", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxComboComponent.prototype, "onAddition", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxComboComponent.prototype, "onSearchInput", void 0); __decorate([ Output(), __metadata("design:type", Object) ], IgxComboComponent.prototype, "onDataPreLoad", void 0); __decorate([ HostBinding('attr.id'), Input(), __metadata("design:type", Object) ], IgxComboComponent.prototype, "id", void 0); __decorate([ HostBinding('style.width'), Input(), __metadata("design:type", String) ], IgxComboComponent.prototype, "width", void 0); __decorate([ HostBinding('class.igx-combo'), __metadata("design:type", Object) ], IgxComboComponent.prototype, "cssClass", void 0);