ngx-select-dropdown
Version:
A angular(4+) select dropdown for single select or multiselct module.
808 lines (799 loc) • 49 kB
JavaScript
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 = Object.assign({}, config);
}
for (const key of Object.keys(config)) {
this.config[key] = this.config[key] ? this.config[key] : config[key];
}
this.config = Object.assign({}, 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