173 lines
3.8 KiB
JavaScript
Raw Normal View History

import {isPresent} from 'angular2/src/facade/lang';
import {StringMap, StringMapWrapper} from 'angular2/src/facade/collection';
import {Validators} from './validators';
export const VALID = "VALID";
export const INVALID = "INVALID";
2015-02-24 11:59:10 -08:00
//interface IControl {
// get value():any;
// validator:Function;
// get status():string;
2015-02-25 12:54:27 -08:00
// get valid():boolean;
2015-02-24 11:59:10 -08:00
// get errors():Map;
2015-03-19 10:51:49 -07:00
// get pristine():boolean;
// get dirty():boolean;
2015-02-24 11:59:10 -08:00
// updateValue(value:any){}
// setParent(parent){}
//}
export class AbstractControl {
2015-02-24 11:59:10 -08:00
_value:any;
_status:string;
_errors;
2015-03-19 10:51:49 -07:00
_updateNeeded:boolean;
_pristine:boolean;
_parent:ControlGroup;
2015-02-24 11:59:10 -08:00
validator:Function;
constructor(validator:Function) {
this.validator = validator;
2015-03-19 10:51:49 -07:00
this._updateNeeded = true;
this._pristine = true;
}
2015-02-24 11:59:10 -08:00
get value() {
this._updateIfNeeded();
2015-02-24 11:59:10 -08:00
return this._value;
}
get status() {
this._updateIfNeeded();
return this._status;
}
get valid() {
2015-02-24 11:59:10 -08:00
this._updateIfNeeded();
return this._status === VALID;
}
get errors() {
this._updateIfNeeded();
return this._errors;
}
2015-03-19 10:51:49 -07:00
get pristine() {
this._updateIfNeeded();
return this._pristine;
}
get dirty() {
return ! this.pristine;
}
2015-02-24 11:59:10 -08:00
setParent(parent){
this._parent = parent;
}
2015-02-24 11:59:10 -08:00
_updateIfNeeded() {
}
_updateParent() {
if (isPresent(this._parent)){
this._parent._controlChanged();
}
}
}
export class Control extends AbstractControl {
constructor(value:any, validator:Function = Validators.nullValidator) {
super(validator);
this._value = value;
}
updateValue(value:any) {
this._value = value;
2015-03-19 10:51:49 -07:00
this._updateNeeded = true;
this._pristine = false;
this._updateParent();
2015-02-24 11:59:10 -08:00
}
_updateIfNeeded() {
2015-03-19 10:51:49 -07:00
if (this._updateNeeded) {
this._updateNeeded = false;
this._errors = this.validator(this);
this._status = isPresent(this._errors) ? INVALID : VALID;
}
}
}
export class ControlGroup extends AbstractControl {
controls;
optionals;
2015-02-24 11:59:10 -08:00
constructor(controls, optionals = null, validator:Function = Validators.group) {
super(validator);
this.controls = controls;
this.optionals = isPresent(optionals) ? optionals : {};
this._setParentForControls();
}
include(controlName:string) {
2015-03-19 10:51:49 -07:00
this._updateNeeded = true;
StringMapWrapper.set(this.optionals, controlName, true);
}
exclude(controlName:string) {
2015-03-19 10:51:49 -07:00
this._updateNeeded = true;
StringMapWrapper.set(this.optionals, controlName, false);
}
contains(controlName:string) {
var c = StringMapWrapper.contains(this.controls, controlName);
return c && this._included(controlName);
}
_setParentForControls() {
StringMapWrapper.forEach(this.controls, (control, name) => {
2015-02-24 11:59:10 -08:00
control.setParent(this);
});
}
2015-02-24 11:59:10 -08:00
_updateIfNeeded() {
2015-03-19 10:51:49 -07:00
if (this._updateNeeded) {
this._updateNeeded = false;
2015-02-24 11:59:10 -08:00
this._value = this._reduceValue();
2015-03-19 10:51:49 -07:00
this._pristine = this._reducePristine();
2015-02-24 11:59:10 -08:00
this._errors = this.validator(this);
this._status = isPresent(this._errors) ? INVALID : VALID;
}
}
_reduceValue() {
2015-03-19 10:51:49 -07:00
return this._reduceChildren({}, (acc, control, name) => {
acc[name] = control.value;
return acc;
});
}
_reducePristine() {
return this._reduceChildren(true,
(acc, control, name) => acc && control.pristine);
}
_reduceChildren(initValue, fn:Function) {
var res = initValue;
2015-02-24 11:59:10 -08:00
StringMapWrapper.forEach(this.controls, (control, name) => {
if (this._included(name)) {
2015-03-19 10:51:49 -07:00
res = fn(res, control, name);
2015-02-24 11:59:10 -08:00
}
});
2015-03-19 10:51:49 -07:00
return res;
}
_controlChanged() {
2015-03-19 10:51:49 -07:00
this._updateNeeded = true;
this._updateParent();
}
2015-02-24 11:59:10 -08:00
_included(controlName:string):boolean {
var isOptional = StringMapWrapper.contains(this.optionals, controlName);
return !isOptional || StringMapWrapper.get(this.optionals, controlName);
2015-02-24 11:59:10 -08:00
}
}