feat(forms/validators): pattern validator
Adding static pattern validation method to Validators Adding a directive for the pattern validator Applying clang-format rules to modified files Updating public api spec for new pattern validator Adding pattern validator to public api guard tool For #5411 Closes #5561
This commit is contained in:
parent
f6a8d04c32
commit
38cb526f60
|
@ -37,6 +37,7 @@ export {
|
|||
RequiredValidator,
|
||||
MinLengthValidator,
|
||||
MaxLengthValidator,
|
||||
PatternValidator,
|
||||
Validator
|
||||
} from './forms/directives/validators';
|
||||
export {FormBuilder} from './forms/form_builder';
|
||||
|
|
|
@ -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';
|
||||
|
@ -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';
|
||||
|
||||
|
@ -73,5 +83,6 @@ export const FORM_DIRECTIVES: Type[] = CONST_EXPR([
|
|||
|
||||
RequiredValidator,
|
||||
MinLengthValidator,
|
||||
MaxLengthValidator
|
||||
MaxLengthValidator,
|
||||
PatternValidator
|
||||
]);
|
||||
|
|
|
@ -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); }
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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); });
|
||||
|
|
|
@ -427,6 +427,8 @@ var NG_COMMON = [
|
|||
'ObservableListDiffFactory.create():dart',
|
||||
'ObservableListDiffFactory.supports():dart',
|
||||
'ObservableListDiffFactory:dart',
|
||||
'PatternValidator',
|
||||
'PatternValidator.validate()',
|
||||
'PercentPipe',
|
||||
'PercentPipe.transform()',
|
||||
'RequiredValidator',
|
||||
|
@ -452,6 +454,7 @@ var NG_COMMON = [
|
|||
'Validators#maxLength()',
|
||||
'Validators#minLength()',
|
||||
'Validators#nullValidator()',
|
||||
'Validators#pattern()',
|
||||
'Validators#required()',
|
||||
'RadioButtonState',
|
||||
'RadioButtonState.checked',
|
||||
|
|
|
@ -772,6 +772,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',
|
||||
|
@ -795,6 +798,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)',
|
||||
|
|
Loading…
Reference in New Issue