Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { FocusMonitor } from '@angular/cdk/a11y';
- import {
- AfterViewInit, Component, DoCheck, ElementRef, EventEmitter, HostBinding,
- Input, OnChanges, OnDestroy, OnInit, Optional, Output, Self
- } from '@angular/core';
- import { ControlValueAccessor, FormControl, FormGroupDirective, NgControl, NgForm } from '@angular/forms';
- import { CanUpdateErrorState, ErrorStateMatcher } from '@angular/material/core';
- import { MatFormField, MatFormFieldControl } from '@angular/material/form-field';
- import { Subject } from 'rxjs';
- // tslint:disable-next-line: no-conflicting-life-cycle-hooks
- @Component({
- selector: 'am-multi-select',
- templateUrl: './am-multi-select.component.html',
- styleUrls: ['./am-multi-select.component.scss'],
- providers: [
- {
- provide: MatFormFieldControl,
- useExisting: AmMultiSelectComponent
- }
- ]
- })
- export class AmMultiSelectComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy,
- DoCheck, ControlValueAccessor, MatFormFieldControl<any | Array<any>>, CanUpdateErrorState {
- get id(): string {
- return this._id;
- }
- @Input()
- set id(value: string) {
- this._id = value || this._uid;
- }
- get value(): any | Array<any> {
- return this._value;
- }
- @Input()
- set value(value: any | Array<any>) {
- this._value = value;
- this.onChangeCallback(value);
- this.stateChanges.next();
- }
- @Input()
- get required(): boolean {
- return this._required;
- }
- set required(value: boolean) {
- this._required = !!value;
- this.stateChanges.next();
- }
- @Input()
- get disabled(): boolean {
- if (this.ngControl && this.ngControl.disabled !== null) {
- return this.ngControl.disabled;
- }
- }
- set disabled(value: boolean) {
- // Browsers may not fire the blur event if the input is disabled too quickly.
- // Reset from here to ensure that the element doesn't become stuck.
- if (this.focused) {
- this.focused = false;
- this.stateChanges.next();
- }
- }
- @Input()
- get placeholder(): string {
- return this._placeholder;
- }
- set placeholder(value: string) {
- this._placeholder = value;
- this.stateChanges.next();
- }
- @HostBinding('class.floating')
- get shouldLabelFloat(): boolean {
- return this.focused || !this.empty;
- }
- get empty(): boolean {
- return this.value === undefined || (this.value instanceof Array && this.value.length === 0);
- }
- @Input() set selectedOptions(selectedOptions: Array<any>) {
- setTimeout(() => {
- if (selectedOptions && selectedOptions.length > 0) {
- this.value = selectedOptions;
- this._selectedOptions = selectedOptions;
- } else {
- this.value = [];
- this._selectedOptions = [];
- }
- }, 1000);
- }
- get selectedOptions(): Array<any> {
- return this._selectedOptions;
- }
- constructor(
- @Optional() @Self() ngControl: NgControl,
- @Optional() public parentForm: NgForm,
- @Optional() public parentFormGroup: FormGroupDirective,
- public defaultErrorStateMatcher: ErrorStateMatcher,
- fm: FocusMonitor,
- private elRef: ElementRef<HTMLElement>,
- private matFormField: MatFormField
- ) {
- this.ngControl = ngControl;
- // Setting the value accessor directly (instead of using
- // the providers) to avoid running into a circular import.
- if (this.ngControl !== undefined) { this.ngControl.valueAccessor = this; }
- // Force setter to be called in case id was not specified.
- this.id = this.id;
- // MatFormFieldControl
- fm.monitor(elRef.nativeElement, true).subscribe(origin => {
- this.focused = !!origin;
- this.stateChanges.next();
- });
- // end MatFormFieldControl
- }
- static nextId = 0;
- private _uid = 'am-multi-select-${AmMatMenuComponent.nextId++}';
- menuValue: string;
- stateChanges = new Subject<void>();
- controlType = 'am-multi-select';
- errorState = false;
- autofilled = false;
- focused = false;
- ngControl: NgControl;
- @HostBinding('attr.aria-describedby') describedBy = '';
- private _id: string;
- private _value: any | Array<any>;
- private _required = false;
- private _placeholder: string;
- // End MatFormFieldControl
- private _onDestroy = new Subject<void>();
- formControl: FormControl = new FormControl();
- @Input() options: Array<any>;
- private _selectedOptions: Array<any>;
- @Output() selectedOptionsChange = new EventEmitter();
- @Input() buttonTrigger: boolean;
- @Input() buttonTriggerText: string;
- @Input() groupClassifier: Function;
- @Input() errorStateMatcher: ErrorStateMatcher;
- @Output() valueChange = new EventEmitter();
- @Output() openedChangeEmitter = new EventEmitter();
- @Output() clearValueEmitter = new EventEmitter();
- @Output() blur = new EventEmitter();
- @Output() selectionChange = new EventEmitter<any>();
- readonly = false;
- @Input() checkboxPosition = 'before';
- onNgModelChange(event): void {
- if (event !== undefined && event.length > 0) {
- this.selectedOptionsChange.emit(this.selectedOptions);
- this.value = this.selectedOptions;
- } else {
- this.value = [];
- }
- }
- @Input() textMapper = (option: any) => {
- return option['name'];
- }
- @Input() valueMapper = (option: any) => {
- return option['id'];
- }
- @Input() compareFn = (c1: any, c2: any) => {
- return c1.id === c2.id;
- }
- // MatFormFieldControl
- setDescribedByIds(ids: Array<string>) {
- this.describedBy = ids.join(' ');
- }
- onContainerClick(event: MouseEvent) {
- const eventTarget = (event.target as Element);
- if (eventTarget.className.toLowerCase().includes('mat-form-field-infix')
- || eventTarget.tagName.toLowerCase() === 'am-multi-select') {
- this.elRef.nativeElement.querySelector<HTMLElement>('mat-select > .mat-select-trigger').click();
- }
- }
- // end MatFormFieldControl
- // ControlValueAccessor
- onChangeCallback: (value: any | Array<any>) => void = () => { };
- onTouchedCallback: () => void = () => { };
- writeValue(val: any | Array<any>): void {
- if (val !== this._value) {
- this._value = val;
- this.stateChanges.next();
- }
- }
- registerOnChange(fn: any): void {
- this.onChangeCallback = fn;
- }
- registerOnTouched(fn: any): void {
- this.onTouchedCallback = fn;
- }
- // end ControlValueAccessor
- ngOnInit() {
- }
- ngAfterViewInit() {
- }
- ngOnChanges() {
- this.stateChanges.next();
- }
- ngDoCheck() {
- if (this.ngControl) {
- this.updateErrorState();
- }
- this.readonly = (this.matFormField._elementRef.nativeElement as HTMLElement).classList.contains('mat-form-field-disabled');
- }
- ngOnDestroy() {
- this._onDestroy.next();
- this._onDestroy.complete();
- }
- updateErrorState() {
- const oldState = this.errorState;
- const parent = this.parentFormGroup || this.parentForm;
- const matcher = this.errorStateMatcher || this.defaultErrorStateMatcher;
- const control = this.ngControl ? this.ngControl.control as FormControl : null;
- const newState = matcher.isErrorState(control, parent);
- if (newState !== oldState) {
- this.errorState = newState;
- this.stateChanges.next();
- }
- }
- clearValue() {
- this.value = null;
- this.focused = false;
- this.clearValueEmitter.emit();
- this.blur.emit();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement