ngx-select-dropdown
Version:
A angular(4+) select dropdown for single select or multiselct module.
643 lines • 86.4 kB
JavaScript
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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