ipsos-components
Version:
Material Design components for Angular
141 lines (115 loc) • 3.69 kB
text/typescript
import {FocusMonitor} from '@angular/cdk/a11y';
import {coerceBooleanProperty} from '@angular/cdk/coercion';
import {Component, ElementRef, Input, OnDestroy} from '@angular/core';
import {FormBuilder, FormGroup} from '@angular/forms';
import {MatFormFieldControl} from '@angular/material/form-field';
import {Subject} from 'rxjs/Subject';
/** Data structure for holding telephone number. */
export class MyTel {
constructor(public area: string, public exchange: string, public subscriber: string) {}
}
/** Custom `MatFormFieldControl` for telephone number input. */
export class MyTelInput implements MatFormFieldControl<MyTel>, OnDestroy {
static nextId = 0;
parts: FormGroup;
stateChanges = new Subject<void>();
focused = false;
ngControl = null;
errorState = false;
controlType = 'my-tel-input';
get empty() {
let n = this.parts.value;
return !n.area && !n.exchange && !n.subscriber;
}
get shouldLabelFloat() {
return this.focused || !this.empty;
}
id = `my-tel-input-${MyTelInput.nextId++}`;
describedBy = '';
get placeholder() {
return this._placeholder;
}
set placeholder(plh) {
this._placeholder = plh;
this.stateChanges.next();
}
private _placeholder: string;
get required() {
return this._required;
}
set required(req) {
this._required = coerceBooleanProperty(req);
this.stateChanges.next();
}
private _required = false;
get disabled() {
return this._disabled;
}
set disabled(dis) {
this._disabled = coerceBooleanProperty(dis);
this.stateChanges.next();
}
private _disabled = false;
get value(): MyTel | null {
let n = this.parts.value;
if (n.area.length == 3 && n.exchange.length == 3 && n.subscriber.length == 4) {
return new MyTel(n.area, n.exchange, n.subscriber);
}
return null;
}
set value(tel: MyTel | null) {
tel = tel || new MyTel('', '', '');
this.parts.setValue({area: tel.area, exchange: tel.exchange, subscriber: tel.subscriber});
this.stateChanges.next();
}
constructor(fb: FormBuilder, private fm: FocusMonitor, private elRef: ElementRef) {
this.parts = fb.group({
'area': '',
'exchange': '',
'subscriber': '',
});
fm.monitor(elRef.nativeElement, true).subscribe((origin) => {
this.focused = !!origin;
this.stateChanges.next();
});
}
ngOnDestroy() {
this.stateChanges.complete();
this.fm.stopMonitoring(this.elRef.nativeElement);
}
setDescribedByIds(ids: string[]) {
this.describedBy = ids.join(' ');
}
onContainerClick(event: MouseEvent) {
if ((event.target as Element).tagName.toLowerCase() != 'input') {
this.elRef.nativeElement.querySelector('input').focus();
}
}
}
/** @title Form field with custom telephone number input control. */
export class FormFieldCustomControlExample {}