UNPKG

primeng

Version:

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![npm version](https://badge.fury.io/js/primeng.svg)](https://badge.fury.io/js/primeng) [![npm downloads](https://img.shields.io/npm/dm/primeng.sv

974 lines (973 loc) 172 kB
import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, Component, ContentChildren, EventEmitter, forwardRef, Input, NgModule, Output, ViewChild, ViewEncapsulation } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { PrimeTemplate, SharedModule, TranslationKeys } from 'primeng/api'; import { AutoFocusModule } from 'primeng/autofocus'; import { DomHandler } from 'primeng/dom'; import { OverlayModule } from 'primeng/overlay'; import { RippleModule } from 'primeng/ripple'; import { ScrollerModule } from 'primeng/scroller'; import { TooltipModule } from 'primeng/tooltip'; import { ObjectUtils, UniqueComponentId } from 'primeng/utils'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "primeng/ripple"; import * as i3 from "primeng/api"; import * as i4 from "primeng/overlay"; import * as i5 from "primeng/tooltip"; import * as i6 from "primeng/scroller"; import * as i7 from "primeng/autofocus"; export const DROPDOWN_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => Dropdown), multi: true }; export class DropdownItem { constructor() { this.onClick = new EventEmitter(); } onOptionClick(event) { this.onClick.emit({ originalEvent: event, option: this.option }); } } DropdownItem.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.7", ngImport: i0, type: DropdownItem, deps: [], target: i0.ɵɵFactoryTarget.Component }); DropdownItem.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.7", type: DropdownItem, selector: "p-dropdownItem", inputs: { option: "option", selected: "selected", label: "label", disabled: "disabled", visible: "visible", itemSize: "itemSize", template: "template" }, outputs: { onClick: "onClick" }, host: { classAttribute: "p-element" }, ngImport: i0, template: ` <li (click)="onOptionClick($event)" role="option" pRipple [attr.aria-label]="label" [attr.aria-selected]="selected" [ngStyle]="{ height: itemSize + 'px' }" [id]="selected ? 'p-highlighted-option' : ''" [ngClass]="{ 'p-dropdown-item': true, 'p-highlight': selected, 'p-disabled': disabled }" > <span *ngIf="!template">{{ label || 'empty' }}</span> <ng-container *ngTemplateOutlet="template; context: { $implicit: option }"></ng-container> </li> `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.Ripple, selector: "[pRipple]" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.7", ngImport: i0, type: DropdownItem, decorators: [{ type: Component, args: [{ selector: 'p-dropdownItem', template: ` <li (click)="onOptionClick($event)" role="option" pRipple [attr.aria-label]="label" [attr.aria-selected]="selected" [ngStyle]="{ height: itemSize + 'px' }" [id]="selected ? 'p-highlighted-option' : ''" [ngClass]="{ 'p-dropdown-item': true, 'p-highlight': selected, 'p-disabled': disabled }" > <span *ngIf="!template">{{ label || 'empty' }}</span> <ng-container *ngTemplateOutlet="template; context: { $implicit: option }"></ng-container> </li> `, host: { class: 'p-element' } }] }], propDecorators: { option: [{ type: Input }], selected: [{ type: Input }], label: [{ type: Input }], disabled: [{ type: Input }], visible: [{ type: Input }], itemSize: [{ type: Input }], template: [{ type: Input }], onClick: [{ type: Output }] } }); export class Dropdown { constructor(el, renderer, cd, zone, filterService, config) { this.el = el; this.renderer = renderer; this.cd = cd; this.zone = zone; this.filterService = filterService; this.config = config; this.scrollHeight = '200px'; this.resetFilterOnHide = false; this.dropdownIcon = 'pi pi-chevron-down'; this.optionGroupChildren = 'items'; this.autoDisplayFirst = true; this.emptyFilterMessage = ''; this.emptyMessage = ''; this.lazy = false; this.filterMatchMode = 'contains'; this.tooltip = ''; this.tooltipPosition = 'right'; this.tooltipPositionStyle = 'absolute'; this.autofocusFilter = true; this.overlayDirection = 'end'; this.onChange = new EventEmitter(); this.onFilter = new EventEmitter(); this.onFocus = new EventEmitter(); this.onBlur = new EventEmitter(); this.onClick = new EventEmitter(); this.onShow = new EventEmitter(); this.onHide = new EventEmitter(); this.onClear = new EventEmitter(); this.onLazyLoad = new EventEmitter(); this.onModelChange = () => { }; this.onModelTouched = () => { }; this.id = UniqueComponentId(); } get disabled() { return this._disabled; } set disabled(_disabled) { if (_disabled) { this.focused = false; if (this.overlayVisible) this.hide(); } this._disabled = _disabled; if (!this.cd.destroyed) { this.cd.detectChanges(); } } get itemSize() { return this._itemSize; } set itemSize(val) { this._itemSize = val; console.warn('The itemSize property is deprecated, use virtualScrollItemSize property instead.'); } get autoZIndex() { return this._autoZIndex; } set autoZIndex(val) { this._autoZIndex = val; console.warn('The autoZIndex property is deprecated since v14.2.0, use overlayOptions property instead.'); } get baseZIndex() { return this._baseZIndex; } set baseZIndex(val) { this._baseZIndex = val; console.warn('The baseZIndex property is deprecated since v14.2.0, use overlayOptions property instead.'); } get showTransitionOptions() { return this._showTransitionOptions; } set showTransitionOptions(val) { this._showTransitionOptions = val; console.warn('The showTransitionOptions property is deprecated since v14.2.0, use overlayOptions property instead.'); } get hideTransitionOptions() { return this._hideTransitionOptions; } set hideTransitionOptions(val) { this._hideTransitionOptions = val; console.warn('The hideTransitionOptions property is deprecated since v14.2.0, use overlayOptions property instead.'); } ngAfterContentInit() { this.templates.forEach((item) => { switch (item.getType()) { case 'item': this.itemTemplate = item.template; break; case 'selectedItem': this.selectedItemTemplate = item.template; break; case 'header': this.headerTemplate = item.template; break; case 'filter': this.filterTemplate = item.template; break; case 'footer': this.footerTemplate = item.template; break; case 'emptyfilter': this.emptyFilterTemplate = item.template; break; case 'empty': this.emptyTemplate = item.template; break; case 'group': this.groupTemplate = item.template; break; case 'loader': this.loaderTemplate = item.template; break; default: this.itemTemplate = item.template; break; } }); } ngOnInit() { this.optionsToDisplay = this.options; this.updateSelectedOption(null); this.labelId = this.id + '_label'; this.listId = this.id + '_list'; if (this.filterBy) { this.filterOptions = { filter: (value) => this.onFilterInputChange(value), reset: () => this.resetFilter() }; } } get options() { return this._options; } set options(val) { this._options = val; this.optionsToDisplay = this._options; this.updateSelectedOption(this.value); this.selectedOption = this.findOption(this.value, this.optionsToDisplay); if (!this.selectedOption && ObjectUtils.isNotEmpty(this.value) && !this.editable) { this.value = null; this.onModelChange(this.value); } this.optionsChanged = true; if (this._filterValue && this._filterValue.length) { this.activateFilter(); } } get filterValue() { return this._filterValue; } set filterValue(val) { this._filterValue = val; this.activateFilter(); } ngAfterViewInit() { if (this.editable) { this.updateEditableLabel(); } } get label() { return this.selectedOption ? this.getOptionLabel(this.selectedOption) : null; } get emptyMessageLabel() { return this.emptyMessage || this.config.getTranslation(TranslationKeys.EMPTY_MESSAGE); } get emptyFilterMessageLabel() { return this.emptyFilterMessage || this.config.getTranslation(TranslationKeys.EMPTY_FILTER_MESSAGE); } get filled() { if (typeof this.value === 'string') return !!this.value; return this.value || this.value != null || this.value != undefined; } get isVisibleClearIcon() { return this.value != null && this.value !== '' && this.showClear && !this.disabled; } updateEditableLabel() { if (this.editableInputViewChild && this.editableInputViewChild.nativeElement) { this.editableInputViewChild.nativeElement.value = this.selectedOption ? this.getOptionLabel(this.selectedOption) : this.value || ''; } } getOptionLabel(option) { return this.optionLabel ? ObjectUtils.resolveFieldData(option, this.optionLabel) : option && option.label !== undefined ? option.label : option; } getOptionValue(option) { return this.optionValue ? ObjectUtils.resolveFieldData(option, this.optionValue) : !this.optionLabel && option && option.value !== undefined ? option.value : option; } isOptionDisabled(option) { return this.optionDisabled ? ObjectUtils.resolveFieldData(option, this.optionDisabled) : option && option.disabled !== undefined ? option.disabled : false; } getOptionGroupLabel(optionGroup) { return this.optionGroupLabel ? ObjectUtils.resolveFieldData(optionGroup, this.optionGroupLabel) : optionGroup && optionGroup.label !== undefined ? optionGroup.label : optionGroup; } getOptionGroupChildren(optionGroup) { return this.optionGroupChildren ? ObjectUtils.resolveFieldData(optionGroup, this.optionGroupChildren) : optionGroup.items; } onItemClick(event) { const option = event.option; if (!this.isOptionDisabled(option)) { this.selectItem(event.originalEvent, option); this.accessibleViewChild.nativeElement.focus({ preventScroll: true }); } setTimeout(() => { this.hide(); }, 1); } selectItem(event, option) { if (this.selectedOption != option) { this.selectedOption = option; this.value = this.getOptionValue(option); this.onModelChange(this.value); this.updateEditableLabel(); this.onChange.emit({ originalEvent: event, value: this.value }); } } ngAfterViewChecked() { if (this.optionsChanged && this.overlayVisible) { this.optionsChanged = false; this.zone.runOutsideAngular(() => { setTimeout(() => { if (this.overlayViewChild) { this.overlayViewChild.alignOverlay(); } }, 1); }); } if (this.selectedOptionUpdated && this.itemsWrapper) { let selectedItem = DomHandler.findSingle(this.overlayViewChild.el.nativeElement, 'li.p-highlight'); if (selectedItem) { DomHandler.scrollInView(this.itemsWrapper, DomHandler.findSingle(this.overlayViewChild.el.nativeElement, 'li.p-highlight')); } this.selectedOptionUpdated = false; } } writeValue(value) { if (this.filter) { this.resetFilter(); } this.value = value; this.updateSelectedOption(value); this.updateEditableLabel(); this.cd.markForCheck(); } resetFilter() { this._filterValue = null; if (this.filterViewChild && this.filterViewChild.nativeElement) { this.filterViewChild.nativeElement.value = ''; } this.optionsToDisplay = this.options; } updateSelectedOption(val) { this.selectedOption = this.findOption(val, this.optionsToDisplay); if (this.autoDisplayFirst && !this.placeholder && !this.selectedOption && this.optionsToDisplay && this.optionsToDisplay.length && !this.editable) { if (this.group) { this.selectedOption = this.optionsToDisplay[0].items[0]; } else { this.selectedOption = this.optionsToDisplay[0]; } this.value = this.getOptionValue(this.selectedOption); this.onModelChange(this.value); } this.selectedOptionUpdated = true; } registerOnChange(fn) { this.onModelChange = fn; } registerOnTouched(fn) { this.onModelTouched = fn; } setDisabledState(val) { this.disabled = val; this.cd.markForCheck(); } onMouseclick(event) { if (this.disabled || this.readonly || this.isInputClick(event)) { return; } this.onClick.emit(event); this.accessibleViewChild.nativeElement.focus({ preventScroll: true }); if (this.overlayVisible) this.hide(); else this.show(); this.cd.detectChanges(); } isInputClick(event) { return DomHandler.hasClass(event.target, 'p-dropdown-clear-icon') || event.target.isSameNode(this.accessibleViewChild.nativeElement) || (this.editableInputViewChild && event.target.isSameNode(this.editableInputViewChild.nativeElement)); } isEmpty() { return !this.optionsToDisplay || (this.optionsToDisplay && this.optionsToDisplay.length === 0); } onEditableInputFocus(event) { this.focused = true; this.hide(); this.onFocus.emit(event); } onEditableInputChange(event) { this.value = event.target.value; this.updateSelectedOption(this.value); this.onModelChange(this.value); this.onChange.emit({ originalEvent: event, value: this.value }); } show() { this.overlayVisible = true; this.cd.markForCheck(); } onOverlayAnimationStart(event) { if (event.toState === 'visible') { this.itemsWrapper = DomHandler.findSingle(this.overlayViewChild.el.nativeElement, this.virtualScroll ? '.p-scroller' : '.p-dropdown-items-wrapper'); this.virtualScroll && this.scroller.setContentEl(this.itemsViewChild.nativeElement); if (this.options && this.options.length) { if (this.virtualScroll) { const selectedIndex = this.selectedOption ? this.findOptionIndex(this.getOptionValue(this.selectedOption), this.optionsToDisplay) : -1; if (selectedIndex !== -1) { this.scroller.scrollToIndex(selectedIndex); } } else { let selectedListItem = DomHandler.findSingle(this.itemsWrapper, '.p-dropdown-item.p-highlight'); if (selectedListItem) { selectedListItem.scrollIntoView({ block: 'nearest', inline: 'center' }); } } } if (this.filterViewChild && this.filterViewChild.nativeElement) { this.preventModelTouched = true; if (this.autofocusFilter) { this.filterViewChild.nativeElement.focus(); } } this.onShow.emit(event); } if (event.toState === 'void') { this.itemsWrapper = null; this.onModelTouched(); this.onHide.emit(event); } } hide() { this.overlayVisible = false; if (this.filter && this.resetFilterOnHide) { this.resetFilter(); } this.cd.markForCheck(); } onInputFocus(event) { this.focused = true; this.onFocus.emit(event); } onInputBlur(event) { this.focused = false; this.onBlur.emit(event); if (!this.preventModelTouched) { this.onModelTouched(); } this.preventModelTouched = false; } findPrevEnabledOption(index) { let prevEnabledOption; if (this.optionsToDisplay && this.optionsToDisplay.length) { for (let i = index - 1; 0 <= i; i--) { let option = this.optionsToDisplay[i]; if (this.isOptionDisabled(option)) { continue; } else { prevEnabledOption = option; break; } } if (!prevEnabledOption) { for (let i = this.optionsToDisplay.length - 1; i >= index; i--) { let option = this.optionsToDisplay[i]; if (this.isOptionDisabled(option)) { continue; } else { prevEnabledOption = option; break; } } } } return prevEnabledOption; } findNextEnabledOption(index) { let nextEnabledOption; if (this.optionsToDisplay && this.optionsToDisplay.length) { for (let i = index + 1; i < this.optionsToDisplay.length; i++) { let option = this.optionsToDisplay[i]; if (this.isOptionDisabled(option)) { continue; } else { nextEnabledOption = option; break; } } if (!nextEnabledOption) { for (let i = 0; i < index; i++) { let option = this.optionsToDisplay[i]; if (this.isOptionDisabled(option)) { continue; } else { nextEnabledOption = option; break; } } } } return nextEnabledOption; } onKeydown(event, search) { if (this.readonly || !this.optionsToDisplay || this.optionsToDisplay.length === null) { return; } switch (event.which) { //down case 40: if (!this.overlayVisible && event.altKey) { this.show(); } else { if (this.group) { let selectedItemIndex = this.selectedOption ? this.findOptionGroupIndex(this.getOptionValue(this.selectedOption), this.optionsToDisplay) : -1; if (selectedItemIndex !== -1) { let nextItemIndex = selectedItemIndex.itemIndex + 1; if (nextItemIndex < this.getOptionGroupChildren(this.optionsToDisplay[selectedItemIndex.groupIndex]).length) { this.selectItem(event, this.getOptionGroupChildren(this.optionsToDisplay[selectedItemIndex.groupIndex])[nextItemIndex]); this.selectedOptionUpdated = true; } else if (this.optionsToDisplay[selectedItemIndex.groupIndex + 1]) { this.selectItem(event, this.getOptionGroupChildren(this.optionsToDisplay[selectedItemIndex.groupIndex + 1])[0]); this.selectedOptionUpdated = true; } } else { if (this.optionsToDisplay && this.optionsToDisplay.length > 0) { this.selectItem(event, this.getOptionGroupChildren(this.optionsToDisplay[0])[0]); } } } else { let selectedItemIndex = this.selectedOption ? this.findOptionIndex(this.getOptionValue(this.selectedOption), this.optionsToDisplay) : -1; let nextEnabledOption = this.findNextEnabledOption(selectedItemIndex); if (nextEnabledOption) { this.selectItem(event, nextEnabledOption); this.selectedOptionUpdated = true; } } } event.preventDefault(); break; //up case 38: if (this.group) { let selectedItemIndex = this.selectedOption ? this.findOptionGroupIndex(this.getOptionValue(this.selectedOption), this.optionsToDisplay) : -1; if (selectedItemIndex !== -1) { let prevItemIndex = selectedItemIndex.itemIndex - 1; if (prevItemIndex >= 0) { this.selectItem(event, this.getOptionGroupChildren(this.optionsToDisplay[selectedItemIndex.groupIndex])[prevItemIndex]); this.selectedOptionUpdated = true; } else if (prevItemIndex < 0) { let prevGroup = this.optionsToDisplay[selectedItemIndex.groupIndex - 1]; if (prevGroup) { this.selectItem(event, this.getOptionGroupChildren(prevGroup)[this.getOptionGroupChildren(prevGroup).length - 1]); this.selectedOptionUpdated = true; } } } } else { let selectedItemIndex = this.selectedOption ? this.findOptionIndex(this.getOptionValue(this.selectedOption), this.optionsToDisplay) : -1; let prevEnabledOption = this.findPrevEnabledOption(selectedItemIndex); if (prevEnabledOption) { this.selectItem(event, prevEnabledOption); this.selectedOptionUpdated = true; } } event.preventDefault(); break; //space case 32: if (search) { if (!this.overlayVisible) { this.show(); } else { this.hide(); } event.preventDefault(); } break; //enter case 13: if (this.overlayVisible && (!this.filter || (this.optionsToDisplay && this.optionsToDisplay.length > 0))) { this.hide(); } else if (!this.overlayVisible) { this.show(); } event.preventDefault(); break; //escape and tab case 27: case 9: this.hide(); break; //search item based on keyboard input default: if (search && !event.metaKey && event.which !== 17) { this.search(event); } break; } } search(event) { if (this.searchTimeout) { clearTimeout(this.searchTimeout); } const char = event.key; this.previousSearchChar = this.currentSearchChar; this.currentSearchChar = char; if (this.previousSearchChar === this.currentSearchChar) this.searchValue = this.currentSearchChar; else this.searchValue = this.searchValue ? this.searchValue + char : char; let newOption; if (this.group) { let searchIndex = this.selectedOption ? this.findOptionGroupIndex(this.getOptionValue(this.selectedOption), this.optionsToDisplay) : { groupIndex: 0, itemIndex: 0 }; newOption = this.searchOptionWithinGroup(searchIndex); } else { let searchIndex = this.selectedOption ? this.findOptionIndex(this.getOptionValue(this.selectedOption), this.optionsToDisplay) : -1; newOption = this.searchOption(++searchIndex); } if (newOption && !this.isOptionDisabled(newOption)) { this.selectItem(event, newOption); this.selectedOptionUpdated = true; } this.searchTimeout = setTimeout(() => { this.searchValue = null; }, 250); } searchOption(index) { let option; if (this.searchValue) { option = this.searchOptionInRange(index, this.optionsToDisplay.length); if (!option) { option = this.searchOptionInRange(0, index); } } return option; } searchOptionInRange(start, end) { for (let i = start; i < end; i++) { let opt = this.optionsToDisplay[i]; if (this.getOptionLabel(opt) .toLocaleLowerCase(this.filterLocale) .startsWith(this.searchValue.toLocaleLowerCase(this.filterLocale)) && !this.isOptionDisabled(opt)) { return opt; } } return null; } searchOptionWithinGroup(index) { let option; if (this.searchValue) { for (let i = index.groupIndex; i < this.optionsToDisplay.length; i++) { for (let j = index.groupIndex === i ? index.itemIndex + 1 : 0; j < this.getOptionGroupChildren(this.optionsToDisplay[i]).length; j++) { let opt = this.getOptionGroupChildren(this.optionsToDisplay[i])[j]; if (this.getOptionLabel(opt) .toLocaleLowerCase(this.filterLocale) .startsWith(this.searchValue.toLocaleLowerCase(this.filterLocale)) && !this.isOptionDisabled(opt)) { return opt; } } } if (!option) { for (let i = 0; i <= index.groupIndex; i++) { for (let j = 0; j < (index.groupIndex === i ? index.itemIndex : this.getOptionGroupChildren(this.optionsToDisplay[i]).length); j++) { let opt = this.getOptionGroupChildren(this.optionsToDisplay[i])[j]; if (this.getOptionLabel(opt) .toLocaleLowerCase(this.filterLocale) .startsWith(this.searchValue.toLocaleLowerCase(this.filterLocale)) && !this.isOptionDisabled(opt)) { return opt; } } } } } return null; } findOptionIndex(val, opts) { let index = -1; if (opts) { for (let i = 0; i < opts.length; i++) { if ((val == null && this.getOptionValue(opts[i]) == null) || ObjectUtils.equals(val, this.getOptionValue(opts[i]), this.dataKey)) { index = i; break; } } } return index; } findOptionGroupIndex(val, opts) { let groupIndex, itemIndex; if (opts) { for (let i = 0; i < opts.length; i++) { groupIndex = i; itemIndex = this.findOptionIndex(val, this.getOptionGroupChildren(opts[i])); if (itemIndex !== -1) { break; } } } if (itemIndex !== -1) { return { groupIndex: groupIndex, itemIndex: itemIndex }; } else { return -1; } } findOption(val, opts, inGroup) { if (this.group && !inGroup) { let opt; if (opts && opts.length) { for (let optgroup of opts) { opt = this.findOption(val, this.getOptionGroupChildren(optgroup), true); if (opt) { break; } } } return opt; } else { let index = this.findOptionIndex(val, opts); return index != -1 ? opts[index] : null; } } onFilterInputChange(event) { let inputValue = event.target.value; if (inputValue && inputValue.length) { this._filterValue = inputValue; this.activateFilter(); } else { this._filterValue = null; this.optionsToDisplay = this.options; } this.virtualScroll && this.scroller.scrollToIndex(0); this.optionsChanged = true; this.onFilter.emit({ originalEvent: event, filter: this._filterValue }); } activateFilter() { let searchFields = (this.filterBy || this.optionLabel || 'label').split(','); if (this.options && this.options.length) { if (this.group) { let filteredGroups = []; for (let optgroup of this.options) { let filteredSubOptions = this.filterService.filter(this.getOptionGroupChildren(optgroup), searchFields, this.filterValue, this.filterMatchMode, this.filterLocale); if (filteredSubOptions && filteredSubOptions.length) { filteredGroups.push({ ...optgroup, ...{ [this.optionGroupChildren]: filteredSubOptions } }); } } this.optionsToDisplay = filteredGroups; } else { this.optionsToDisplay = this.filterService.filter(this.options, searchFields, this.filterValue, this.filterMatchMode, this.filterLocale); } this.optionsChanged = true; } } applyFocus() { if (this.editable) DomHandler.findSingle(this.el.nativeElement, '.p-dropdown-label.p-inputtext').focus(); else DomHandler.findSingle(this.el.nativeElement, 'input[readonly]').focus(); } focus() { this.applyFocus(); } clear(event) { this.value = null; this.onModelChange(this.value); this.onChange.emit({ originalEvent: event, value: this.value }); this.updateSelectedOption(this.value); this.updateEditableLabel(); this.onClear.emit(event); } } Dropdown.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.7", ngImport: i0, type: Dropdown, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i3.FilterService }, { token: i3.PrimeNGConfig }], target: i0.ɵɵFactoryTarget.Component }); Dropdown.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.7", type: Dropdown, selector: "p-dropdown", inputs: { scrollHeight: "scrollHeight", filter: "filter", name: "name", style: "style", panelStyle: "panelStyle", styleClass: "styleClass", panelStyleClass: "panelStyleClass", readonly: "readonly", required: "required", editable: "editable", appendTo: "appendTo", tabindex: "tabindex", placeholder: "placeholder", filterPlaceholder: "filterPlaceholder", filterLocale: "filterLocale", inputId: "inputId", selectId: "selectId", dataKey: "dataKey", filterBy: "filterBy", autofocus: "autofocus", resetFilterOnHide: "resetFilterOnHide", dropdownIcon: "dropdownIcon", optionLabel: "optionLabel", optionValue: "optionValue", optionDisabled: "optionDisabled", optionGroupLabel: "optionGroupLabel", optionGroupChildren: "optionGroupChildren", autoDisplayFirst: "autoDisplayFirst", group: "group", showClear: "showClear", emptyFilterMessage: "emptyFilterMessage", emptyMessage: "emptyMessage", lazy: "lazy", virtualScroll: "virtualScroll", virtualScrollItemSize: "virtualScrollItemSize", virtualScrollOptions: "virtualScrollOptions", overlayOptions: "overlayOptions", ariaFilterLabel: "ariaFilterLabel", ariaLabel: "ariaLabel", ariaLabelledBy: "ariaLabelledBy", filterMatchMode: "filterMatchMode", maxlength: "maxlength", tooltip: "tooltip", tooltipPosition: "tooltipPosition", tooltipPositionStyle: "tooltipPositionStyle", tooltipStyleClass: "tooltipStyleClass", autofocusFilter: "autofocusFilter", overlayDirection: "overlayDirection", disabled: "disabled", itemSize: "itemSize", autoZIndex: "autoZIndex", baseZIndex: "baseZIndex", showTransitionOptions: "showTransitionOptions", hideTransitionOptions: "hideTransitionOptions", options: "options", filterValue: "filterValue" }, outputs: { onChange: "onChange", onFilter: "onFilter", onFocus: "onFocus", onBlur: "onBlur", onClick: "onClick", onShow: "onShow", onHide: "onHide", onClear: "onClear", onLazyLoad: "onLazyLoad" }, host: { properties: { "class.p-inputwrapper-filled": "filled", "class.p-inputwrapper-focus": "focused || overlayVisible" }, classAttribute: "p-element p-inputwrapper" }, providers: [DROPDOWN_VALUE_ACCESSOR], queries: [{ propertyName: "templates", predicate: PrimeTemplate }], viewQueries: [{ propertyName: "containerViewChild", first: true, predicate: ["container"], descendants: true }, { propertyName: "filterViewChild", first: true, predicate: ["filter"], descendants: true }, { propertyName: "accessibleViewChild", first: true, predicate: ["in"], descendants: true }, { propertyName: "editableInputViewChild", first: true, predicate: ["editableInput"], descendants: true }, { propertyName: "itemsViewChild", first: true, predicate: ["items"], descendants: true }, { propertyName: "scroller", first: true, predicate: ["scroller"], descendants: true }, { propertyName: "overlayViewChild", first: true, predicate: ["overlay"], descendants: true }], ngImport: i0, template: ` <div #container [ngClass]="{ 'p-dropdown p-component': true, 'p-disabled': disabled, 'p-dropdown-open': overlayVisible, 'p-focus': focused, 'p-dropdown-clearable': showClear && !disabled }" (click)="onMouseclick($event)" [ngStyle]="style" [class]="styleClass" > <div class="p-hidden-accessible"> <input #in [attr.id]="inputId" type="text" readonly (focus)="onInputFocus($event)" aria-haspopup="listbox" [attr.placeholder]="placeholder" aria-haspopup="listbox" [attr.aria-label]="ariaLabel" [attr.aria-expanded]="false" [attr.aria-labelledby]="ariaLabelledBy" (blur)="onInputBlur($event)" (keydown)="onKeydown($event, true)" [disabled]="disabled" [attr.tabindex]="tabindex" pAutoFocus [autofocus]="autofocus" [attr.aria-activedescendant]="overlayVisible ? labelId : null" role="combobox" /> </div> <span [attr.id]="labelId" [ngClass]="{ 'p-dropdown-label p-inputtext': true, 'p-dropdown-label-empty': label == null || label.length === 0 }" *ngIf="!editable && label != null" [pTooltip]="tooltip" [tooltipPosition]="tooltipPosition" [positionStyle]="tooltipPositionStyle" [tooltipStyleClass]="tooltipStyleClass" > <ng-container *ngIf="!selectedItemTemplate">{{ label || 'empty' }}</ng-container> <ng-container *ngTemplateOutlet="selectedItemTemplate; context: { $implicit: selectedOption }"></ng-container> </span> <span [ngClass]="{ 'p-dropdown-label p-inputtext p-placeholder': true, 'p-dropdown-label-empty': placeholder == null || placeholder.length === 0 }" *ngIf="!editable && label == null">{{ placeholder || 'empty' }}</span> <input #editableInput type="text" [attr.maxlength]="maxlength" class="p-dropdown-label p-inputtext" *ngIf="editable" [disabled]="disabled" [attr.placeholder]="placeholder" aria-haspopup="listbox" [attr.aria-expanded]="overlayVisible" (input)="onEditableInputChange($event)" (focus)="onEditableInputFocus($event)" (blur)="onInputBlur($event)" /> <i class="p-dropdown-clear-icon pi pi-times" (click)="clear($event)" *ngIf="isVisibleClearIcon"></i> <div class="p-dropdown-trigger" role="button" aria-label="dropdown trigger" aria-haspopup="listbox" [attr.aria-expanded]="overlayVisible"> <span class="p-dropdown-trigger-icon" [ngClass]="dropdownIcon"></span> </div> <p-overlay #overlay [(visible)]="overlayVisible" [options]="overlayOptions" [target]="'@parent'" [appendTo]="appendTo" [autoZIndex]="autoZIndex" [baseZIndex]="baseZIndex" [showTransitionOptions]="showTransitionOptions" [hideTransitionOptions]="hideTransitionOptions" (onAnimationStart)="onOverlayAnimationStart($event)" (onHide)="hide()" > <ng-template pTemplate="content"> <div [ngClass]="'p-dropdown-panel p-component'" [ngStyle]="panelStyle" [class]="panelStyleClass"> <ng-container *ngTemplateOutlet="headerTemplate"></ng-container> <div class="p-dropdown-header" *ngIf="filter" (click)="$event.stopPropagation()"> <ng-container *ngIf="filterTemplate; else builtInFilterElement"> <ng-container *ngTemplateOutlet="filterTemplate; context: { options: filterOptions }"></ng-container> </ng-container> <ng-template #builtInFilterElement> <div class="p-dropdown-filter-container"> <input #filter type="text" autocomplete="off" [value]="filterValue || ''" class="p-dropdown-filter p-inputtext p-component" [attr.placeholder]="filterPlaceholder" (keydown.enter)="$event.preventDefault()" (keydown)="onKeydown($event, false)" (input)="onFilterInputChange($event)" [attr.aria-label]="ariaFilterLabel" [attr.aria-activedescendant]="overlayVisible ? 'p-highlighted-option' : labelId" /> <span class="p-dropdown-filter-icon pi pi-search"></span> </div> </ng-template> </div> <div class="p-dropdown-items-wrapper" [style.max-height]="virtualScroll ? 'auto' : scrollHeight || 'auto'"> <p-scroller *ngIf="virtualScroll" #scroller [items]="optionsToDisplay" [style]="{ height: scrollHeight }" [itemSize]="virtualScrollItemSize || _itemSize" [autoSize]="true" [lazy]="lazy" (onLazyLoad)="onLazyLoad.emit($event)" [options]="virtualScrollOptions" > <ng-template pTemplate="content" let-items let-scrollerOptions="options"> <ng-container *ngTemplateOutlet="buildInItems; context: { $implicit: items, options: scrollerOptions }"></ng-container> </ng-template> <ng-container *ngIf="loaderTemplate"> <ng-template pTemplate="loader" let-scrollerOptions="options"> <ng-container *ngTemplateOutlet="loaderTemplate; context: { options: scrollerOptions }"></ng-container> </ng-template> </ng-container> </p-scroller> <ng-container *ngIf="!virtualScroll"> <ng-container *ngTemplateOutlet="buildInItems; context: { $implicit: optionsToDisplay, options: {} }"></ng-container> </ng-container> <ng-template #buildInItems let-items let-scrollerOptions="options"> <ul #items [attr.id]="listId" class="p-dropdown-items" [ngClass]="scrollerOptions.contentStyleClass" [style]="scrollerOptions.contentStyle" role="listbox"> <ng-container *ngIf="group"> <ng-template ngFor let-optgroup [ngForOf]="items"> <li class="p-dropdown-item-group" [ngStyle]="{ height: scrollerOptions.itemSize + 'px' }"> <span *ngIf="!groupTemplate">{{ getOptionGroupLabel(optgroup) || 'empty' }}</span> <ng-container *ngTemplateOutlet="groupTemplate; context: { $implicit: optgroup }"></ng-container> </li> <ng-container *ngTemplateOutlet="itemslist; context: { $implicit: getOptionGroupChildren(optgroup), selectedOption: selectedOption }"></ng-container> </ng-template> </ng-container> <ng-container *ngIf="!group"> <ng-container *ngTemplateOutlet="itemslist; context: { $implicit: items, selectedOption: selectedOption }"></ng-container> </ng-container> <ng-template #itemslist let-options let-selectedOption="selectedOption"> <ng-template ngFor let-option let-i="index" [ngForOf]="options"> <p-dropdownItem [option]="option" [selected]="selectedOption == option" [label]="getOptionLabel(option)" [disabled]="isOptionDisabled(option)" (onClick)="onItemClick($event)" [template]="itemTemplate" ></p-dropdownItem> </ng-template> </ng-template> <li *ngIf="filterValue && isEmpty()" class="p-dropdown-empty-message" [ngStyle]="{ height: scrollerOptions.itemSize + 'px' }"> <ng-container *ngIf="!emptyFilterTemplate && !emptyTemplate; else emptyFilter"> {{ emptyFilterMessageLabel }} </ng-container> <ng-container #emptyFilter *ngTemplateOutlet="emptyFilterTemplate || emptyTemplate"></ng-container> </li> <li *ngIf="!filterValue && isEmpty()" class="p-dropdown-empty-message" [ngStyle]="{ height: scrollerOptions.itemSize + 'px' }"> <ng-container *ngIf="!emptyTemplate; else empty"> {{ emptyMessageLabel }} </ng-container> <ng-container #empty *ngTemplateOutlet="emptyTemplate"></ng-container> </li> </ul> </ng-template> </div> <ng-container *ngTemplateOutlet="footerTemplate"></ng-container> </div> </ng-template> </p-overlay> </div> `, isInline: true, styles: [".p-dropdown{display:inline-flex;cursor:pointer;position:relative;-webkit-user-select:none;user-select:none}.p-dropdown-clear-icon{position:absolute;top:50%;margin-top:-.5rem}.p-dropdown-trigger{display:flex;align-items:center;justify-content:center;flex-shrink:0}.p-dropdown-label{display:block;white-space:nowrap;overflow:hidden;flex:1 1 auto;width:1%;text-overflow:ellipsis;cursor:pointer}.p-dropdown-label-empty{overflow:hidden;visibility:hidden}input.p-dropdown-label{cursor:default}.p-dropdown-items-wrapper{overflow:auto}.p-dropdown-item{cursor:pointer;font-weight:400;white-space:nowrap;position:relative;overflow:hidden}.p-dropdown-items{margin:0;padding:0;list-style-type:none}.p-dropdown-filter{width:100%}.p-dropdown-filter-container{position:relative}.p-dropdown-filter-icon{position:absolute;top:50%;margin-top:-.5rem}.p-fluid .p-dropdown{display:flex}.p-fluid .p-dropdown .p-dropdown-label{width:1%}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i4.Overlay, selector: "p-overlay", inputs: ["visible", "mode", "style", "styleClass", "contentStyle", "contentStyleClass", "target", "appendTo", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "listener", "responsive", "options"], outputs: ["visibleChange", "onBeforeShow", "onShow", "onBeforeHide", "onHide", "onAnimationStart", "onAnimationDone"] }, { kind: "directive", type: i3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "fitContent", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: i6.Scroller, selector: "p-scroller", inputs: ["id", "style", "styleClass", "tabindex", "items", "itemSize", "scrollHeight", "scrollWidth", "orientation", "step", "delay", "resizeDelay", "appendOnly", "inline", "lazy", "disabled", "loaderDisabled", "columns", "showSpacer", "showLoader", "numToleratedItems", "loading", "autoSize", "trackBy", "options"], outputs: ["onLazyLoad", "onScroll", "onScrollIndexChange"] }, { kind: "directive", type: i7.AutoFocus, selector: "[pAutoFocus]", inputs: ["autofocus"] }, { kind: "component", type: DropdownItem, selector: "p-dr