Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { Component, ElementRef, Input, OnDestroy, Optional, Self, HostBinding, Output, EventEmitter, ViewEncapsulation } from '@angular/core';
- import { NgControl } from '@angular/forms';
- import { FocusMonitor } from '@angular/cdk/a11y';
- import { coerceBooleanProperty } from '@angular/cdk/coercion';
- import { MatFormFieldControl } from '@angular/material';
- import { Subject } from 'rxjs';
- import * as lodash from 'lodash';
- @Component({
- selector: 'app-auto-complete',
- templateUrl: 'auto-complete.component.html',
- styleUrls: ['./auto-complete.component.scss'],
- encapsulation: ViewEncapsulation.None,
- providers: [{ provide: MatFormFieldControl, useExisting: AutoCompleteComponent }]
- })
- export class AutoCompleteComponent implements MatFormFieldControl<any>, OnDestroy {
- public static nextId = 0;
- public stateChanges = new Subject<void>();
- public focused = false;
- public errorState = false;
- public controlType = 'app-auto-complete';
- @HostBinding('class.floating')
- @HostBinding('attr.aria-describedby') describedBy = '';
- @HostBinding() id = `app-auto-complete-${AutoCompleteComponent.nextId++}`;
- get empty() { return (this.selectedValue === null || this.selectedValue === undefined) && (this.keyword === null || this.keyword === ''); }
- get shouldLabelFloat() { return this.focused || !this.empty; }
- private _placeholder: string;
- @Input()
- get placeholder(): string { return this._placeholder; }
- set placeholder(value: string) { this._placeholder = value; this.stateChanges.next(); }
- private _required = false;
- @Input()
- get required(): boolean { return this._required; }
- set required(value: boolean) { this._required = coerceBooleanProperty(value); this.stateChanges.next(); }
- private _disabled = false;
- @Input()
- get disabled(): boolean { return this._disabled; }
- set disabled(value: boolean) { this._disabled = coerceBooleanProperty(value); this.stateChanges.next(); }
- private _items: any[] = [];
- private filteredItems: any[] = [];
- @Input()
- get items() { return this._items; }
- set items(items: Array<any>) { this._items = items; this.setFilteredItems(lodash.cloneDeep(items), this.keyword); }
- @Output() public valueChange: EventEmitter<any>;
- private _value: any;
- @Input()
- get value(): any { return this._value; }
- set value(value: any) { this._value = value; this.stateChanges.next(); }
- private _key: string;
- @Input()
- get key(): string { return this._key; }
- set key(key: string) { this._key = key; }
- public keyword: string;
- public selectedValue: any;
- public propagateChange = (_: any) => { /* do nothing */ };
- public propagateTouch = (_: any) => { /* do nothing */ };
- constructor(
- private fm: FocusMonitor,
- private elRef: ElementRef,
- @Optional() @Self() public ngControl: NgControl
- ) {
- this.keyword = '';
- this.valueChange = new EventEmitter<any>();
- if (this.ngControl != null) {
- this.ngControl.valueAccessor = this;
- }
- fm.monitor(elRef.nativeElement, true).subscribe(origin => {
- this.focused = !!origin;
- this.stateChanges.next();
- });
- /**
- * To Do : Add Internationalization here!
- */
- }
- ngOnDestroy() {
- this.stateChanges.complete();
- this.fm.stopMonitoring(this.elRef.nativeElement);
- }
- setDescribedByIds(ids: string[]) {
- this.describedBy = ids.join(' ');
- }
- onContainerClick(event: MouseEvent) {
- /**
- * To Do : Write Focus element logic here
- */
- }
- public writeValue(value: any): void {
- this.selectedValue = value;
- this.setKeyword(value);
- this.setFilteredItems(this.items, this.keyword);
- }
- public registerOnChange(fn: (_: any) => {}): void {
- this.propagateChange = fn;
- }
- public registerOnTouched(fn: (_: any) => {}): void {
- this.propagateTouch = fn;
- }
- public _onValueChange(value: any): void {
- this.keyword = value;
- this.selectedValue = null;
- this.setFilteredItems(this.items, this.keyword);
- this.propagateChange(this.selectedValue);
- this.valueChange.emit(value);
- }
- public setDisabledState(isDisabled: boolean): void {
- this.disabled = isDisabled;
- }
- public selectItem(event: any) {
- this.selectedValue = event.option.value;
- this.setKeyword(event.option.value);
- this.propagateChange(event.option.value);
- }
- public getItemLabel(item: any): string {
- if (item) {
- if (this.key) {
- return item[this.key];
- } else {
- let localKey = null;
- for (const objKey in item) {
- if (objKey !== 'id' && objKey !== 'version' && objKey !== 'rootId' && objKey !== 'rootVersion') {
- localKey = objKey;
- break;
- }
- }
- if (localKey) {
- return item[localKey];
- }
- return 'no-key-defined';
- }
- } else {
- return 'no-key-defined';
- }
- }
- private setKeyword(value: any) {
- if (this.key) {
- this.keyword = value[this.key];
- } else {
- let localKey = null;
- for (const objKey in value) {
- if (objKey !== 'id' && objKey !== 'version' && objKey !== 'rootId' && objKey !== 'rootVersion') {
- localKey = objKey;
- break;
- }
- }
- if (localKey) {
- this.keyword = value[localKey];
- }
- }
- }
- private setFilteredItems(items: any[], keyword: string) {
- this.filteredItems = items.filter(item => {
- if (this.key) {
- return (item[this.key] + '').toLowerCase().indexOf((keyword + '').toLowerCase()) > -1;
- } else {
- let localKey = null;
- for (const objKey in item) {
- if (objKey !== 'id' && objKey !== 'version' && objKey !== 'rootId' && objKey !== 'rootVersion') {
- localKey = objKey;
- break;
- }
- }
- if (localKey) {
- return (item[localKey] + '').toLowerCase().indexOf((keyword + '').toLowerCase()) > -1;
- }
- return true;
- }
- });
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement