Skip to content

Instantly share code, notes, and snippets.

@christiaan-lombard
Created February 10, 2017 09:26
Show Gist options
  • Save christiaan-lombard/31c5e3ccbd55f9ce523d64f9bf48b5f5 to your computer and use it in GitHub Desktop.
Save christiaan-lombard/31c5e3ccbd55f9ce523d64f9bf48b5f5 to your computer and use it in GitHub Desktop.
Date Mutator - Angular 2 ControlValueAccessor
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