Created
February 10, 2017 09:26
-
-
Save christiaan-lombard/31c5e3ccbd55f9ce523d64f9bf48b5f5 to your computer and use it in GitHub Desktop.
Date Mutator - Angular 2 ControlValueAccessor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Directive, ElementRef, Input, Host, forwardRef, HostListener, Renderer, SimpleChanges } from '@angular/core'; | |
import { NgModel, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; | |
import * as moment from 'moment'; | |
const MUTATE_VALUE_ACCESSOR_PROVIDER = [ | |
{provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MutateDirective), multi: true} | |
]; | |
@Directive({ | |
selector: '[mutate]', | |
providers: [MUTATE_VALUE_ACCESSOR_PROVIDER] | |
}) | |
export class MutateDirective implements ControlValueAccessor{ | |
@Input('mutate') set format(value: string){ | |
this._viewFormat = value; | |
this.updateView(this.model, true); | |
} | |
@Input('inputFormat') set inputFormat(value: string){ | |
this._modelFormat = value; | |
this.updateView(this.model, true); | |
} | |
model: string; | |
private _viewFormat: string = 'Y/M/D'; | |
private _modelFormat: string = 'YYYY-MM-DD HH:mm:ss'; | |
private _fallbackValue: any = null; | |
private _onChange: (value: any) => void = () => {}; | |
private _onTouched: () => void = () => {}; | |
@HostListener('blur') | |
onBlur() { | |
this._onTouched(); | |
} | |
@HostListener('input', ['$event']) | |
onChange(event) { | |
let viewValue = event.target.value; | |
this.updateModel(viewValue); | |
this._onChange(this.model); | |
} | |
constructor(private _renderer: Renderer, | |
private _elementRef: ElementRef) { | |
} | |
registerOnChange(fn: (value: Date) => void): void { | |
this._onChange = fn; | |
} | |
registerOnTouched(fn: () => void): void{ | |
this._onTouched = fn; | |
} | |
writeValue(value: any): void { | |
if (value !== undefined) { | |
this.model = value; | |
this.updateView(this.model, true); | |
} | |
}; | |
/** | |
* Update model value with new view value | |
* 'Informing other form directives and controls when the view/DOM changes' | |
*/ | |
updateModel(viewValue: any){ | |
let date = moment(viewValue, this._viewFormat); | |
this.model = date.isValid() ? date.format(this._modelFormat) : viewValue; | |
} | |
/** | |
* Update view value with new model value | |
* 'Writing a value from the form model into the view/DOM' | |
*/ | |
updateView(modelValue: string, forceUpdate = false) { | |
let date = moment(modelValue, this._modelFormat); | |
if (!date.isValid() && !forceUpdate) { | |
return; | |
} | |
let viewValue = date.isValid() ? date.format(this._viewFormat) : ''; | |
this._renderer.setElementProperty(this._elementRef.nativeElement, 'value', viewValue); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment