parent
50e922f37b
commit
e82a35d1fd
|
@ -34,7 +34,11 @@ export {
|
|||
} from './forms/directives/select_control_value_accessor';
|
||||
export {FORM_DIRECTIVES} from './forms/directives';
|
||||
export {NG_VALIDATORS, Validators} from './forms/validators';
|
||||
export {DefaultValidators} from './forms/directives/validators';
|
||||
export {
|
||||
RequiredValidator,
|
||||
MinLengthValidator,
|
||||
MaxLengthValidator
|
||||
} from './forms/directives/validators';
|
||||
export {FormBuilder} from './forms/form_builder';
|
||||
|
||||
import {FormBuilder} from './forms/form_builder';
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
SelectControlValueAccessor,
|
||||
NgSelectOption
|
||||
} from './directives/select_control_value_accessor';
|
||||
import {DefaultValidators} from './directives/validators';
|
||||
import {RequiredValidator, MinLengthValidator, MaxLengthValidator} from './directives/validators';
|
||||
|
||||
export {NgControlName} from './directives/ng_control_name';
|
||||
export {NgFormControl} from './directives/ng_form_control';
|
||||
|
@ -28,7 +28,7 @@ export {
|
|||
SelectControlValueAccessor,
|
||||
NgSelectOption
|
||||
} from './directives/select_control_value_accessor';
|
||||
export {DefaultValidators} from './directives/validators';
|
||||
export {RequiredValidator, MinLengthValidator, MaxLengthValidator} from './directives/validators';
|
||||
export {NgControlStatus} from './directives/ng_control_status';
|
||||
|
||||
/**
|
||||
|
@ -62,5 +62,7 @@ export const FORM_DIRECTIVES: Type[] = CONST_EXPR([
|
|||
SelectControlValueAccessor,
|
||||
NgControlStatus,
|
||||
|
||||
DefaultValidators
|
||||
RequiredValidator,
|
||||
MinLengthValidator,
|
||||
MaxLengthValidator
|
||||
]);
|
||||
|
|
|
@ -1,14 +1,53 @@
|
|||
import {forwardRef, Provider, OpaqueToken} from 'angular2/src/core/di';
|
||||
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||
import {Directive} from 'angular2/src/core/metadata';
|
||||
import {Attribute, Directive} from 'angular2/src/core/metadata';
|
||||
import {Validators, NG_VALIDATORS} from '../validators';
|
||||
import {NumberWrapper} from "angular2/src/core/facade/lang";
|
||||
|
||||
const DEFAULT_VALIDATORS =
|
||||
const REQUIRED_VALIDATOR =
|
||||
CONST_EXPR(new Provider(NG_VALIDATORS, {useValue: Validators.required, multi: true}));
|
||||
|
||||
@Directive({
|
||||
selector: '[required][ng-control],[required][ng-form-control],[required][ng-model]',
|
||||
bindings: [DEFAULT_VALIDATORS]
|
||||
providers: [REQUIRED_VALIDATOR]
|
||||
})
|
||||
export class DefaultValidators {
|
||||
export class RequiredValidator {
|
||||
}
|
||||
|
||||
function createMinLengthValidator(dir): any {
|
||||
return Validators.minLength(dir.minLength);
|
||||
}
|
||||
const MIN_LENGTH_VALIDATOR = CONST_EXPR(new Provider(NG_VALIDATORS, {
|
||||
useFactory: createMinLengthValidator,
|
||||
deps: [forwardRef(() => MinLengthValidator)],
|
||||
multi: true
|
||||
}));
|
||||
@Directive({
|
||||
selector: '[minlength][ng-control],[minlength][ng-form-control],[minlength][ng-model]',
|
||||
providers: [MIN_LENGTH_VALIDATOR]
|
||||
})
|
||||
export class MinLengthValidator {
|
||||
minLength: number;
|
||||
constructor(@Attribute("minlength") minLength: string) {
|
||||
this.minLength = NumberWrapper.parseInt(minLength, 10);
|
||||
}
|
||||
}
|
||||
|
||||
function createMaxLengthValidator(dir): any {
|
||||
return Validators.maxLength(dir.maxLength);
|
||||
}
|
||||
const MAX_LENGTH_VALIDATOR = CONST_EXPR(new Provider(NG_VALIDATORS, {
|
||||
useFactory: createMaxLengthValidator,
|
||||
deps: [forwardRef(() => MaxLengthValidator)],
|
||||
multi: true
|
||||
}));
|
||||
@Directive({
|
||||
selector: '[maxlength][ng-control],[maxlength][ng-form-control],[maxlength][ng-model]',
|
||||
providers: [MAX_LENGTH_VALIDATOR]
|
||||
})
|
||||
export class MaxLengthValidator {
|
||||
maxLength: number;
|
||||
constructor(@Attribute("maxlength") maxLength: string) {
|
||||
this.maxLength = NumberWrapper.parseInt(maxLength, 10);
|
||||
}
|
||||
}
|
|
@ -21,6 +21,26 @@ export class Validators {
|
|||
return isBlank(control.value) || control.value == "" ? {"required": true} : null;
|
||||
}
|
||||
|
||||
static minLength(minLength: number): Function {
|
||||
return (control: modelModule.Control): {[key: string]: any} => {
|
||||
if (isPresent(Validators.required(control))) return null;
|
||||
var v: string = control.value;
|
||||
return v.length < minLength ?
|
||||
{"minlength": {"requiredLength": minLength, "actualLength": v.length}} :
|
||||
null;
|
||||
};
|
||||
}
|
||||
|
||||
static maxLength(maxLength: number): Function {
|
||||
return (control: modelModule.Control): {[key: string]: any} => {
|
||||
if (isPresent(Validators.required(control))) return null;
|
||||
var v: string = control.value;
|
||||
return v.length > maxLength ?
|
||||
{"maxlength": {"requiredLength": maxLength, "actualLength": v.length}} :
|
||||
null;
|
||||
};
|
||||
}
|
||||
|
||||
static nullValidator(c: any): {[key: string]: boolean} { return null; }
|
||||
|
||||
static compose(validators: Function[]): Function {
|
||||
|
|
|
@ -28,7 +28,6 @@ import {
|
|||
NgForm,
|
||||
NgModel,
|
||||
NgFormControl,
|
||||
DefaultValidators,
|
||||
NgControl,
|
||||
DefaultValueAccessor,
|
||||
CheckboxControlValueAccessor,
|
||||
|
|
|
@ -349,23 +349,43 @@ export function main() {
|
|||
describe("validations", () => {
|
||||
it("should use validators defined in html",
|
||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||
var form = new ControlGroup({"login": new Control("aa")});
|
||||
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">
|
||||
</div>`;
|
||||
|
||||
tcb.overrideTemplate(MyComp, t).createAsync(MyComp).then((rootTC) => {
|
||||
rootTC.debugElement.componentInstance.form = form;
|
||||
rootTC.detectChanges();
|
||||
|
||||
var required = rootTC.debugElement.query(By.css("[required]"));
|
||||
var minLength = rootTC.debugElement.query(By.css("[minlength]"));
|
||||
var maxLength = rootTC.debugElement.query(By.css("[maxlength]"));
|
||||
|
||||
required.nativeElement.value = "";
|
||||
minLength.nativeElement.value = "1";
|
||||
maxLength.nativeElement.value = "1234";
|
||||
dispatchEvent(required.nativeElement, "change");
|
||||
dispatchEvent(minLength.nativeElement, "change");
|
||||
dispatchEvent(maxLength.nativeElement, "change");
|
||||
|
||||
expect(form.hasError("required", ["login"])).toEqual(true);
|
||||
expect(form.hasError("minlength", ["min"])).toEqual(true);
|
||||
expect(form.hasError("maxlength", ["max"])).toEqual(true);
|
||||
|
||||
required.nativeElement.value = "1";
|
||||
minLength.nativeElement.value = "123";
|
||||
maxLength.nativeElement.value = "123";
|
||||
dispatchEvent(required.nativeElement, "change");
|
||||
dispatchEvent(minLength.nativeElement, "change");
|
||||
dispatchEvent(maxLength.nativeElement, "change");
|
||||
|
||||
expect(form.valid).toEqual(true);
|
||||
|
||||
var input = rootTC.debugElement.query(By.css("input"));
|
||||
|
||||
input.nativeElement.value = "";
|
||||
dispatchEvent(input.nativeElement, "change");
|
||||
|
||||
expect(form.valid).toEqual(false);
|
||||
async.done();
|
||||
});
|
||||
}));
|
||||
|
|
|
@ -32,6 +32,38 @@ export function main() {
|
|||
() => { expect(Validators.required(new Control("not empty"))).toEqual(null); });
|
||||
});
|
||||
|
||||
describe("minLength", () => {
|
||||
it("should not error on an empty string",
|
||||
() => { expect(Validators.minLength(2)(new Control(""))).toEqual(null); });
|
||||
|
||||
it("should not error on null",
|
||||
() => { expect(Validators.minLength(2)(new Control(null))).toEqual(null); });
|
||||
|
||||
it("should not error on valid strings",
|
||||
() => { expect(Validators.minLength(2)(new Control("aa"))).toEqual(null); });
|
||||
|
||||
it("should error on short strings", () => {
|
||||
expect(Validators.minLength(2)(new Control("a")))
|
||||
.toEqual({"minlength": {"requiredLength": 2, "actualLength": 1}});
|
||||
});
|
||||
});
|
||||
|
||||
describe("maxLength", () => {
|
||||
it("should not error on an empty string",
|
||||
() => { expect(Validators.maxLength(2)(new Control(""))).toEqual(null); });
|
||||
|
||||
it("should not error on null",
|
||||
() => { expect(Validators.maxLength(2)(new Control(null))).toEqual(null); });
|
||||
|
||||
it("should not error on valid strings",
|
||||
() => { expect(Validators.maxLength(2)(new Control("aa"))).toEqual(null); });
|
||||
|
||||
it("should error on short strings", () => {
|
||||
expect(Validators.maxLength(2)(new Control("aaa")))
|
||||
.toEqual({"maxlength": {"requiredLength": 2, "actualLength": 3}});
|
||||
});
|
||||
});
|
||||
|
||||
describe("compose", () => {
|
||||
it("should return a null validator when given null",
|
||||
() => { expect(Validators.compose(null)).toBe(Validators.nullValidator); });
|
||||
|
|
|
@ -396,7 +396,13 @@ var NG_API = [
|
|||
'DebugElement.queryAll()',
|
||||
'DecimalPipe',
|
||||
'DecimalPipe.transform()',
|
||||
'DefaultValidators',
|
||||
'RequiredValidator',
|
||||
'MinLengthValidator',
|
||||
'MinLengthValidator.minLength',
|
||||
'MinLengthValidator.minLength=',
|
||||
'MaxLengthValidator',
|
||||
'MaxLengthValidator.maxLength',
|
||||
'MaxLengthValidator.maxLength=',
|
||||
'DefaultValueAccessor',
|
||||
'DefaultValueAccessor.onChange',
|
||||
'DefaultValueAccessor.onChange=',
|
||||
|
@ -995,6 +1001,8 @@ var NG_API = [
|
|||
'Validators#group()',
|
||||
'Validators#nullValidator()',
|
||||
'Validators#required()',
|
||||
'Validators#minLength()',
|
||||
'Validators#maxLength()',
|
||||
'Validators',
|
||||
'View',
|
||||
'View.directives',
|
||||
|
|
Loading…
Reference in New Issue