Skip to content

Instantly share code, notes, and snippets.

@studds
Created December 1, 2016 03:08
Show Gist options
  • Save studds/0946818628a66ea10660f0e9163db315 to your computer and use it in GitHub Desktop.
Save studds/0946818628a66ea10660f0e9163db315 to your computer and use it in GitHub Desktop.
An angular 2 value accessor for content editable fields (for use with ngModel)
import { forwardRef, Directive, ElementRef, HostListener, Renderer, SecurityContext } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { DomSanitizer } from '@angular/platform-browser';
type OnChangeFn = (innerHTML: string) => void;
type OnTouchFn = () => void;
const ENTER_KEY_CODE = 13;
@Directive({
selector: '[contenteditable]',
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => ContentEditableValueAccessor),
multi: true
}
]
})
export class ContentEditableValueAccessor implements ControlValueAccessor {
private elementRef: ElementRef;
private renderer: Renderer;
private onChange: OnChangeFn;
private onTouched: OnTouchFn;
private domSanitizer: DomSanitizer;
constructor(elementRef: ElementRef, renderer: Renderer, domSanitizer: DomSanitizer) {
this.elementRef = elementRef;
this.renderer = renderer;
this.domSanitizer = domSanitizer;
}
@HostListener('input', [ ])
onInput(): void {
const innerHTML = this.elementRef.nativeElement.innerHTML;
this.onChange(innerHTML);
}
@HostListener('keypress', [ '$event' ])
onKeypress(event: KeyboardEvent): void {
if (event.keyCode === ENTER_KEY_CODE) {
// prevent enter from creating new paragraphs
event.preventDefault();
}
}
@HostListener('blur', [])
onBlur(): void {
this.onTouched();
}
// will be called if a values comes in via ngModule !
writeValue (innerHTML: string = ''): void {
const sanitizedHTML = this.domSanitizer.sanitize(SecurityContext.HTML, innerHTML);
this.renderer.setElementProperty(this.elementRef.nativeElement, 'innerHTML', sanitizedHTML);
}
registerOnChange(fn: OnChangeFn): void {
this.onChange = fn;
}
registerOnTouched(fn: OnTouchFn): void {
this.onTouched = fn;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment