Advertisement
Guest User

Untitled

a guest
Jul 23rd, 2019
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.94 KB | None | 0 0
  1. import { FocusMonitor } from '@angular/cdk/a11y';
  2. import {
  3. AfterViewInit, Component, DoCheck, ElementRef, EventEmitter, HostBinding,
  4. Input, OnChanges, OnDestroy, OnInit, Optional, Output, Self
  5. } from '@angular/core';
  6. import { ControlValueAccessor, FormControl, FormGroupDirective, NgControl, NgForm } from '@angular/forms';
  7. import { CanUpdateErrorState, ErrorStateMatcher } from '@angular/material/core';
  8. import { MatFormField, MatFormFieldControl } from '@angular/material/form-field';
  9. import { Subject } from 'rxjs';
  10.  
  11. // tslint:disable-next-line: no-conflicting-life-cycle-hooks
  12. @Component({
  13. selector: 'am-multi-select',
  14. templateUrl: './am-multi-select.component.html',
  15. styleUrls: ['./am-multi-select.component.scss'],
  16. providers: [
  17. {
  18. provide: MatFormFieldControl,
  19. useExisting: AmMultiSelectComponent
  20. }
  21. ]
  22. })
  23. export class AmMultiSelectComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy,
  24. DoCheck, ControlValueAccessor, MatFormFieldControl<any | Array<any>>, CanUpdateErrorState {
  25. get id(): string {
  26. return this._id;
  27. }
  28. @Input()
  29. set id(value: string) {
  30. this._id = value || this._uid;
  31. }
  32. get value(): any | Array<any> {
  33. return this._value;
  34. }
  35. @Input()
  36. set value(value: any | Array<any>) {
  37. this._value = value;
  38. this.onChangeCallback(value);
  39. this.stateChanges.next();
  40. }
  41.  
  42. @Input()
  43. get required(): boolean {
  44. return this._required;
  45. }
  46. set required(value: boolean) {
  47. this._required = !!value;
  48. this.stateChanges.next();
  49. }
  50.  
  51. @Input()
  52. get disabled(): boolean {
  53. if (this.ngControl && this.ngControl.disabled !== null) {
  54. return this.ngControl.disabled;
  55. }
  56. }
  57. set disabled(value: boolean) {
  58.  
  59. // Browsers may not fire the blur event if the input is disabled too quickly.
  60. // Reset from here to ensure that the element doesn't become stuck.
  61. if (this.focused) {
  62. this.focused = false;
  63. this.stateChanges.next();
  64. }
  65. }
  66.  
  67. @Input()
  68. get placeholder(): string {
  69. return this._placeholder;
  70. }
  71. set placeholder(value: string) {
  72. this._placeholder = value;
  73. this.stateChanges.next();
  74. }
  75.  
  76. @HostBinding('class.floating')
  77. get shouldLabelFloat(): boolean {
  78. return this.focused || !this.empty;
  79. }
  80.  
  81. get empty(): boolean {
  82. return this.value === undefined || (this.value instanceof Array && this.value.length === 0);
  83. }
  84.  
  85. @Input() set selectedOptions(selectedOptions: Array<any>) {
  86. setTimeout(() => {
  87. if (selectedOptions && selectedOptions.length > 0) {
  88. this.value = selectedOptions;
  89. this._selectedOptions = selectedOptions;
  90. } else {
  91. this.value = [];
  92. this._selectedOptions = [];
  93. }
  94. }, 1000);
  95.  
  96. }
  97. get selectedOptions(): Array<any> {
  98. return this._selectedOptions;
  99. }
  100.  
  101. constructor(
  102. @Optional() @Self() ngControl: NgControl,
  103. @Optional() public parentForm: NgForm,
  104. @Optional() public parentFormGroup: FormGroupDirective,
  105. public defaultErrorStateMatcher: ErrorStateMatcher,
  106. fm: FocusMonitor,
  107. private elRef: ElementRef<HTMLElement>,
  108. private matFormField: MatFormField
  109. ) {
  110. this.ngControl = ngControl;
  111.  
  112. // Setting the value accessor directly (instead of using
  113. // the providers) to avoid running into a circular import.
  114. if (this.ngControl !== undefined) { this.ngControl.valueAccessor = this; }
  115.  
  116. // Force setter to be called in case id was not specified.
  117. this.id = this.id;
  118.  
  119. // MatFormFieldControl
  120. fm.monitor(elRef.nativeElement, true).subscribe(origin => {
  121. this.focused = !!origin;
  122. this.stateChanges.next();
  123. });
  124. // end MatFormFieldControl
  125. }
  126. static nextId = 0;
  127. private _uid = 'am-multi-select-${AmMatMenuComponent.nextId++}';
  128. menuValue: string;
  129. stateChanges = new Subject<void>();
  130. controlType = 'am-multi-select';
  131. errorState = false;
  132. autofilled = false;
  133. focused = false;
  134. ngControl: NgControl;
  135.  
  136. @HostBinding('attr.aria-describedby') describedBy = '';
  137.  
  138. private _id: string;
  139.  
  140. private _value: any | Array<any>;
  141. private _required = false;
  142. private _placeholder: string;
  143. // End MatFormFieldControl
  144.  
  145. private _onDestroy = new Subject<void>();
  146. formControl: FormControl = new FormControl();
  147.  
  148. @Input() options: Array<any>;
  149. private _selectedOptions: Array<any>;
  150.  
  151. @Output() selectedOptionsChange = new EventEmitter();
  152.  
  153. @Input() buttonTrigger: boolean;
  154. @Input() buttonTriggerText: string;
  155. @Input() groupClassifier: Function;
  156. @Input() errorStateMatcher: ErrorStateMatcher;
  157. @Output() valueChange = new EventEmitter();
  158. @Output() openedChangeEmitter = new EventEmitter();
  159. @Output() clearValueEmitter = new EventEmitter();
  160. @Output() blur = new EventEmitter();
  161.  
  162. @Output() selectionChange = new EventEmitter<any>();
  163. readonly = false;
  164.  
  165. @Input() checkboxPosition = 'before';
  166.  
  167. onNgModelChange(event): void {
  168. if (event !== undefined && event.length > 0) {
  169. this.selectedOptionsChange.emit(this.selectedOptions);
  170. this.value = this.selectedOptions;
  171. } else {
  172. this.value = [];
  173. }
  174. }
  175. @Input() textMapper = (option: any) => {
  176. return option['name'];
  177. }
  178. @Input() valueMapper = (option: any) => {
  179. return option['id'];
  180. }
  181.  
  182. @Input() compareFn = (c1: any, c2: any) => {
  183. return c1.id === c2.id;
  184. }
  185.  
  186. // MatFormFieldControl
  187. setDescribedByIds(ids: Array<string>) {
  188. this.describedBy = ids.join(' ');
  189. }
  190.  
  191. onContainerClick(event: MouseEvent) {
  192. const eventTarget = (event.target as Element);
  193.  
  194. if (eventTarget.className.toLowerCase().includes('mat-form-field-infix')
  195. || eventTarget.tagName.toLowerCase() === 'am-multi-select') {
  196. this.elRef.nativeElement.querySelector<HTMLElement>('mat-select > .mat-select-trigger').click();
  197. }
  198. }
  199. // end MatFormFieldControl
  200.  
  201. // ControlValueAccessor
  202. onChangeCallback: (value: any | Array<any>) => void = () => { };
  203. onTouchedCallback: () => void = () => { };
  204.  
  205. writeValue(val: any | Array<any>): void {
  206. if (val !== this._value) {
  207. this._value = val;
  208. this.stateChanges.next();
  209. }
  210. }
  211.  
  212. registerOnChange(fn: any): void {
  213. this.onChangeCallback = fn;
  214. }
  215.  
  216. registerOnTouched(fn: any): void {
  217. this.onTouchedCallback = fn;
  218. }
  219. // end ControlValueAccessor
  220.  
  221. ngOnInit() {
  222.  
  223. }
  224. ngAfterViewInit() {
  225. }
  226.  
  227. ngOnChanges() {
  228. this.stateChanges.next();
  229. }
  230.  
  231. ngDoCheck() {
  232. if (this.ngControl) {
  233. this.updateErrorState();
  234. }
  235. this.readonly = (this.matFormField._elementRef.nativeElement as HTMLElement).classList.contains('mat-form-field-disabled');
  236. }
  237.  
  238. ngOnDestroy() {
  239. this._onDestroy.next();
  240. this._onDestroy.complete();
  241. }
  242.  
  243. updateErrorState() {
  244. const oldState = this.errorState;
  245. const parent = this.parentFormGroup || this.parentForm;
  246. const matcher = this.errorStateMatcher || this.defaultErrorStateMatcher;
  247. const control = this.ngControl ? this.ngControl.control as FormControl : null;
  248. const newState = matcher.isErrorState(control, parent);
  249.  
  250. if (newState !== oldState) {
  251. this.errorState = newState;
  252. this.stateChanges.next();
  253. }
  254. }
  255.  
  256. clearValue() {
  257. this.value = null;
  258. this.focused = false;
  259. this.clearValueEmitter.emit();
  260. this.blur.emit();
  261. }
  262. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement