diff --git a/modules/angular2/forms.js b/modules/angular2/forms.js index e943dd2d96..40f02caae1 100644 --- a/modules/angular2/forms.js +++ b/modules/angular2/forms.js @@ -1,4 +1,5 @@ export * from './src/forms/model'; export * from './src/forms/directives'; export * from './src/forms/validators'; -export * from './src/forms/validator_directives'; \ No newline at end of file +export * from './src/forms/validator_directives'; +export * from './src/forms/form_builder'; \ No newline at end of file diff --git a/modules/angular2/src/forms/model.js b/modules/angular2/src/forms/model.js index e6eba381da..7f481e56ee 100644 --- a/modules/angular2/src/forms/model.js +++ b/modules/angular2/src/forms/model.js @@ -11,7 +11,6 @@ export const INVALID = "INVALID"; // get status():string; // get valid():boolean; // get errors():Map; -// get active():boolean {} // updateValue(value:any){} // setParent(parent){} //} @@ -29,10 +28,6 @@ export class AbstractControl { this._dirty = true; } - get active():boolean { - return true; - } - get value() { this._updateIfNeeded(); return this._value; @@ -90,13 +85,30 @@ export class Control extends AbstractControl { export class ControlGroup extends AbstractControl { controls; + optionals; - constructor(controls, validator:Function = controlGroupValidator) { + constructor(controls, optionals = null, validator:Function = controlGroupValidator) { super(validator); this.controls = controls; + this.optionals = isPresent(optionals) ? optionals : {}; this._setParentForControls(); } + include(controlName:string) { + this._dirty = true; + StringMapWrapper.set(this.optionals, controlName, true); + } + + exclude(controlName:string) { + this._dirty = 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) => { control.setParent(this); @@ -115,7 +127,7 @@ export class ControlGroup extends AbstractControl { _reduceValue() { var newValue = {}; StringMapWrapper.forEach(this.controls, (control, name) => { - if (control.active) { + if (this._included(name)) { newValue[name] = control.value; } }); @@ -126,56 +138,9 @@ export class ControlGroup extends AbstractControl { this._dirty = true; this._updateParent(); } -} -export class OptionalControl { - _control:Control; - _cond:boolean; - - constructor(control:Control, cond:boolean) { - super(); - this._control = control; - this._cond = cond; - } - - get active():boolean { - return this._cond; - } - - get value() { - return this._control.value; - } - - get status() { - return this._control.status; - } - - get errors() { - return this._control.errors; - } - - set validator(v) { - this._control.validator = v; - } - - get validator() { - return this._control.validator; - } - - set cond(value:boolean){ - this._cond = value; - this._control._updateParent(); - } - - get cond():boolean{ - return this._cond; - } - - updateValue(value:any){ - this._control.updateValue(value); - } - - setParent(parent){ - this._control.setParent(parent); + _included(controlName:string):boolean { + var isOptional = StringMapWrapper.contains(this.optionals, controlName); + return !isOptional || StringMapWrapper.get(this.optionals, controlName); } } \ No newline at end of file diff --git a/modules/angular2/src/forms/validators.js b/modules/angular2/src/forms/validators.js index 1df7d22b93..9888f12648 100644 --- a/modules/angular2/src/forms/validators.js +++ b/modules/angular2/src/forms/validators.js @@ -24,7 +24,7 @@ export function compose(validators:List):Function { export function controlGroupValidator(c:ControlGroup) { var res = {}; StringMapWrapper.forEach(c.controls, (control, name) => { - if (control.active && isPresent(control.errors)) { + if (c.contains(name) && isPresent(control.errors)) { StringMapWrapper.forEach(control.errors, (value, error) => { if (! StringMapWrapper.contains(res, error)) { res[error] = []; diff --git a/modules/angular2/test/forms/model_spec.js b/modules/angular2/test/forms/model_spec.js index 65e405e8f9..8b81f30bcf 100644 --- a/modules/angular2/test/forms/model_spec.js +++ b/modules/angular2/test/forms/model_spec.js @@ -84,56 +84,68 @@ export function main() { expect(g.errors).toEqual(null); }); }); - }); - describe("OptionalControl", () => { - it("should read properties from the wrapped component", () => { - var wrapperControl = new Control("value", validations.required); - var c = new OptionalControl(wrapperControl, true); + describe("optional components", () => { + describe("contains", () => { + var group; - expect(c.value).toEqual('value'); - expect(c.status).toEqual('VALID'); - expect(c.validator).toEqual(validations.required); - }); + beforeEach(() => { + group = new ControlGroup({ + "required": new Control("requiredValue"), + "optional": new Control("optionalValue") + }, { + "optional": false + }); + }); - it("should update the wrapped component", () => { - var wrappedControl = new Control("value"); - var c = new OptionalControl(wrappedControl, true); + // rename contains into has + it("should return false when the component is not included", () => { + expect(group.contains("optional")).toEqual(false); + }) - c.validator = validations.required; - c.updateValue("newValue"); + it("should return false when there is no component with the given name", () => { + expect(group.contains("something else")).toEqual(false); + }); + it("should return true when the component is included", () => { + expect(group.contains("required")).toEqual(true); - expect(wrappedControl.validator).toEqual(validations.required); - expect(wrappedControl.value).toEqual('newValue'); - }); + group.include("optional"); - it("should not include an inactive component into the group value", () => { - var group = new ControlGroup({ - "required" : new Control("requiredValue"), - "optional" : new OptionalControl(new Control("optionalValue"), false) + expect(group.contains("optional")).toEqual(true); + }); }); - expect(group.value).toEqual({"required" : "requiredValue"}); + it("should not include an inactive component into the group value", () => { + var group = new ControlGroup({ + "required": new Control("requiredValue"), + "optional": new Control("optionalValue") + }, { + "optional": false + }); - group.controls["optional"].cond = true; + expect(group.value).toEqual({"required" : "requiredValue"}); - expect(group.value).toEqual({"required" : "requiredValue", "optional" : "optionalValue"}); - }); + group.include("optional"); - it("should not run validations on an inactive component", () => { - var group = new ControlGroup({ - "required" : new Control("requiredValue", validations.required), - "optional" : new OptionalControl(new Control("", validations.required), false) + expect(group.value).toEqual({"required" : "requiredValue", "optional" : "optionalValue"}); }); - expect(group.valid).toEqual(true); + it("should not run validations on an inactive component", () => { + var group = new ControlGroup({ + "required": new Control("requiredValue", validations.required), + "optional": new Control("", validations.required) + }, { + "optional": false + }); - group.controls["optional"].cond = true; + expect(group.valid).toEqual(true); - expect(group.valid).toEqual(false); + group.include("optional"); + + expect(group.valid).toEqual(false); + }); }); }); - }); -} \ No newline at end of file +}