X Tutup
Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modules/angular2/src/common/forms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export {
RequiredValidator,
MinLengthValidator,
MaxLengthValidator,
PatternValidator,
Validator
} from './forms/directives/validators';
export {FormBuilder} from './forms/form_builder';
Expand Down
17 changes: 14 additions & 3 deletions modules/angular2/src/common/forms/directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ import {
SelectControlValueAccessor,
NgSelectOption
} from './directives/select_control_value_accessor';
import {RequiredValidator, MinLengthValidator, MaxLengthValidator} from './directives/validators';
import {
RequiredValidator,
MinLengthValidator,
MaxLengthValidator,
PatternValidator
} from './directives/validators';

export {NgControlName} from './directives/ng_control_name';
export {NgFormControl} from './directives/ng_form_control';
Expand All @@ -34,7 +39,12 @@ export {
SelectControlValueAccessor,
NgSelectOption
} from './directives/select_control_value_accessor';
export {RequiredValidator, MinLengthValidator, MaxLengthValidator} from './directives/validators';
export {
RequiredValidator,
MinLengthValidator,
MaxLengthValidator,
PatternValidator
} from './directives/validators';
export {NgControl} from './directives/ng_control';
export {ControlValueAccessor} from './directives/control_value_accessor';

Expand Down Expand Up @@ -73,5 +83,6 @@ export const FORM_DIRECTIVES: Type[] = CONST_EXPR([

RequiredValidator,
MinLengthValidator,
MaxLengthValidator
MaxLengthValidator,
PatternValidator
]);
29 changes: 29 additions & 0 deletions modules/angular2/src/common/forms/directives/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,32 @@ export class MaxLengthValidator implements Validator {

validate(c: Control): {[key: string]: any} { return this._validator(c); }
}


/**
* A Directive that adds the `pattern` validator to any controls marked with the
* `pattern` attribute, via the {@link NG_VALIDATORS} binding. Uses attribute value
* as the regex to validate Control value against. Follows pattern attribute
* semantics; i.e. regex must match entire Control value.
*
* ### Example
*
* ```
* <input [ngControl]="fullName" pattern="[a-zA-Z ]*">
* ```
*/
const PATTERN_VALIDATOR = CONST_EXPR(
new Provider(NG_VALIDATORS, {useExisting: forwardRef(() => PatternValidator), multi: true}));
@Directive({
selector: '[pattern][ngControl],[pattern][ngFormControl],[pattern][ngModel]',
providers: [PATTERN_VALIDATOR]
})
export class PatternValidator implements Validator {
private _validator: Function;

constructor(@Attribute("pattern") pattern: string) {
this._validator = Validators.pattern(pattern);
}

validate(c: Control): {[key: string]: any} { return this._validator(c); }
}
13 changes: 13 additions & 0 deletions modules/angular2/src/common/forms/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,19 @@ export class Validators {
};
}

/**
* Validator that requires a control to match a regex to its value.
*/
static pattern(pattern: string): Function {
return (control: modelModule.Control): {[key: string]: any} => {
if (isPresent(Validators.required(control))) return null;
let regex = new RegExp(`^${pattern}$`);
let v: string = control.value;
return regex.test(v) ? null :
{"pattern": {"requiredPattern": `^${pattern}$`, "actualValue": v}};
};
}

/**
* No-op validator.
*/
Expand Down
18 changes: 17 additions & 1 deletion modules/angular2/test/common/forms/validators_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,28 @@ export function main() {
it("should not error on valid strings",
() => { expect(Validators.maxLength(2)(new Control("aa"))).toEqual(null); });

it("should error on short strings", () => {
it("should error on long strings", () => {
expect(Validators.maxLength(2)(new Control("aaa")))
.toEqual({"maxlength": {"requiredLength": 2, "actualLength": 3}});
});
});

describe("pattern", () => {
it("should not error on an empty string",
() => { expect(Validators.pattern("[a-zA-Z ]*")(new Control(""))).toEqual(null); });

it("should not error on null",
() => { expect(Validators.pattern("[a-zA-Z ]*")(new Control(null))).toEqual(null); });

it("should not error on valid strings",
() => { expect(Validators.pattern("[a-zA-Z ]*")(new Control("aaAA"))).toEqual(null); });

it("should error on failure to match string", () => {
expect(Validators.pattern("[a-zA-Z ]*")(new Control("aaa0")))
.toEqual({"pattern": {"requiredPattern": "^[a-zA-Z ]*$", "actualValue": "aaa0"}});
});
});

describe("compose", () => {
it("should return null when given null",
() => { expect(Validators.compose(null)).toBe(null); });
Expand Down
3 changes: 3 additions & 0 deletions modules/angular2/test/public_api_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,8 @@ var NG_COMMON = [
'ObservableListDiffFactory.create():dart',
'ObservableListDiffFactory.supports():dart',
'ObservableListDiffFactory:dart',
'PatternValidator',
'PatternValidator.validate()',
'PercentPipe',
'PercentPipe.transform()',
'RequiredValidator',
Expand All @@ -452,6 +454,7 @@ var NG_COMMON = [
'Validators#maxLength()',
'Validators#minLength()',
'Validators#nullValidator()',
'Validators#pattern()',
'Validators#required()',
'RadioButtonState',
'RadioButtonState.checked',
Expand Down
4 changes: 4 additions & 0 deletions tools/public_api_guard/public_api_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,9 @@ const COMMON = [
'NgSwitchWhen.constructor(viewContainer:ViewContainerRef, templateRef:TemplateRef, ngSwitch:NgSwitch)',
'NgSwitchWhen.ngSwitchWhen=(value:any)',
'NumberPipe',
'PatternValidator',
'PatternValidator.constructor(pattern:string)',
'PatternValidator.validate(c:Control):{[key:string]:any}',
'PercentPipe',
'PercentPipe.transform(value:any, args:any[]):string',
'RequiredValidator',
Expand All @@ -794,6 +797,7 @@ const COMMON = [
'Validators.maxLength(maxLength:number):Function',
'Validators.minLength(minLength:number):Function',
'Validators.nullValidator(c:any):{[key:string]:boolean}',
'Validators.pattern(pattern:string):Function',
'Validators.required(control:Control):{[key:string]:boolean}',
'RadioButtonState',
'RadioButtonState.constructor(checked:boolean, value:string)',
Expand Down
X Tutup