UNPKG

ipsos-components

Version:

Material Design components for Angular

141 lines (115 loc) 3.69 kB
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. */ @Component({ selector: 'my-tel-input', templateUrl: 'form-field-custom-control-example.html', styleUrls: ['form-field-custom-control-example.css'], providers: [{provide: MatFormFieldControl, useExisting: MyTelInput}], host: { '[class.floating]': 'shouldLabelFloat', '[id]': 'id', '[attr.aria-describedby]': 'describedBy', } }) 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 = ''; @Input() get placeholder() { return this._placeholder; } set placeholder(plh) { this._placeholder = plh; this.stateChanges.next(); } private _placeholder: string; @Input() get required() { return this._required; } set required(req) { this._required = coerceBooleanProperty(req); this.stateChanges.next(); } private _required = false; @Input() get disabled() { return this._disabled; } set disabled(dis) { this._disabled = coerceBooleanProperty(dis); this.stateChanges.next(); } private _disabled = false; @Input() 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. */ @Component({ selector: 'form-field-custom-control-example', template: ` <mat-form-field> <my-tel-input placeholder="Phone number" required></my-tel-input> <mat-icon matSuffix>phone</mat-icon> <mat-hint>Include area code</mat-hint> </mat-form-field> ` }) export class FormFieldCustomControlExample {}