feat(forms): support adding validators to ControlGroup via template

Closes #4954
This commit is contained in:
vsavkin
2015-10-27 14:36:13 -07:00
committed by Victor Savkin
parent f98faf0702
commit 758062807a
9 changed files with 137 additions and 30 deletions
@@ -105,8 +105,12 @@ export function main() {
var loginControlDir;
beforeEach(() => {
form = new NgFormModel();
formModel = new ControlGroup({"login": new Control(null)});
form = new NgFormModel([]);
formModel = new ControlGroup({
"login": new Control(),
"passwords":
new ControlGroup({"password": new Control(), "passwordConfirm": new Control()})
});
form.form = formModel;
loginControlDir = new NgControlName(form, [], [defaultAccessor]);
@@ -167,6 +171,26 @@ export function main() {
});
});
describe("addControlGroup", () => {
var matchingPasswordsValidator = (g) => {
if (g.controls["password"].value != g.controls["passwordConfirm"].value) {
return {"differentPasswords": true};
} else {
return null;
}
};
it("should set up validator", () => {
var group = new NgControlGroup(form, [matchingPasswordsValidator]);
group.name = "passwords";
form.addControlGroup(group);
formModel.find(["passwords", "password"]).updateValue("somePassword");
expect(formModel.hasError("differentPasswords", ["passwords"])).toEqual(true);
});
});
describe("removeControl", () => {
it("should remove the directive to the list of directives included in the form", () => {
form.addControl(loginControlDir);
@@ -181,10 +205,22 @@ export function main() {
formModel.find(["login"]).updateValue("new value");
form.onChanges(null);
form.onChanges({});
expect((<any>loginControlDir.valueAccessor).writtenValue).toEqual("new value");
});
it("should set up validator", () => {
var formValidator = (c) => ({"custom": true});
var f = new NgFormModel([formValidator]);
f.form = formModel;
f.onChanges({"form": formModel});
// trigger validation
formModel.controls["login"].updateValue("");
expect(formModel.errors).toEqual({"custom": true});
});
});
});
@@ -195,10 +231,10 @@ export function main() {
var personControlGroupDir;
beforeEach(() => {
form = new NgForm();
form = new NgForm([]);
formModel = form.form;
personControlGroupDir = new NgControlGroup(form);
personControlGroupDir = new NgControlGroup(form, []);
personControlGroupDir.name = "person";
loginControlDir = new NgControlName(personControlGroupDir, null, [defaultAccessor]);
@@ -246,6 +282,17 @@ export function main() {
// should update the form's value and validity
});
it("should set up validator", fakeAsync(() => {
var formValidator = (c) => ({"custom": true});
var f = new NgForm([formValidator]);
f.addControlGroup(personControlGroupDir);
f.addControl(loginControlDir);
flushMicrotasks();
expect(f.form.errors).toEqual({"custom": true});
}));
});
describe("NgControlGroup", () => {
@@ -255,9 +302,9 @@ export function main() {
beforeEach(() => {
formModel = new ControlGroup({"login": new Control(null)});
var parent = new NgFormModel();
var parent = new NgFormModel([]);
parent.form = new ControlGroup({"group": formModel});
controlGroupDir = new NgControlGroup(parent);
controlGroupDir = new NgControlGroup(parent, []);
controlGroupDir.name = "group";
});
@@ -356,7 +403,7 @@ export function main() {
beforeEach(() => {
formModel = new Control("name");
var parent = new NgFormModel();
var parent = new NgFormModel([]);
parent.form = new ControlGroup({"name": formModel});
controlNameDir = new NgControlName(parent, [], [defaultAccessor]);
controlNameDir.name = "name";
@@ -24,6 +24,8 @@ import {
ControlGroup,
ControlValueAccessor,
FORM_DIRECTIVES,
NG_VALIDATORS,
Provider,
NgControl,
NgIf,
NgFor,
@@ -398,10 +400,10 @@ export function main() {
var form = new ControlGroup(
{"login": new Control(""), "min": new Control(""), "max": new Control("")});
var t = `<div [ng-form-model]="form">
<input type="text" ng-control="login" required>
<input type="text" ng-control="min" minlength="3">
<input type="text" ng-control="max" maxlength="3">
var t = `<div [ng-form-model]="form" login-is-empty-validator>
<input type="text" ng-control="login" required>
<input type="text" ng-control="min" minlength="3">
<input type="text" ng-control="max" maxlength="3">
</div>`;
tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((rootTC) => {
@@ -423,6 +425,8 @@ export function main() {
expect(form.hasError("minlength", ["min"])).toEqual(true);
expect(form.hasError("maxlength", ["max"])).toEqual(true);
expect(form.hasError("loginIsEmpty")).toEqual(true);
required.nativeElement.value = "1";
minLength.nativeElement.value = "123";
maxLength.nativeElement.value = "123";
@@ -914,8 +918,22 @@ class MyInput implements ControlValueAccessor {
}
}
@Component({selector: "my-comp"})
@View({directives: [FORM_DIRECTIVES, WrappedValue, MyInput, NgIf, NgFor]})
function loginIsEmptyGroupValidator(c: ControlGroup) {
return c.controls["login"].value == "" ? {"loginIsEmpty": true} : null;
}
@Directive({
selector: '[login-is-empty-validator]',
providers: [new Provider(NG_VALIDATORS, {useValue: loginIsEmptyGroupValidator, multi: true})]
})
class LoginIsEmptyValidator {
}
@Component({
selector: "my-comp",
template: '',
directives: [FORM_DIRECTIVES, WrappedValue, MyInput, NgIf, NgFor, LoginIsEmptyValidator]
})
class MyComp {
form: any;
name: string;
+2 -2
View File
@@ -73,6 +73,7 @@ var NG_API = [
'AbstractControlDirective.untouched',
'AbstractControlDirective.valid',
'AbstractControlDirective.value',
'AbstractControlDirective.path',
'AppRootUrl',
'AppRootUrl.value',
'AppRootUrl.value=',
@@ -657,6 +658,7 @@ var NG_API = [
'NgControlGroup.untouched',
'NgControlGroup.valid',
'NgControlGroup.value',
'NgControlGroup.validator',
'NgControlStatus',
'NgControlStatus.ngClassDirty',
'NgControlStatus.ngClassInvalid',
@@ -1030,9 +1032,7 @@ var NG_API = [
'UpperCasePipe.transform()',
'UrlResolver',
'UrlResolver.resolve()',
'Validators#array()',
'Validators#compose()',
'Validators#group()',
'Validators#nullValidator()',
'Validators#required()',
'Validators#minLength()',