Skip to content

Instantly share code, notes, and snippets.

@jwcarroll
Last active January 24, 2017 13:13
Show Gist options
  • Save jwcarroll/0613e6c594cb0b6c9b8e08935f315e8d to your computer and use it in GitHub Desktop.
Save jwcarroll/0613e6c594cb0b6c9b8e08935f315e8d to your computer and use it in GitHub Desktop.
Automatically adds bootstrap style validation to forms
import { Directive, OnDestroy, ElementRef } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Subscription } from 'rxjs/Subscription';
import { Observable } from 'rxjs/Observable';
import * as _ from 'lodash';
import 'rxjs/add/observable/combineLatest';
@Directive({ selector: '[bsValidation]' })
export class BSValidationDirective implements OnDestroy {
private sub: Subscription;
constructor(private form: ControlContainer, private element: ElementRef) {
this.sub = Observable.combineLatest(form.valueChanges, form.statusChanges)
.debounceTime(300)
.subscribe(([valueChanges, statusChanges]) => {
this.monitorForm(Object.keys(valueChanges));
});
}
monitorForm(keys: string[]) {
keys.forEach(name => {
let control = this.form.controls[name];
let controlElement = _.find(this.element.nativeElement, (x: any) => x.name === name);
if (!controlElement) {
// This is to handle widgets that controlElements cannot be found for (ie NGPrime Calendar). Instead add an id to parent element.
controlElement = document.getElementById(name);
}
if (control.dirty && control.invalid) {
if (controlElement && !controlElement.parentElement.classList.contains('has-error')) {
controlElement.parentElement.classList.add('has-error');
}
} else {
if (controlElement && controlElement.parentElement.classList.contains('has-error')) {
controlElement.parentElement.classList.remove('has-error');
}
}
});
}
ngOnDestroy() {
if (this.sub) {
this.sub.unsubscribe();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment