UNPKG

ngx-select-dropdown

Version:

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

643 lines 86.4 kB
import { FilterByPipe } from "./pipes/filter-by.pipe"; import { Component, Input, EventEmitter, Output, HostListener, ViewChildren, forwardRef, ViewChild, HostBinding, } from "@angular/core"; import { NG_VALUE_ACCESSOR } from "@angular/forms"; import * as i0 from "@angular/core"; import * as i1 from "./ngx-select-dropdown.service"; import * as i2 from "@angular/common"; import * as i3 from "@angular/forms"; import * as i4 from "./pipes/filter-by.pipe"; import * as i5 from "./pipes/limit-to.pipe"; export 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 = {}; /** * 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; } 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() { if (!this.insideKeyPress && !this.optionMouseDown) { 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.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 = []; } 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; 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() { 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", }; /* istanbul ignore else */ if (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; } } /** @nocollapse */ NgxSelectDropdownComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.5", ngImport: i0, type: NgxSelectDropdownComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i1.SelectDropDownService }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ NgxSelectDropdownComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.5", type: NgxSelectDropdownComponent, selector: "ngx-select-dropdown", inputs: { _value: "_value", options: "options", config: "config", multiple: "multiple", disabled: "disabled", instanceId: "instanceId" }, 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 <button *ngIf=\"!toggleDropdown\" type=\"button\" tabindex=\"-1\" class=\"ngx-dropdown-button\"\n [ngClass]=\"{ 'ngx-disabled': disabled }\" [disabled]=\"disabled\" (click)=\"openSelectDropdown()\">\n <span class=\"display-text\">{{ selectedDisplayText }} </span>\n <span class=\"nsdicon-angle-down\"></span>\n\n </button>\n <button *ngIf=\"toggleDropdown\" type=\"button\" tabindex=\"-1\" class=\"ngx-dropdown-button\"\n [ngClass]=\"{ 'ngx-disabled': disabled }\" [disabled]=\"disabled\" (click)=\"closeSelectDropdown()\">\n <span class=\"display-text\">{{ selectedDisplayText }} </span>\n <span class=\"nsdicon-angle-down\" [ngClass]=\"{'up': toggleDropdown }\"></span>\n </button>\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 class=\"select-options\">\n <div class=\"select-all\">Select all</div>\n <div class=\"clear-all\">Clear all</div>\n </div> -->\n <ul class=\"selected-items\">\n <li class=\"selected-item\" tabindex=\"-1\" *ngFor=\"let selected of selectedItems; let i = index\"\n (click)=\"deselectItem(selected, i)\" (mousedown)=\"optionMouseDown = true\">\n <span class=\"nsdicon-close\">x</span>\n <span>\n {{\n config.displayFn\n ? config.displayFn(selected)\n : selected[config.displayKey] || selected\n }}\n </span>\n </li>\n </ul>\n <hr *ngIf=\"selectedItems.length > 0 && availableItems.length > 0\" />\n <ul class=\"available-items\">\n <li 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 {{\n config.displayFn\n ? config.displayFn(item)\n : item[config.displayKey] || item\n }}\n </li>\n <li *ngIf=\"showNotFound\">{{ config.noResultsFound }}</li>\n </ul>\n </div>\n</div>", styles: [".ngx-dropdown-container{width:100%;position:relative}.ngx-dropdown-container 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 button span{display:inline;vertical-align:middle}.ngx-dropdown-container button .nsdicon-angle-down{right:5px;position:relative;float:right;transition:transform .2s ease}.ngx-dropdown-container 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 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 .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 ul{margin-top:1rem;margin-bottom:1rem;list-style-type:none;padding-left:0}.ngx-dropdown-container .ngx-dropdown-list-container ul.selected-items .selected-item{background-color:#337ab7;color:#fff;margin-bottom:2px}.ngx-dropdown-container .ngx-dropdown-list-container ul.selected-items .selected-item .nsdicon-close{font-weight:700;font-size:large}.ngx-dropdown-container .ngx-dropdown-list-container ul.available-items .available-item.active{background-color:#337ab7;color:#fff}.ngx-dropdown-container .ngx-dropdown-list-container ul li{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: 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.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: i4.FilterByPipe, name: "filterBy" }, { kind: "pipe", type: i5.LimitToPipe, name: "limitTo" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.5", 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 <button *ngIf=\"!toggleDropdown\" type=\"button\" tabindex=\"-1\" class=\"ngx-dropdown-button\"\n [ngClass]=\"{ 'ngx-disabled': disabled }\" [disabled]=\"disabled\" (click)=\"openSelectDropdown()\">\n <span class=\"display-text\">{{ selectedDisplayText }} </span>\n <span class=\"nsdicon-angle-down\"></span>\n\n </button>\n <button *ngIf=\"toggleDropdown\" type=\"button\" tabindex=\"-1\" class=\"ngx-dropdown-button\"\n [ngClass]=\"{ 'ngx-disabled': disabled }\" [disabled]=\"disabled\" (click)=\"closeSelectDropdown()\">\n <span class=\"display-text\">{{ selectedDisplayText }} </span>\n <span class=\"nsdicon-angle-down\" [ngClass]=\"{'up': toggleDropdown }\"></span>\n </button>\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 class=\"select-options\">\n <div class=\"select-all\">Select all</div>\n <div class=\"clear-all\">Clear all</div>\n </div> -->\n <ul class=\"selected-items\">\n <li class=\"selected-item\" tabindex=\"-1\" *ngFor=\"let selected of selectedItems; let i = index\"\n (click)=\"deselectItem(selected, i)\" (mousedown)=\"optionMouseDown = true\">\n <span class=\"nsdicon-close\">x</span>\n <span>\n {{\n config.displayFn\n ? config.displayFn(selected)\n : selected[config.displayKey] || selected\n }}\n </span>\n </li>\n </ul>\n <hr *ngIf=\"selectedItems.length > 0 && availableItems.length > 0\" />\n <ul class=\"available-items\">\n <li 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 {{\n config.displayFn\n ? config.displayFn(item)\n : item[config.displayKey] || item\n }}\n </li>\n <li *ngIf=\"showNotFound\">{{ config.noResultsFound }}</li>\n </ul>\n </div>\n</div>", styles: [".ngx-dropdown-container{width:100%;position:relative}.ngx-dropdown-container 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 button span{display:inline;vertical-align:middle}.ngx-dropdown-container button .nsdicon-angle-down{right:5px;position:relative;float:right;transition:transform .2s ease}.ngx-dropdown-container 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 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 .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 ul{margin-top:1rem;margin-bottom:1rem;list-style-type:none;padding-left:0}.ngx-dropdown-container .ngx-dropdown-list-container ul.selected-items .selected-item{background-color:#337ab7;color:#fff;margin-bottom:2px}.ngx-dropdown-container .ngx-dropdown-list-container ul.selected-items .selected-item .nsdicon-close{font-weight:700;font-size:large}.ngx-dropdown-container .ngx-dropdown-list-container ul.available-items .available-item.active{background-color:#337ab7;color:#fff}.ngx-dropdown-container .ngx-dropdown-list-container ul li{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: i1.SelectDropDownService }]; }, propDecorators: { _value: [{ type: Input }], options: [{ type: Input }], config: [{ type: Input }], multiple: [{ type: Input }], disabled: [{ type: Input }], instanceId: [{ 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"]] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXNlbGVjdC1kcm9wZG93bi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc2VsZWN0LWRyb3Bkb3duL3NyYy9saWIvbmd4LXNlbGVjdC1kcm9wZG93bi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc2VsZWN0LWRyb3Bkb3duL3NyYy9saWIvbmd4LXNlbGVjdC1kcm9wZG93bi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEQsT0FBTyxFQUNMLFNBQVMsRUFFVCxLQUFLLEVBQ0wsWUFBWSxFQUNaLE1BQU0sRUFDTixZQUFZLEVBR1osWUFBWSxFQUtaLFVBQVUsRUFDVixTQUFTLEVBQ1QsV0FBVyxHQUNaLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7O0FBYW5ELE1BQU0sT0FBTywwQkFBMEI7SUE4SHJDLFlBQ1UsS0FBd0IsRUFDekIsV0FBdUIsRUFDdEIsZUFBc0M7UUFGdEMsVUFBSyxHQUFMLEtBQUssQ0FBbUI7UUFDekIsZ0JBQVcsR0FBWCxXQUFXLENBQVk7UUFDdEIsb0JBQWUsR0FBZixlQUFlLENBQXVCO1FBM0hoRDs7V0FFRztRQUNhLFlBQU8sR0FBUSxFQUFFLENBQUM7UUFFbEM7O1dBRUc7UUFDYSxXQUFNLEdBQVEsRUFBRSxDQUFDO1FBRWpDOztXQUVHO1FBQ2EsYUFBUSxHQUFHLEtBQUssQ0FBQztRQVVqQzs7V0FFRztRQUNjLFdBQU0sR0FBc0IsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUVoRTs7V0FFRztRQUNjLGlCQUFZLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFFdEU7O1dBRUc7UUFDYyxTQUFJLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFFOUQ7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