#726 min/max value validators, validation improvements

This commit is contained in:
Denys Vuika
2016-09-14 12:37:31 +01:00
parent 7700205270
commit 4a9357b6cf
4 changed files with 114 additions and 21 deletions

View File

@@ -35,8 +35,8 @@ export class RequiredFieldValidator implements FormFieldValidator {
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field &&
field.required && this.supportedTypes.indexOf(field.type) > -1 &&
this.supportedTypes.indexOf(field.type) > -1; field.required;
} }
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
@@ -56,7 +56,13 @@ export class NumberFieldValidator implements FormFieldValidator {
FormFieldTypes.NUMBER FormFieldTypes.NUMBER
]; ];
private pattern: string = '-?[0-9]*(\.[0-9]+)?'; static isNumber(value: any): boolean {
if (value === null || value === undefined || value === '') {
return false;
}
return !isNaN(+value);
}
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && this.supportedTypes.indexOf(field.type) > -1; return field && this.supportedTypes.indexOf(field.type) > -1;
@@ -64,11 +70,17 @@ export class NumberFieldValidator implements FormFieldValidator {
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
if (this.isSupported(field)) { if (this.isSupported(field)) {
return !(this.pattern && field.value && (field.value.length > 0) && !field.value.match(new RegExp('^' + this.pattern + '$'))); if (field.value === null ||
field.value === undefined ||
field.value === '' ||
NumberFieldValidator.isNumber(field.value)) {
return true;
}
field.validationSummary = 'Input must be a number';
return false;
} }
return true; return true;
} }
} }
export class MinLengthFieldValidator implements FormFieldValidator { export class MinLengthFieldValidator implements FormFieldValidator {
@@ -80,17 +92,17 @@ export class MinLengthFieldValidator implements FormFieldValidator {
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field &&
field.minLength > 0 && this.supportedTypes.indexOf(field.type) > -1 &&
this.supportedTypes.indexOf(field.type) > -1; field.minLength > 0;
} }
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
if (this.isSupported(field) && field.value) { if (this.isSupported(field) && field.value) {
let result = field.value.length >= field.minLength; if (field.value.length >= field.minLength) {
if (!result) { return true;
field.validationSummary = `Should be at least ${field.minLength} characters long.`;
} }
return result; field.validationSummary = `Should be at least ${field.minLength} characters long.`;
return false;
} }
return true; return true;
} }
@@ -105,18 +117,74 @@ export class MaxLengthFieldValidator implements FormFieldValidator {
isSupported(field: FormFieldModel): boolean { isSupported(field: FormFieldModel): boolean {
return field && return field &&
field.maxLength > 0 && this.supportedTypes.indexOf(field.type) > -1 &&
this.supportedTypes.indexOf(field.type) > -1; field.maxLength > 0;
} }
validate(field: FormFieldModel): boolean { validate(field: FormFieldModel): boolean {
if (this.isSupported(field) && field.value) { if (this.isSupported(field) && field.value) {
let result = field.value.length <= field.maxLength; if (field.value.length <= field.maxLength) {
if (!result) { return true;
field.validationSummary = `Should be ${field.maxLength} characters maximum.`;
} }
return result; field.validationSummary = `Should be ${field.maxLength} characters maximum.`;
return false;
} }
return true; return true;
} }
} }
export class MinValueFieldValidator implements FormFieldValidator {
private supportedTypes = [
FormFieldTypes.NUMBER
];
isSupported(field: FormFieldModel): boolean {
return field &&
this.supportedTypes.indexOf(field.type) > -1 &&
NumberFieldValidator.isNumber(field.minValue);
}
validate(field: FormFieldModel): boolean {
if (this.isSupported(field) && field.value) {
let value: number = +field.value;
let minValue: number = +field.minValue;
if (value >= minValue) {
return true;
}
field.validationSummary = `Should not be less than ${field.minValue}`;
return false;
}
return true;
}
}
export class MaxValueFieldValidator implements FormFieldValidator {
private supportedTypes = [
FormFieldTypes.NUMBER
];
isSupported(field: FormFieldModel): boolean {
return field &&
this.supportedTypes.indexOf(field.type) > -1 &&
NumberFieldValidator.isNumber(field.maxValue);
}
validate(field: FormFieldModel): boolean {
if (this.isSupported(field) && field.value) {
let value: number = +field.value;
let maxValue: number = +field.maxValue;
if (value <= maxValue) {
return true;
}
field.validationSummary = `Should not be greater than ${field.maxValue}`;
return false;
}
return true;
}
}

View File

@@ -26,7 +26,9 @@ import {
RequiredFieldValidator, RequiredFieldValidator,
NumberFieldValidator, NumberFieldValidator,
MinLengthFieldValidator, MinLengthFieldValidator,
MaxLengthFieldValidator MaxLengthFieldValidator,
MinValueFieldValidator,
MaxValueFieldValidator
} from './form-field-validator'; } from './form-field-validator';
@@ -88,6 +90,8 @@ export class FormFieldModel extends FormWidgetModel {
} }
validate(): boolean { validate(): boolean {
this.validationSummary = null;
// TODO: consider doing that on value setter and caching result // TODO: consider doing that on value setter and caching result
if (this.validators && this.validators.length > 0) { if (this.validators && this.validators.length > 0) {
for (let i = 0; i < this.validators.length; i++) { for (let i = 0; i < this.validators.length; i++) {
@@ -141,7 +145,9 @@ export class FormFieldModel extends FormWidgetModel {
new RequiredFieldValidator(), new RequiredFieldValidator(),
new NumberFieldValidator(), new NumberFieldValidator(),
new MinLengthFieldValidator(), new MinLengthFieldValidator(),
new MaxLengthFieldValidator() new MaxLengthFieldValidator(),
new MinValueFieldValidator(),
new MaxValueFieldValidator()
]; ];
} }

View File

@@ -1,3 +1,20 @@
.number-widget { .number-widget {
width: 100%; width: 100%;
} }
.number-widget__invalid .mdl-textfield__input {
border-color: #d50000;
}
.number-widget__invalid .mdl-textfield__label {
color: #d50000;
}
.number-widget__invalid .mdl-textfield__label:after {
background-color: #d50000;
}
.number-widget__invalid .mdl-textfield__error {
visibility: visible !important;
}

View File

@@ -1,4 +1,5 @@
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label number-widget"> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label number-widget"
[class.number-widget__invalid]="!field.isValid">
<input class="mdl-textfield__input" <input class="mdl-textfield__input"
type="text" type="text"
pattern="-?[0-9]*(\.[0-9]+)?" pattern="-?[0-9]*(\.[0-9]+)?"
@@ -8,5 +9,6 @@
(ngModelChange)="checkVisibility(field)" (ngModelChange)="checkVisibility(field)"
[disabled]="field.readOnly"> [disabled]="field.readOnly">
<label class="mdl-textfield__label" [attr.for]="field.id">{{field.name}}</label> <label class="mdl-textfield__label" [attr.for]="field.id">{{field.name}}</label>
<span class="mdl-textfield__error">Input is not a number!</span> <!--<span class="mdl-textfield__error">Input is not a number!</span>-->
<span *ngIf="field.validationSummary" class="mdl-textfield__error">{{field.validationSummary}}</span>
</div> </div>