ng2-multi-selector
Version:
A small plugin which generates multi-selector control, it supports web api loading.
221 lines (172 loc) • 6.34 kB
text/typescript
import {
AfterViewInit,
ApplicationRef,
Component,
ElementRef,
EventEmitter,
Input,
Output,
ViewChild,
ChangeDetectorRef, TemplateRef
} from "@angular/core";
import {Observable} from 'rxjs/Rx'
export class Ng2MultiSelectorComponent implements AfterViewInit {
//#region Methods
// This callback is fired when view has been initiated.
public ngAfterViewInit(): void {
// Only catch the key up event of search text box if it is supported.
if (this.isSearchBoxAvailable) {
// Catch key up event of search box.
Observable.fromEvent(this.txtSearch.nativeElement, 'keyup')
.map((x: KeyboardEvent) => {
return x.key;
})
.filter((x: string) => {
return (x != null && x.length > 0 && x != ' ');
})
.debounceTime(this.interval)
.distinctUntilChanged()
.subscribe(() => {
// Clear previous search results.
this.items = new Array<any>();
// Emit the search event to outer element.
this.search.emit(this.txtSearch.nativeElement.value)
}
);
}
}
// Check whether item has been chosen or not.
public getItemChosen(item: any): boolean {
return this.getChosenItemIndex(item) != -1;
}
// Find chosen item index in array.
public getChosenItemIndex(item: any): number {
// Items list is empty.
if (this.chosenItems == null || this.chosenItems.length < 1)
return -1;
let results = this.chosenItems.filter((x: any) => {
return x[this.key] == item[this.key]
});
if (results == null || results.length < 1)
return -1;
let result = results[0];
return this.chosenItems.indexOf(result);
}
// Get title which is used for being displayed on search box.
public getChosenItemsTitle(): string {
if (this.chosenItems == null || this.chosenItems.length < 1)
return "";
// Find separation character.
let separation = this.szSeparationCharacter;
if (separation == null || separation.length < 1)
separation = ',';
return this.chosenItems.map(x => {
return x[this.displayProperty]
}).join(separation).slice(0, 255);
}
// Clear chosen items list.
public clearChosenItems(): void {
// Clear button is not supported.
if (!this.isClearButtonAvailable)
return;
// Initiate new array.
this.chosenItems = new Array<any>();
this.changeDetectorRef.detectChanges();
// Fire the update event.
this.updateItemEventEmitter.emit(this.chosenItems);
}
// Select an item in list.
public clickSelectItem(item: any): void {
// Find item index in array.
let itemIndex = this.getChosenItemIndex(item);
// Item hasn't been chosen.
if (itemIndex == null || itemIndex < 0) {
// Maximum selected item exceeded.
if (this.limitItemSelection != null && this.chosenItems.length >= this.limitItemSelection)
return;
this.chosenItems.push(item);
this.updateItemEventEmitter.emit(this.chosenItems);
this.changeDetectorRef.detectChanges();
return;
}
// Remove item from list.
this.chosenItems.splice(itemIndex, 1);
this.updateItemEventEmitter.emit(this.chosenItems);
this.changeDetectorRef.detectChanges();
}
// Get chosen item list.
public getChosenItems(): Array<any> {
return this.chosenItems;
}
//#endregion
//#region Properties
// Inject search box into component.
private txtSearch: ElementRef;
// Key which is for recognizing whether item is in the chosen list or not.
private key: string;
// Property in item which should be display on search box.
private displayProperty: string;
// List of item which should be displayed on drop-down menu.
public items: Array<any>;
// Whether clear button should be available or not.
private isClearButtonAvailable: boolean;
// Whether search box should be available or not.
private isSearchBoxAvailable: boolean;
// How many items should be shown to be selected.
private limitItemAmount: number;
// How many items can be selected.
private limitItemSelection: number;
// Place holder of search box in drop-down list.
private placeholderSearchDropDown: string;
// Place holder of title.
private placeholderTitleDropDown: string;
// Character which is used for dividing searched items.
private szSeparationCharacter: string;
// Whether component is disabled or not.
private disabled: boolean;
// How much time should component raise another one about its changes.
private interval: number;
// Event emitter which is emitted when data should be submitted to server.
private search: EventEmitter<string>;
// This event emitter is emitted when item in list is selected.
private updateItemEventEmitter: EventEmitter<Array<any>>;
// Item which have been chosen.
private chosenItems: Array<any>;
private itemTemplate: TemplateRef<any>;
//#endregion
//#region Constructor
// Initiate components with injectors (as available)
public constructor(private changeDetectorRef: ChangeDetectorRef) {
this.chosenItems = new Array<any>();
this.search = new EventEmitter<string>();
this.updateItemEventEmitter = new EventEmitter<Array<any>>();
this.items = new Array<any>();
// By default, items amount is limited to 10.
this.limitItemAmount = 10;
// By default, interval should be 400ms.
this.interval = 400;
}
//#endregion
}