UNPKG

ngx-select-dropdown

Version:

A angular(4+) select dropdown for single select or multiselct module.

808 lines (799 loc) 49 kB
import * as i0 from '@angular/core'; import { EventEmitter, Injectable, Pipe, forwardRef, Component, Input, Output, ViewChildren, HostListener, ViewChild, HostBinding, NgModule } from '@angular/core'; import * as i3 from '@angular/forms'; import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import * as i2 from '@angular/common'; import { CommonModule } from '@angular/common'; class SelectDropDownService { constructor() { this.openDropdownInstance = new EventEmitter(); this.closeDropdownInstance = new EventEmitter(); this.openInstances = []; // constructor } isOpen(instanceId) { return this.openInstances.indexOf(instanceId) > -1; } /** * @summary: Open a specific dropdown instance based on the instance ID. * @param instanceId: Instance id of the dropdown that must be opened. */ openDropdown(instanceId) { this.openDropdownInstance.emit(instanceId); } /** * @summary: Close a specific dropdown instance based on the instance ID. * @param instanceId: Instance id of the dropdown that must be closed. */ closeDropdown(instanceId) { this.closeDropdownInstance.emit(instanceId); } } /** @nocollapse */ SelectDropDownService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SelectDropDownService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); /** @nocollapse */ SelectDropDownService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SelectDropDownService, providedIn: "root" }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SelectDropDownService, decorators: [{ type: Injectable, args: [{ providedIn: "root", }] }], ctorParameters: function () { return []; } }); /** * filters an array based on searctext */ class FilterByPipe { transform(array, searchText, keyName) { if (!array || !searchText || !Array.isArray(array)) { return array; } if (typeof array[0] === 'string') { return array.filter((item) => item.toLowerCase().indexOf(searchText.trim().toLowerCase()) > -1); } // filter array, items which match and return true will be // kept, false will be filtered out if (!keyName) { return array.filter((item) => { for (const key in item) { if (typeof item[key] !== 'object' && item[key].toString().toLowerCase().indexOf(searchText.trim().toLowerCase()) > -1) { return true; } } return false; }); } else { return array.filter((item) => { if (typeof item[keyName] !== 'object' && item[keyName].toString().toLowerCase().indexOf(searchText.trim().toLowerCase()) > -1) { return true; } return false; }); } } } /** @nocollapse */ FilterByPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: FilterByPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); /** @nocollapse */ FilterByPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: FilterByPipe, name: "filterBy" }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: FilterByPipe, decorators: [{ type: Pipe, args: [{ name: 'filterBy' }] }] }); class LimitToPipe { transform(array, itemsCount, startIndex = 0) { if (!Array.isArray(array) || itemsCount === 0) { return array; } return array.slice(startIndex, startIndex + itemsCount); } } /** @nocollapse */ LimitToPipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: LimitToPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); /** @nocollapse */ LimitToPipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: LimitToPipe, name: "limitTo" }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: LimitToPipe, decorators: [{ type: Pipe, args: [{ name: 'limitTo' }] }] }); const config = { displayKey: "description", height: "auto", search: false, placeholder: "Select", searchPlaceholder: "Search...", limitTo: 0, customComparator: undefined, noResultsFound: "No results found!", moreText: "more", searchOnKey: null, clearOnSelection: false, inputDirection: "ltr", selectAllLabel: "Select all", enableSelectAll: false, }; class NgxSelectDropdownComponent { constructor(cdref, _elementRef, dropdownService) { this.cdref = cdref; this._elementRef = _elementRef; this.dropdownService = dropdownService; /** * Get the required inputs */ this.options = []; /** * configuration options */ this.config = config; /** * Whether multiple selection or single selection allowed */ this.multiple = false; /** * change event when value changes to provide user to handle things in change event */ this.change = new EventEmitter(); /** * The search text change event emitter emitted when user type in the search input */ this.searchChange = new EventEmitter(); /** * Event emitted when dropdown is open. */ this.open = new EventEmitter(); /** * Event emitted when dropdown is open. */ this.close = new EventEmitter(); /** * Toogle the dropdown list */ this.toggleDropdown = false; /** * Available items for selection */ this.availableItems = []; /** * Selected Items */ this.selectedItems = []; /** * Selection text to be Displayed */ this.selectedDisplayText = "Select"; /** * variable to track if clicked inside or outside of component */ this.clickedInside = false; /** * variable to track keypress event inside and outsid of component */ this.insideKeyPress = false; /** * variable to track the focused item whenuser uses arrow keys to select item */ this.focusedItemIndex = null; /** * element to show not found text when not itmes match the search */ this.showNotFound = false; this.onChange = () => { // empty }; this.onTouched = () => { // empty }; /** * Binding to set the tabindex property to set to 0 for accessibilty */ this.tabindex = 0; this.multiple = false; this.selectAll = false; } get value() { return this._value; } set value(val) { this._value = val; this.onChange(val); this.onTouched(); } /** * click listener for host inside this component i.e * if many instances are there, this detects if clicked inside * this instance */ clickInsideComponent() { this.clickedInside = true; } /** * View reference for the dorpdown list */ set dropDownElement(ref) { if (ref) { // initially setter gets called with undefined this.dropdownList = ref; } } /** * Event listener for the blur event to hide the dropdown */ blur($event) { if (!this.insideKeyPress && !this.optionMouseDown && $event instanceof KeyboardEvent) { this.toggleDropdown = false; this.openStateChange(); } } /** * Event listener for the focus event to show the dropdown when using tab key */ focus() { /* istanbul ignore else */ if (!this.disabled) { this.toggleDropdown = true; this.openStateChange(); } } /** * click handler on documnent to hide the open dropdown if clicked outside */ clickOutsideComponent() { /* istanbul ignore else */ if (!this.clickedInside) { this.toggleDropdown = false; this.openStateChange(); this.resetArrowKeyActiveElement(); // clear searh on close this.searchText = null; this.close.emit(); } this.clickedInside = false; } /** * click handler on documnent to hide the open dropdown if clicked outside */ KeyPressOutsideComponent() { /* istanbul ignore else */ if (!this.insideKeyPress) { this.toggleDropdown = false; this.openStateChange(); this.resetArrowKeyActiveElement(); } this.insideKeyPress = false; } /** * Event handler for key up and down event and enter press for selecting element */ handleKeyboardEvent($event) { this.insideKeyPress = true; /* istanbul ignore else */ if ($event.keyCode === 27 || this.disabled) { this.toggleDropdown = false; this.openStateChange(); this.insideKeyPress = false; return; } const avaOpts = this.availableOptions.toArray(); /* istanbul ignore else */ if ($event.keyCode !== 9 && avaOpts.length === 0 && !this.toggleDropdown) { this.toggleDropdown = true; this.openStateChange(); } // Arrow Down /* istanbul ignore else */ if ($event.keyCode === 40 && avaOpts.length > 0) { this.onArrowKeyDown(); /* istanbul ignore else */ if (this.focusedItemIndex >= avaOpts.length) { this.focusedItemIndex = 0; } avaOpts[this.focusedItemIndex].nativeElement.focus(); $event.preventDefault(); } // Arrow Up /* istanbul ignore else */ if ($event.keyCode === 38 && avaOpts.length) { this.onArrowKeyUp(); /* istanbul ignore else */ if (this.focusedItemIndex >= avaOpts.length) { this.focusedItemIndex = avaOpts.length - 1; } avaOpts[this.focusedItemIndex].nativeElement.focus(); $event.preventDefault(); } // Enter /* istanbul ignore else */ if ($event.keyCode === 13 && this.focusedItemIndex !== null) { const filteredItems = new FilterByPipe().transform(this.availableItems, this.searchText, this.config.searchOnKey); this.selectItem(filteredItems[this.focusedItemIndex], this.availableItems.indexOf(filteredItems[this.focusedItemIndex])); return false; } } /** * Component onInit */ ngOnInit() { /* istanbul ignore else */ if (typeof this.options !== "undefined" && typeof this.config !== "undefined" && Array.isArray(this.options)) { this.availableItems = [ ...this.options.sort(this.config.customComparator), ]; this.initDropdownValuesAndOptions(); } this.serviceSubscriptions(); } isVisible() { if (!this.dropdownList) { return { visible: false, element: null }; } const el = this.dropdownList.nativeElement; if (!el) { return { visible: false, element: el }; } const rect = el.getBoundingClientRect(); const topShown = rect.top >= 0; const bottomShown = rect.bottom <= window.innerHeight; return { visible: topShown && bottomShown, element: el }; } serviceSubscriptions() { this.dropdownService.openDropdownInstance.subscribe((instanceId) => { if (this.instanceId === instanceId) { this.toggleDropdown = true; this.openStateChange(); this.resetArrowKeyActiveElement(); } }); this.dropdownService.closeDropdownInstance.subscribe((instanceId) => { if (this.instanceId === instanceId) { this.toggleDropdown = false; this.openStateChange(); this.resetArrowKeyActiveElement(); } }); } /** * after view init to subscribe to available option changes */ ngAfterViewInit() { this.availableOptions.changes.subscribe(this.setNotFoundState.bind(this)); } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } setDisabledState(isDisabled) { this.disabled = isDisabled; } writeValue(value, internal) { if (value) { if (Array.isArray(value)) { if (this.multiple) { this.value = value; } else if (value.length > 0) { this.value = value[0]; } } else { this.value = value; } /* istanbul ignore else */ if (this.selectedItems.length === 0) { if (Array.isArray(value)) { this.selectedItems = value; } else { this.selectedItems.push(value); } this.initDropdownValuesAndOptions(); } } else { this.value = []; /* istanbul ignore else */ if (!internal) { this.reset(); } } /* istanbul ignore else */ if (!internal) { this.reset(); } } reset() { if (!this.config) { return; } this.selectedItems = []; this.availableItems = [...this.options.sort(this.config.customComparator)]; this.initDropdownValuesAndOptions(); } /** * function sets whether to show items not found text or not */ setNotFoundState() { if (this.availableOptions.length === 0 && this.selectedItems.length !== this.options.length) { this.showNotFound = true; } else { this.showNotFound = false; } this.cdref.detectChanges(); } /** * Component onchage i.e when any of the input properties change */ ngOnChanges(changes) { if (!this.config) { return; } this.selectedItems = []; // this.searchText = null; this.options = this.options || []; /* istanbul ignore else */ if (changes.options) { this.availableItems = [ ...this.options.sort(this.config.customComparator), ]; } /* istanbul ignore else */ if (changes.value) { /* istanbul ignore else */ if (JSON.stringify(changes.value.currentValue) === JSON.stringify([]) || changes.value.currentValue === "" || changes.value.currentValue === null) { this.availableItems = [ ...this.options.sort(this.config.customComparator), ]; } } this.initDropdownValuesAndOptions(); } /** * Deselct a selected items * @param item: item to be deselected * @param index: index of the item */ deselectItem(item, index) { this.selectedItems.forEach((element, i) => { /* istanbul ignore else */ if (item === element) { this.selectedItems.splice(i, 1); } }); let sortedItems = [...this.availableItems]; /* istanbul ignore else */ if (!this.availableItems.includes(item)) { this.availableItems.push(item); sortedItems = this.availableItems.sort(this.config.customComparator); } this.selectedItems = [...this.selectedItems]; this.availableItems = [...sortedItems]; /* istanbul ignore else */ if (!Array.isArray(this.value)) { this.value = []; } if (!this.areAllSelected()) { this.selectAll = false; } this.valueChanged(); this.resetArrowKeyActiveElement(); } /** * Select an item * @param item: item to be selected * @param index: index of the item */ selectItem(item, index) { /* istanbul ignore else */ if (!this.multiple) { /* istanbul ignore else */ if (this.selectedItems.length > 0) { this.availableItems.push(this.selectedItems[0]); } this.selectedItems = []; this.toggleDropdown = false; } this.availableItems.forEach((element, i) => { /* istanbul ignore else */ if (item === element) { this.selectedItems.push(item); this.availableItems.splice(i, 1); } }); /* istanbul ignore else */ if (this.config.clearOnSelection) { this.searchText = null; } this.selectedItems = [...this.selectedItems]; this.availableItems = [...this.availableItems]; this.selectedItems.sort(this.config.customComparator); this.availableItems.sort(this.config.customComparator); // this.searchText = null; /* istanbul ignore else */ if (this.areAllSelected()) { this.selectAll = true; } this.valueChanged(); this.resetArrowKeyActiveElement(); } /** * When selected items changes trigger the chaange back to parent */ valueChanged() { this.writeValue(this.selectedItems, true); // this.valueChange.emit(this.value); this.change.emit({ value: this.value }); this.setSelectedDisplayText(); } /** * Toggle the dropdownlist on/off */ openSelectDropdown() { this.toggleDropdown = true; this.top = "30px"; this.openStateChange(); this.resetArrowKeyActiveElement(); setTimeout(() => { const { visible, element } = this.isVisible(); if (element) { this.top = visible ? "30px" : `-${element.getBoundingClientRect().height}px`; } }, 3); } closeSelectDropdown() { this.toggleDropdown = false; this.openStateChange(); this.resetArrowKeyActiveElement(); } openStateChange() { if (this.toggleDropdown) { this.dropdownService.openInstances.push(this.instanceId); this.open.emit(); } else { this.searchText = null; this.optionMouseDown = false; this.close.emit(); this.dropdownService.openInstances.splice(this.dropdownService.openInstances.indexOf(this.instanceId), 1); } } /** * The change handler for search text */ searchTextChanged() { this.searchChange.emit(this.searchText); } changeSearchText($event) { $event.stopPropagation(); } /** * initialize the config and other properties */ initDropdownValuesAndOptions() { /* istanbul ignore else */ if (typeof this.config === "undefined" || Object.keys(this.config).length === 0) { this.config = { ...config }; } for (const key of Object.keys(config)) { this.config[key] = this.config[key] ? this.config[key] : config[key]; } this.config = { ...this.config }; // Adding placeholder in config as default param this.selectedDisplayText = this.config["placeholder"]; /* istanbul ignore else */ if (this.value !== "" && typeof this.value !== "undefined") { if (Array.isArray(this.value)) { this.selectedItems = this.value; } else if (this.value !== "" && this.value !== null) { this.selectedItems[0] = this.value; } else { this.selectedItems = []; this.value = []; } this.selectedItems.forEach((item) => { const ind = this.availableItems.findIndex((aItem) => JSON.stringify(item) === JSON.stringify(aItem)); if (ind !== -1) { this.availableItems.splice(ind, 1); } }); } this.setSelectedDisplayText(); } /** * set the text to be displayed */ setSelectedDisplayText() { let text = this.selectedItems[0]; /* istanbul ignore else */ if (typeof this.selectedItems[0] === "object") { text = this.config.displayFn ? this.config.displayFn(this.selectedItems[0]) : this.selectedItems[0][this.config.displayKey]; } if (this.multiple && this.selectedItems.length > 0) { this.selectedDisplayText = this.selectedItems.length === 1 ? text : text + ` + ${this.selectedItems.length - 1} ${this.config.moreText}`; } else { this.selectedDisplayText = this.selectedItems.length === 0 ? this.config.placeholder : text; } } /** * Event handler for arrow key up event thats focuses on a item */ onArrowKeyUp() { /* istanbul ignore else */ if (this.focusedItemIndex === 0) { this.focusedItemIndex = this.availableItems.length - 1; return; } /* istanbul ignore else */ if (this.onArrowKey()) { this.focusedItemIndex--; } } /** * Event handler for arrow key down event thats focuses on a item */ onArrowKeyDown() { /* istanbul ignore else */ if (this.focusedItemIndex === this.availableItems.length - 1) { this.focusedItemIndex = 0; return; } /* istanbul ignore else */ if (this.onArrowKey()) { this.focusedItemIndex++; } } onArrowKey() { /* istanbul ignore else */ if (this.focusedItemIndex === null) { this.focusedItemIndex = 0; return false; } return true; } /** * will reset the element that is marked active using arrow keys */ resetArrowKeyActiveElement() { this.focusedItemIndex = null; } /** * Toggle the select all option */ toggleSelectAll(close, emitChange) { this.selectAll = !this.selectAll; if (this.selectAll) { this.selectedItems = [...this.selectedItems, ...this.availableItems]; this.availableItems = []; } else { this.availableItems = [...this.selectedItems, ...this.availableItems]; this.selectedItems = []; } this.selectedItems.sort(this.config.customComparator); this.availableItems.sort(this.config.customComparator); this.valueChanged(); this.closeSelectDropdown(); this.openStateChange(); this.resetArrowKeyActiveElement(); } /** * Check if all options selected */ areAllSelected() { return this.selectedItems.length === this.options.length; } } /** @nocollapse */ NgxSelectDropdownComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NgxSelectDropdownComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: SelectDropDownService }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ NgxSelectDropdownComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: NgxSelectDropdownComponent, selector: "ngx-select-dropdown", inputs: { _value: "_value", options: "options", config: "config", multiple: "multiple", disabled: "disabled", instanceId: "instanceId", selectedItemTemplate: "selectedItemTemplate", optionItemTemplate: "optionItemTemplate", notFoundTemplate: "notFoundTemplate", dropdownButtonTemplate: "dropdownButtonTemplate" }, outputs: { change: "change", searchChange: "searchChange", open: "open", close: "close" }, host: { listeners: { "click": "clickInsideComponent()", "blur": "blur()", "focus": "focus()", "document:click": "clickOutsideComponent()", "document:keydown": "KeyPressOutsideComponent()", "keydown": "handleKeyboardEvent($event)" }, properties: { "attr.tabindex": "this.tabindex" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((() => NgxSelectDropdownComponent)), multi: true, }, ], viewQueries: [{ propertyName: "dropDownElement", first: true, predicate: ["dropdownList"], descendants: true }, { propertyName: "availableOptions", predicate: ["availableOption"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"ngx-dropdown-container\">\n <div [ngClass]=\"{ 'ngx-disabled': disabled }\" *ngIf=\"!toggleDropdown\" (click)=\"openSelectDropdown()\">\n <ng-container [ngTemplateOutlet]=\"dropdownButtonTemplate || dropdownButton\"></ng-container>\n </div>\n <div [ngClass]=\"{ 'ngx-disabled': disabled }\" *ngIf=\"toggleDropdown\" (click)=\"closeSelectDropdown()\">\n <ng-container [ngTemplateOutlet]=\"dropdownButtonTemplate || dropdownButton\"></ng-container>\n </div>\n <div #dropdownList class=\"ngx-dropdown-list-container\" *ngIf=\"toggleDropdown\" [style.maxHeight]=\"config.height\"\n [style.top]=\"top\">\n <div class=\"search-container\" *ngIf=\"config.search\">\n <input (change)=\"changeSearchText($event)\" [style.direction]=\"config.inputDirection\" name=\"search-text\"\n (input)=\"searchTextChanged()\" [(ngModel)]=\"searchText\" tabindex=\"-1\" autocomplete=\"off\" />\n <label [ngClass]=\"{ active: searchText }\">\n <span class=\"nsdicon-search\"></span>\n {{ config.searchPlaceholder }}</label>\n </div>\n <div *ngIf=\"config.enableSelectAll && multiple\">\n <div class=\"select-options\">\n <label (click)=\"toggleSelectAll(true, true)\">\n <input type=\"checkbox\" class=\"filled-in\" [(ngModel)]=\"selectAll\" />\n <span>{{ config.selectAllLabel }}</span>\n </label>\n </div>\n </div>\n <div class=\"selected-items\">\n <div class=\"selected-item\" tabindex=\"-1\" *ngFor=\"let selected of selectedItems; let i = index\"\n (click)=\"deselectItem(selected, i)\" (mousedown)=\"optionMouseDown = true\">\n <ng-container [ngTemplateOutlet]=\"selectedItemTemplate || selectedTemplate\"\n [ngTemplateOutletContext]=\"{item: selected, config: config}\"></ng-container>\n\n </div>\n </div>\n <hr *ngIf=\"selectedItems.length > 0 && availableItems.length > 0\" />\n <div class=\"available-items\">\n <div class=\"available-item\" #availableOption *ngFor=\"\n let item of availableItems\n | filterBy: searchText:config.searchOnKey\n | limitTo: config.limitTo;\n let i = index\n \" tabindex=\"-1\" [ngClass]=\"{\n active: focusedItemIndex == i && !item.disabled,\n disabled: item.disabled\n }\" (click)=\"selectItem(item, i)\" (mousedown)=\"optionMouseDown = true\">\n <ng-container [ngTemplateOutlet]=\"optionItemTemplate || availableItemTemplate\"\n [ngTemplateOutletContext]=\"{item: item, config: config}\"></ng-container>\n </div>\n <ng-container [ngTemplateOutlet]=\"notFoundTemplate || notFound\"></ng-container>\n </div>\n </div>\n</div>\n\n<ng-template #notFound>\n <div *ngIf=\"showNotFound\">{{ config.noResultsFound }}</div>\n</ng-template>\n\n<ng-template #availableItemTemplate let-item=\"item\" let-config=\"config\">\n <span>\n {{\n config.displayFn\n ? config.displayFn(item)\n : item[config.displayKey] || item\n }}\n </span>\n</ng-template>\n<ng-template #selectedTemplate let-item=\"item\" let-config=\"config\">\n <span class=\"nsdicon-close\">x</span>\n <span>\n {{\n config.displayFn\n ? config.displayFn(item)\n : item[config.displayKey] || item\n }}\n </span>\n</ng-template>\n\n<ng-template #dropdownButton>\n <button type=\"button\" tabindex=\"-1\" class=\"ngx-dropdown-button\" [ngClass]=\"{ 'ngx-disabled': disabled }\"\n [disabled]=\"disabled\">\n <span class=\"display-text\">{{ selectedDisplayText }} </span>\n <span class=\"nsdicon-angle-down\" [ngClass]=\"{'up': toggleDropdown }\"></span>\n </button>\n</ng-template>", styles: [".ngx-dropdown-container{width:100%;position:relative}.ngx-dropdown-container .ngx-dropdown-button{display:inline-block;margin-bottom:0;font-weight:400;line-height:1.42857143;vertical-align:middle;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;user-select:none;border:1px solid #ccc;border-radius:4px;color:#333;background-color:#fff;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis;text-align:left}.ngx-dropdown-container .ngx-dropdown-button span{display:inline;vertical-align:middle}.ngx-dropdown-container .ngx-dropdown-button .nsdicon-angle-down{right:5px;position:relative;float:right;transition:transform .2s ease}.ngx-dropdown-container .ngx-dropdown-button .nsdicon-angle-down:before{border-style:solid;border-width:.1em .1em 0 0;content:\"\";display:inline-block;height:10px;position:relative;vertical-align:text-top;width:10px;top:0;transform:rotate(135deg)}.ngx-dropdown-container .ngx-dropdown-button .nsdicon-angle-down.up{transform:rotate(180deg);transition:transform .2s ease}.ngx-dropdown-container .ngx-dropdown-button{width:100%;min-height:30px;padding:5px 10px;background-color:#fff}.ngx-dropdown-container .ngx-dropdown-button .display-text{display:inline-block;width:calc(100% - 20px)}.ngx-dropdown-container .ngx-dropdown-list-container{box-sizing:border-box;border:1px solid rgba(0,0,0,.15);border-radius:4px;padding-left:10px;padding-right:10px;z-index:999999999;width:100%;background-clip:padding-box;background:white;position:absolute;box-shadow:5px 5px 5px #00000036;overflow-y:auto}.ngx-dropdown-container .ngx-dropdown-list-container .select-options{padding-top:10px}.ngx-dropdown-container .ngx-dropdown-list-container .select-options .filled-in:checked+span:not(.lever):after,.ngx-dropdown-container .ngx-dropdown-list-container .select-options .filled-in:not(:checked)+span:not(.lever):after{height:15px;width:15px}.ngx-dropdown-container .ngx-dropdown-list-container .select-options .filled-in:checked+span:not(.lever):after{border-color:#337ab7;background-color:#337ab7}.ngx-dropdown-container .ngx-dropdown-list-container .select-options .filled-in:checked+span:not(.lever):before{top:-2px;left:1px;width:5px;height:11px}.ngx-dropdown-container .ngx-dropdown-list-container .select-options [type=checkbox]+span:not(.lever){line-height:15px;height:15px;padding-left:25px}.ngx-dropdown-container .ngx-dropdown-list-container .search-container{position:relative;padding-top:10px;margin-top:5px}.ngx-dropdown-container .ngx-dropdown-list-container .search-container input{background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;border-radius:0;outline:none;height:2rem;width:100%;font-size:13px;margin:0;padding:0;box-shadow:none;box-sizing:content-box;transition:all .3s}.ngx-dropdown-container .ngx-dropdown-list-container .search-container input:focus{border-bottom:1px solid #26a69a}.ngx-dropdown-container .ngx-dropdown-list-container .search-container input:focus+label{transform:translateY(-2px) scale(.8);transform-origin:0 0}.ngx-dropdown-container .ngx-dropdown-list-container .search-container label{color:#9e9e9e;position:absolute;top:0;left:0;height:100%;font-size:1rem;cursor:text;transition:transform .2s ease-out;transform-origin:0% 100%;text-align:initial;transform:translateY(12px);pointer-events:none}.ngx-dropdown-container .ngx-dropdown-list-container .search-container label.active{transform:translateY(-2px) scale(.8);transform-origin:0 0}.ngx-dropdown-container .ngx-dropdown-list-container .available-items,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items{margin-top:1rem;margin-bottom:1rem;list-style-type:none;padding-left:0}.ngx-dropdown-container .ngx-dropdown-list-container .available-items.selected-items .selected-item,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items.selected-items .selected-item{background-color:#337ab7;color:#fff;margin-bottom:2px}.ngx-dropdown-container .ngx-dropdown-list-container .available-items.selected-items .selected-item .nsdicon-close,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items.selected-items .selected-item .nsdicon-close{font-weight:700;font-size:large}.ngx-dropdown-container .ngx-dropdown-list-container .available-items.available-items .available-item.active,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items.available-items .available-item.active{background-color:#337ab7;color:#fff}.ngx-dropdown-container .ngx-dropdown-list-container .available-items .available-item,.ngx-dropdown-container .ngx-dropdown-list-container .available-items .selected-item,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items .available-item,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items .selected-item{font-size:inherit;cursor:pointer;display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:normal}.ngx-dropdown-container .ngx-disabled{pointer-events:none;background-color:#e9ecef;opacity:1;cursor:no-drop}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: FilterByPipe, name: "filterBy" }, { kind: "pipe", type: LimitToPipe, name: "limitTo" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NgxSelectDropdownComponent, decorators: [{ type: Component, args: [{ selector: "ngx-select-dropdown", providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((() => NgxSelectDropdownComponent)), multi: true, }, ], template: "<div class=\"ngx-dropdown-container\">\n <div [ngClass]=\"{ 'ngx-disabled': disabled }\" *ngIf=\"!toggleDropdown\" (click)=\"openSelectDropdown()\">\n <ng-container [ngTemplateOutlet]=\"dropdownButtonTemplate || dropdownButton\"></ng-container>\n </div>\n <div [ngClass]=\"{ 'ngx-disabled': disabled }\" *ngIf=\"toggleDropdown\" (click)=\"closeSelectDropdown()\">\n <ng-container [ngTemplateOutlet]=\"dropdownButtonTemplate || dropdownButton\"></ng-container>\n </div>\n <div #dropdownList class=\"ngx-dropdown-list-container\" *ngIf=\"toggleDropdown\" [style.maxHeight]=\"config.height\"\n [style.top]=\"top\">\n <div class=\"search-container\" *ngIf=\"config.search\">\n <input (change)=\"changeSearchText($event)\" [style.direction]=\"config.inputDirection\" name=\"search-text\"\n (input)=\"searchTextChanged()\" [(ngModel)]=\"searchText\" tabindex=\"-1\" autocomplete=\"off\" />\n <label [ngClass]=\"{ active: searchText }\">\n <span class=\"nsdicon-search\"></span>\n {{ config.searchPlaceholder }}</label>\n </div>\n <div *ngIf=\"config.enableSelectAll && multiple\">\n <div class=\"select-options\">\n <label (click)=\"toggleSelectAll(true, true)\">\n <input type=\"checkbox\" class=\"filled-in\" [(ngModel)]=\"selectAll\" />\n <span>{{ config.selectAllLabel }}</span>\n </label>\n </div>\n </div>\n <div class=\"selected-items\">\n <div class=\"selected-item\" tabindex=\"-1\" *ngFor=\"let selected of selectedItems; let i = index\"\n (click)=\"deselectItem(selected, i)\" (mousedown)=\"optionMouseDown = true\">\n <ng-container [ngTemplateOutlet]=\"selectedItemTemplate || selectedTemplate\"\n [ngTemplateOutletContext]=\"{item: selected, config: config}\"></ng-container>\n\n </div>\n </div>\n <hr *ngIf=\"selectedItems.length > 0 && availableItems.length > 0\" />\n <div class=\"available-items\">\n <div class=\"available-item\" #availableOption *ngFor=\"\n let item of availableItems\n | filterBy: searchText:config.searchOnKey\n | limitTo: config.limitTo;\n let i = index\n \" tabindex=\"-1\" [ngClass]=\"{\n active: focusedItemIndex == i && !item.disabled,\n disabled: item.disabled\n }\" (click)=\"selectItem(item, i)\" (mousedown)=\"optionMouseDown = true\">\n <ng-container [ngTemplateOutlet]=\"optionItemTemplate || availableItemTemplate\"\n [ngTemplateOutletContext]=\"{item: item, config: config}\"></ng-container>\n </div>\n <ng-container [ngTemplateOutlet]=\"notFoundTemplate || notFound\"></ng-container>\n </div>\n </div>\n</div>\n\n<ng-template #notFound>\n <div *ngIf=\"showNotFound\">{{ config.noResultsFound }}</div>\n</ng-template>\n\n<ng-template #availableItemTemplate let-item=\"item\" let-config=\"config\">\n <span>\n {{\n config.displayFn\n ? config.displayFn(item)\n : item[config.displayKey] || item\n }}\n </span>\n</ng-template>\n<ng-template #selectedTemplate let-item=\"item\" let-config=\"config\">\n <span class=\"nsdicon-close\">x</span>\n <span>\n {{\n config.displayFn\n ? config.displayFn(item)\n : item[config.displayKey] || item\n }}\n </span>\n</ng-template>\n\n<ng-template #dropdownButton>\n <button type=\"button\" tabindex=\"-1\" class=\"ngx-dropdown-button\" [ngClass]=\"{ 'ngx-disabled': disabled }\"\n [disabled]=\"disabled\">\n <span class=\"display-text\">{{ selectedDisplayText }} </span>\n <span class=\"nsdicon-angle-down\" [ngClass]=\"{'up': toggleDropdown }\"></span>\n </button>\n</ng-template>", styles: [".ngx-dropdown-container{width:100%;position:relative}.ngx-dropdown-container .ngx-dropdown-button{display:inline-block;margin-bottom:0;font-weight:400;line-height:1.42857143;vertical-align:middle;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;user-select:none;border:1px solid #ccc;border-radius:4px;color:#333;background-color:#fff;white-space:nowrap;overflow-x:hidden;text-overflow:ellipsis;text-align:left}.ngx-dropdown-container .ngx-dropdown-button span{display:inline;vertical-align:middle}.ngx-dropdown-container .ngx-dropdown-button .nsdicon-angle-down{right:5px;position:relative;float:right;transition:transform .2s ease}.ngx-dropdown-container .ngx-dropdown-button .nsdicon-angle-down:before{border-style:solid;border-width:.1em .1em 0 0;content:\"\";display:inline-block;height:10px;position:relative;vertical-align:text-top;width:10px;top:0;transform:rotate(135deg)}.ngx-dropdown-container .ngx-dropdown-button .nsdicon-angle-down.up{transform:rotate(180deg);transition:transform .2s ease}.ngx-dropdown-container .ngx-dropdown-button{width:100%;min-height:30px;padding:5px 10px;background-color:#fff}.ngx-dropdown-container .ngx-dropdown-button .display-text{display:inline-block;width:calc(100% - 20px)}.ngx-dropdown-container .ngx-dropdown-list-container{box-sizing:border-box;border:1px solid rgba(0,0,0,.15);border-radius:4px;padding-left:10px;padding-right:10px;z-index:999999999;width:100%;background-clip:padding-box;background:white;position:absolute;box-shadow:5px 5px 5px #00000036;overflow-y:auto}.ngx-dropdown-container .ngx-dropdown-list-container .select-options{padding-top:10px}.ngx-dropdown-container .ngx-dropdown-list-container .select-options .filled-in:checked+span:not(.lever):after,.ngx-dropdown-container .ngx-dropdown-list-container .select-options .filled-in:not(:checked)+span:not(.lever):after{height:15px;width:15px}.ngx-dropdown-container .ngx-dropdown-list-container .select-options .filled-in:checked+span:not(.lever):after{border-color:#337ab7;background-color:#337ab7}.ngx-dropdown-container .ngx-dropdown-list-container .select-options .filled-in:checked+span:not(.lever):before{top:-2px;left:1px;width:5px;height:11px}.ngx-dropdown-container .ngx-dropdown-list-container .select-options [type=checkbox]+span:not(.lever){line-height:15px;height:15px;padding-left:25px}.ngx-dropdown-container .ngx-dropdown-list-container .search-container{position:relative;padding-top:10px;margin-top:5px}.ngx-dropdown-container .ngx-dropdown-list-container .search-container input{background-color:transparent;border:none;border-bottom:1px solid #9e9e9e;border-radius:0;outline:none;height:2rem;width:100%;font-size:13px;margin:0;padding:0;box-shadow:none;box-sizing:content-box;transition:all .3s}.ngx-dropdown-container .ngx-dropdown-list-container .search-container input:focus{border-bottom:1px solid #26a69a}.ngx-dropdown-container .ngx-dropdown-list-container .search-container input:focus+label{transform:translateY(-2px) scale(.8);transform-origin:0 0}.ngx-dropdown-container .ngx-dropdown-list-container .search-container label{color:#9e9e9e;position:absolute;top:0;left:0;height:100%;font-size:1rem;cursor:text;transition:transform .2s ease-out;transform-origin:0% 100%;text-align:initial;transform:translateY(12px);pointer-events:none}.ngx-dropdown-container .ngx-dropdown-list-container .search-container label.active{transform:translateY(-2px) scale(.8);transform-origin:0 0}.ngx-dropdown-container .ngx-dropdown-list-container .available-items,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items{margin-top:1rem;margin-bottom:1rem;list-style-type:none;padding-left:0}.ngx-dropdown-container .ngx-dropdown-list-container .available-items.selected-items .selected-item,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items.selected-items .selected-item{background-color:#337ab7;color:#fff;margin-bottom:2px}.ngx-dropdown-container .ngx-dropdown-list-container .available-items.selected-items .selected-item .nsdicon-close,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items.selected-items .selected-item .nsdicon-close{font-weight:700;font-size:large}.ngx-dropdown-container .ngx-dropdown-list-container .available-items.available-items .available-item.active,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items.available-items .available-item.active{background-color:#337ab7;color:#fff}.ngx-dropdown-container .ngx-dropdown-list-container .available-items .available-item,.ngx-dropdown-container .ngx-dropdown-list-container .available-items .selected-item,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items .available-item,.ngx-dropdown-container .ngx-dropdown-list-container .selected-items .selected-item{font-size:inherit;cursor:pointer;display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:normal}.ngx-dropdown-container .ngx-disabled{pointer-events:none;background-color:#e9ecef;opacity:1;cursor:no-drop}\n"] }] }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: SelectDropDownService }]; }, propDecorators: { _value: [{ type: Input }], options: [{ type: Input }], config: [{ type: Input }], multiple: [{ type: Input }], disabled: [{ type: Input }], instanceId: [{ type: Input }], selectedItemTemplate: [{ type: Input }], optionItemTemplate: [{ type: Input }], notFoundTemplate: [{ type: Input }], dropdownButtonTemplate: [{ type: Input }], change: [{ type: Output }], searchChange: [{ type: Output }], open: [{ type: Output }], close: [{ type: Output }], availableOptions: [{ type: ViewChildren, args: ["availableOption"] }], clickInsideComponent: [{ type: HostListener, args: ["click"] }], dropDownElement: [{ type: ViewChild, args: ["dropdownList"] }], blur: [{ type: HostListener, args: ["blur"] }], focus: [{ type: HostListener, args: ["focus"] }], clickOutsideComponent: [{ type: HostListener, args: ["document:click"] }], KeyPressOutsideComponent: [{ type: HostListener, args: ["document:keydown"] }], tabindex: [{ type: HostBinding, args: ["attr.tabindex"] }], handleKeyboardEvent: [{ type: HostListener, args: ["keydown", ["$event"]] }] } }); class SelectDropDownModule { } /** @nocollapse */ SelectDropDownModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SelectDropDownModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); /** @nocollapse */ SelectDropDownModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.2.12", ngImport: i0, type: SelectDropDownModule, declarations: [NgxSelectDropdownComponent, FilterByPipe, LimitToPipe], imports: [CommonModule, FormsModule], exports: [NgxSelectDropdownComponent, FilterByPipe, LimitToPipe] }); /** @nocollapse */ SelectDropDownModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SelectDropDownModule, imports: [CommonModule, FormsModule] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: SelectDropDownModule, decorators: [{ type: NgModule, args: [{ declarations: [NgxSelectDropdownComponent, FilterByPipe, LimitToPipe], imports: [CommonModule, FormsModule], exports: [NgxSelectDropdownComponent, FilterByPipe, LimitToPipe], providers: [], }] }] }); /* * Public API Surface of ngx-select-dropdown */ /** * Generated bundle index. Do not edit. */ export { FilterByPipe, LimitToPipe, NgxSelectDropdownComponent, SelectDropDownModule, SelectDropDownService }; //# sourceMappingURL=ngx-select-dropdown.mjs.map