mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-08-29 11:00:40 +08:00
Add field type validators
- Add validators for specific field types
This commit is contained in:
parent
ba542821c2
commit
801632388b
11 changed files with 582 additions and 2 deletions
|
@ -1,4 +1,5 @@
|
||||||
import {FieldManager} from '@services/record/field/field.manager';
|
import {FieldManager} from '@services/record/field/field.manager';
|
||||||
import {validationManagerMock} from '@services/record/validation/validation.manager.spec.mock';
|
import {validationManagerMock} from '@services/record/validation/validation.manager.spec.mock';
|
||||||
|
import {dataTypeFormatterMock} from '@services/formatters/data-type.formatter.spec.mock';
|
||||||
|
|
||||||
export const fieldManagerMock = new FieldManager(validationManagerMock);
|
export const fieldManagerMock = new FieldManager(validationManagerMock, dataTypeFormatterMock);
|
||||||
|
|
|
@ -1,4 +1,26 @@
|
||||||
import {ValidationManager} from '@services/record/validation/validation.manager';
|
import {ValidationManager} from '@services/record/validation/validation.manager';
|
||||||
import {RequiredValidator} from '@services/record/validation/validators/required.validator';
|
import {RequiredValidator} from '@services/record/validation/validators/required.validator';
|
||||||
|
import {RangeValidator} from '@services/record/validation/validators/range.validator';
|
||||||
|
import {CurrencyValidator} from '@services/record/validation/validators/currency.validator';
|
||||||
|
import {DateValidator} from '@services/record/validation/validators/date.validator';
|
||||||
|
import {DateTimeValidator} from '@services/record/validation/validators/datetime.validator';
|
||||||
|
import {EmailValidator} from '@services/record/validation/validators/email.validator';
|
||||||
|
import {FloatValidator} from '@services/record/validation/validators/float.validator';
|
||||||
|
import {IntValidator} from '@services/record/validation/validators/int.validator';
|
||||||
|
import {PhoneValidator} from '@services/record/validation/validators/phone.validator';
|
||||||
|
import {numberFormatterMock} from '@services/formatters/number/number-formatter.spec.mock';
|
||||||
|
import {dateFormatterMock} from '@services/formatters/datetime/date-formatter.service.spec.mock';
|
||||||
|
import {datetimeFormatterMock} from '@services/formatters/datetime/datetime-formatter.service.spec.mock';
|
||||||
|
import {phoneFormatterMock} from '@services/formatters/phone/phone-formatter.spec.mock';
|
||||||
|
|
||||||
export const validationManagerMock = new ValidationManager(new RequiredValidator());
|
export const validationManagerMock = new ValidationManager(
|
||||||
|
new RequiredValidator(),
|
||||||
|
new RangeValidator(),
|
||||||
|
new CurrencyValidator(numberFormatterMock),
|
||||||
|
new DateValidator(dateFormatterMock),
|
||||||
|
new DateTimeValidator(datetimeFormatterMock),
|
||||||
|
new EmailValidator(),
|
||||||
|
new FloatValidator(numberFormatterMock),
|
||||||
|
new IntValidator(numberFormatterMock),
|
||||||
|
new PhoneValidator(phoneFormatterMock)
|
||||||
|
);
|
||||||
|
|
|
@ -6,6 +6,14 @@ import {AsyncValidatorFn, ValidatorFn} from '@angular/forms';
|
||||||
import {AsyncValidatorInterface} from '@services/record/validation/aync-validator.Interface';
|
import {AsyncValidatorInterface} from '@services/record/validation/aync-validator.Interface';
|
||||||
import {OverridableMap} from '@app-common/types/OverridableMap';
|
import {OverridableMap} from '@app-common/types/OverridableMap';
|
||||||
import {RequiredValidator} from '@services/record/validation/validators/required.validator';
|
import {RequiredValidator} from '@services/record/validation/validators/required.validator';
|
||||||
|
import {CurrencyValidator} from '@services/record/validation/validators/currency.validator';
|
||||||
|
import {DateValidator} from '@services/record/validation/validators/date.validator';
|
||||||
|
import {DateTimeValidator} from '@services/record/validation/validators/datetime.validator';
|
||||||
|
import {FloatValidator} from '@services/record/validation/validators/float.validator';
|
||||||
|
import {IntValidator} from '@services/record/validation/validators/int.validator';
|
||||||
|
import {EmailValidator} from '@services/record/validation/validators/email.validator';
|
||||||
|
import {PhoneValidator} from '@services/record/validation/validators/phone.validator';
|
||||||
|
import {RangeValidator} from '@services/record/validation/validators/range.validator';
|
||||||
|
|
||||||
export interface ValidationManagerInterface {
|
export interface ValidationManagerInterface {
|
||||||
registerValidator(module: string, key: string, validator: ValidatorInterface): void;
|
registerValidator(module: string, key: string, validator: ValidatorInterface): void;
|
||||||
|
@ -30,12 +38,28 @@ export class ValidationManager implements ValidationManagerInterface {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected requiredValidator: RequiredValidator,
|
protected requiredValidator: RequiredValidator,
|
||||||
|
protected rangeValidator: RangeValidator,
|
||||||
|
protected currencyValidator: CurrencyValidator,
|
||||||
|
protected dateValidator: DateValidator,
|
||||||
|
protected datetimeValidator: DateTimeValidator,
|
||||||
|
protected emailValidator: EmailValidator,
|
||||||
|
protected floatValidator: FloatValidator,
|
||||||
|
protected intValidator: IntValidator,
|
||||||
|
protected phoneValidator: PhoneValidator,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
this.validators = new OverridableMap<ValidatorInterface>();
|
this.validators = new OverridableMap<ValidatorInterface>();
|
||||||
this.asyncValidators = new OverridableMap<AsyncValidatorInterface>();
|
this.asyncValidators = new OverridableMap<AsyncValidatorInterface>();
|
||||||
|
|
||||||
this.validators.addEntry('default', 'required', requiredValidator);
|
this.validators.addEntry('default', 'required', requiredValidator);
|
||||||
|
this.validators.addEntry('default', 'range', rangeValidator);
|
||||||
|
this.validators.addEntry('default', 'currency', currencyValidator);
|
||||||
|
this.validators.addEntry('default', 'date', dateValidator);
|
||||||
|
this.validators.addEntry('default', 'datetime', datetimeValidator);
|
||||||
|
this.validators.addEntry('default', 'email', emailValidator);
|
||||||
|
this.validators.addEntry('default', 'float', floatValidator);
|
||||||
|
this.validators.addEntry('default', 'int', intValidator);
|
||||||
|
this.validators.addEntry('default', 'phone', phoneValidator);
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerValidator(module: string, key: string, validator: ValidatorInterface): void {
|
public registerValidator(module: string, key: string, validator: ValidatorInterface): void {
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
import {ValidatorInterface} from '@services/record/validation/validator.Interface';
|
||||||
|
import {AbstractControl} from '@angular/forms';
|
||||||
|
import {Record} from '@app-common/record/record.model';
|
||||||
|
import {ViewFieldDefinition} from '@app-common/metadata/metadata.model';
|
||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {NumberFormatter} from '@services/formatters/number/number-formatter.service';
|
||||||
|
import {StandardValidationErrors, StandardValidatorFn} from '@app-common/services/validators/validators.model';
|
||||||
|
|
||||||
|
export const currencyValidator = (formatter: NumberFormatter): StandardValidatorFn => (
|
||||||
|
(control: AbstractControl): StandardValidationErrors | null => {
|
||||||
|
|
||||||
|
if (control.value == null || control.value.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pattern = formatter.getFloatUserFormatPattern();
|
||||||
|
const regex = new RegExp(pattern);
|
||||||
|
|
||||||
|
if (regex.test(control.value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
currencyValidator: {
|
||||||
|
valid: false,
|
||||||
|
format: pattern,
|
||||||
|
message: {
|
||||||
|
labelKey: 'LBL_VALIDATION_ERROR_CURRENCY_FORMAT',
|
||||||
|
context: {
|
||||||
|
value: control.value,
|
||||||
|
expected: formatter.toUserFormat('1000.50')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class CurrencyValidator implements ValidatorInterface {
|
||||||
|
|
||||||
|
constructor(protected formatter: NumberFormatter) {
|
||||||
|
}
|
||||||
|
|
||||||
|
applies(record: Record, viewField: ViewFieldDefinition): boolean {
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewField.type === 'currency';
|
||||||
|
}
|
||||||
|
|
||||||
|
getValidator(viewField: ViewFieldDefinition): StandardValidatorFn[] {
|
||||||
|
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [currencyValidator(this.formatter)];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
import {ValidatorInterface} from '@services/record/validation/validator.Interface';
|
||||||
|
import {AbstractControl} from '@angular/forms';
|
||||||
|
import {Record} from '@app-common/record/record.model';
|
||||||
|
import {ViewFieldDefinition} from '@app-common/metadata/metadata.model';
|
||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {DateFormatter} from '@services/formatters/datetime/date-formatter.service';
|
||||||
|
import {StandardValidationErrors, StandardValidatorFn} from '@app-common/services/validators/validators.model';
|
||||||
|
|
||||||
|
export const dateValidator = (formatter: DateFormatter): StandardValidatorFn => (
|
||||||
|
(control: AbstractControl): StandardValidationErrors | null => {
|
||||||
|
const invalid = formatter.validateUserFormat(control.value);
|
||||||
|
return invalid ? {
|
||||||
|
invalidDate: {
|
||||||
|
value: control.value,
|
||||||
|
message: {
|
||||||
|
labelKey: 'LBL_VALIDATION_ERROR_DATE_FORMAT',
|
||||||
|
context: {
|
||||||
|
value: control.value,
|
||||||
|
expected: formatter.toUserFormat('2020-01-12')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
} : null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class DateValidator implements ValidatorInterface {
|
||||||
|
|
||||||
|
constructor(protected formatter: DateFormatter) {
|
||||||
|
}
|
||||||
|
|
||||||
|
applies(record: Record, viewField: ViewFieldDefinition): boolean {
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewField.type === 'date';
|
||||||
|
}
|
||||||
|
|
||||||
|
getValidator(viewField: ViewFieldDefinition): StandardValidatorFn[] {
|
||||||
|
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [dateValidator(this.formatter)];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
import {ValidatorInterface} from '@services/record/validation/validator.Interface';
|
||||||
|
import {AbstractControl} from '@angular/forms';
|
||||||
|
import {Record} from '@app-common/record/record.model';
|
||||||
|
import {ViewFieldDefinition} from '@app-common/metadata/metadata.model';
|
||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {DatetimeFormatter} from '@services/formatters/datetime/datetime-formatter.service';
|
||||||
|
import {StandardValidationErrors, StandardValidatorFn} from '@app-common/services/validators/validators.model';
|
||||||
|
|
||||||
|
export const dateTimeValidator = (formatter: DatetimeFormatter): StandardValidatorFn => (
|
||||||
|
(control: AbstractControl): StandardValidationErrors | null => {
|
||||||
|
const invalid = formatter.validateUserFormat(control.value);
|
||||||
|
return invalid ? {
|
||||||
|
dateTimeValidator: {
|
||||||
|
value: control.value,
|
||||||
|
message: {
|
||||||
|
labelKey: 'LBL_VALIDATION_ERROR_DATETIME_FORMAT',
|
||||||
|
context: {
|
||||||
|
value: control.value,
|
||||||
|
expected: formatter.toUserFormat('2020-01-12 12:30:40')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} : null;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class DateTimeValidator implements ValidatorInterface {
|
||||||
|
|
||||||
|
constructor(protected formatter: DatetimeFormatter) {
|
||||||
|
}
|
||||||
|
|
||||||
|
applies(record: Record, viewField: ViewFieldDefinition): boolean {
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewField.type === 'datetime';
|
||||||
|
}
|
||||||
|
|
||||||
|
getValidator(viewField: ViewFieldDefinition): StandardValidatorFn[] {
|
||||||
|
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [dateTimeValidator(this.formatter)];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
import {ValidatorInterface} from '@services/record/validation/validator.Interface';
|
||||||
|
import {AbstractControl, Validators} from '@angular/forms';
|
||||||
|
import {Record} from '@app-common/record/record.model';
|
||||||
|
import {ViewFieldDefinition} from '@app-common/metadata/metadata.model';
|
||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {StandardValidationErrors, StandardValidatorFn} from '@app-common/services/validators/validators.model';
|
||||||
|
|
||||||
|
export const emailValidator = (): StandardValidatorFn => (
|
||||||
|
(control: AbstractControl): StandardValidationErrors | null => {
|
||||||
|
|
||||||
|
const result = Validators.email(control);
|
||||||
|
|
||||||
|
if (result === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
emailValidator: {
|
||||||
|
...result,
|
||||||
|
message: {
|
||||||
|
labelKey: 'LBL_VALIDATION_ERROR_EMAIL_FORMAT',
|
||||||
|
context: {
|
||||||
|
value: control.value,
|
||||||
|
expected: 'example@example.org'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class EmailValidator implements ValidatorInterface {
|
||||||
|
|
||||||
|
applies(record: Record, viewField: ViewFieldDefinition): boolean {
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewField.type === 'email';
|
||||||
|
}
|
||||||
|
|
||||||
|
getValidator(viewField: ViewFieldDefinition): StandardValidatorFn[] {
|
||||||
|
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [emailValidator()];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
import {ValidatorInterface} from '@services/record/validation/validator.Interface';
|
||||||
|
import {AbstractControl} from '@angular/forms';
|
||||||
|
import {Record} from '@app-common/record/record.model';
|
||||||
|
import {ViewFieldDefinition} from '@app-common/metadata/metadata.model';
|
||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {NumberFormatter} from '@services/formatters/number/number-formatter.service';
|
||||||
|
import {StandardValidationErrors, StandardValidatorFn} from '@app-common/services/validators/validators.model';
|
||||||
|
|
||||||
|
export const floatValidator = (formatter: NumberFormatter): StandardValidatorFn => (
|
||||||
|
(control: AbstractControl): StandardValidationErrors | null => {
|
||||||
|
|
||||||
|
if (control.value == null || control.value.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pattern = formatter.getFloatUserFormatPattern();
|
||||||
|
const regex = new RegExp(pattern);
|
||||||
|
|
||||||
|
if (regex.test(control.value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
floatValidator: {
|
||||||
|
valid: false,
|
||||||
|
format: pattern,
|
||||||
|
message: {
|
||||||
|
labelKey: 'LBL_VALIDATION_ERROR_FLOAT_FORMAT',
|
||||||
|
context: {
|
||||||
|
value: control.value,
|
||||||
|
expected: formatter.toUserFormat('1000.50')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class FloatValidator implements ValidatorInterface {
|
||||||
|
|
||||||
|
constructor(protected formatter: NumberFormatter) {
|
||||||
|
}
|
||||||
|
|
||||||
|
applies(record: Record, viewField: ViewFieldDefinition): boolean {
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewField.type === 'float';
|
||||||
|
}
|
||||||
|
|
||||||
|
getValidator(viewField: ViewFieldDefinition): StandardValidatorFn[] {
|
||||||
|
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [floatValidator(this.formatter)];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
import {ValidatorInterface} from '@services/record/validation/validator.Interface';
|
||||||
|
import {AbstractControl} from '@angular/forms';
|
||||||
|
import {Record} from '@app-common/record/record.model';
|
||||||
|
import {ViewFieldDefinition} from '@app-common/metadata/metadata.model';
|
||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {NumberFormatter} from '@services/formatters/number/number-formatter.service';
|
||||||
|
import {StandardValidationErrors, StandardValidatorFn} from '@app-common/services/validators/validators.model';
|
||||||
|
|
||||||
|
export const intValidator = (formatter: NumberFormatter): StandardValidatorFn => (
|
||||||
|
(control: AbstractControl): StandardValidationErrors | null => {
|
||||||
|
|
||||||
|
if (control.value == null || control.value.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pattern = formatter.getIntUserFormatPattern();
|
||||||
|
const regex = new RegExp(pattern);
|
||||||
|
|
||||||
|
if (regex.test(control.value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
intValidator: {
|
||||||
|
valid: false,
|
||||||
|
format: pattern,
|
||||||
|
message: {
|
||||||
|
labelKey: 'LBL_VALIDATION_ERROR_INT_FORMAT',
|
||||||
|
context: {
|
||||||
|
value: control.value,
|
||||||
|
expected: formatter.toUserFormat('1000')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class IntValidator implements ValidatorInterface {
|
||||||
|
|
||||||
|
constructor(protected formatter: NumberFormatter) {
|
||||||
|
}
|
||||||
|
|
||||||
|
applies(record: Record, viewField: ViewFieldDefinition): boolean {
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewField.type === 'int';
|
||||||
|
}
|
||||||
|
|
||||||
|
getValidator(viewField: ViewFieldDefinition): StandardValidatorFn[] {
|
||||||
|
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [intValidator(this.formatter)];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
import {ValidatorInterface} from '@services/record/validation/validator.Interface';
|
||||||
|
import {AbstractControl} from '@angular/forms';
|
||||||
|
import {Record} from '@app-common/record/record.model';
|
||||||
|
import {ViewFieldDefinition} from '@app-common/metadata/metadata.model';
|
||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {PhoneFormatter} from '@services/formatters/phone/phone-formatter.service';
|
||||||
|
import {StandardValidationErrors, StandardValidatorFn} from '@app-common/services/validators/validators.model';
|
||||||
|
|
||||||
|
export const phoneValidator = (formatter: PhoneFormatter): StandardValidatorFn => (
|
||||||
|
(control: AbstractControl): StandardValidationErrors | null => {
|
||||||
|
|
||||||
|
if (control.value == null || control.value.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pattern = formatter.getUserFormatPattern();
|
||||||
|
const regex = new RegExp(pattern, 'g');
|
||||||
|
|
||||||
|
if (regex.test(control.value)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
phoneValidator: {
|
||||||
|
valid: false,
|
||||||
|
format: pattern,
|
||||||
|
message: {
|
||||||
|
labelKey: 'LBL_VALIDATION_ERROR_PHONE_FORMAT',
|
||||||
|
context: {
|
||||||
|
value: control.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class PhoneValidator implements ValidatorInterface {
|
||||||
|
|
||||||
|
constructor(protected formatter: PhoneFormatter) {
|
||||||
|
}
|
||||||
|
|
||||||
|
applies(record: Record, viewField: ViewFieldDefinition): boolean {
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewField.type === 'phone';
|
||||||
|
}
|
||||||
|
|
||||||
|
getValidator(viewField: ViewFieldDefinition): StandardValidatorFn[] {
|
||||||
|
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [phoneValidator(this.formatter)];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
import {ValidatorInterface} from '@services/record/validation/validator.Interface';
|
||||||
|
import {AbstractControl, Validators} from '@angular/forms';
|
||||||
|
import {Record} from '@app-common/record/record.model';
|
||||||
|
import {ViewFieldDefinition} from '@app-common/metadata/metadata.model';
|
||||||
|
import {FieldDefinition, ValidationDefinition} from '@app-common/record/field.model';
|
||||||
|
import {Injectable} from '@angular/core';
|
||||||
|
import {StandardValidationErrors, StandardValidatorFn} from '@app-common/services/validators/validators.model';
|
||||||
|
|
||||||
|
export const minValidator = (min: number): StandardValidatorFn => (
|
||||||
|
(control: AbstractControl): StandardValidationErrors | null => {
|
||||||
|
|
||||||
|
const result = Validators.min(min)(control);
|
||||||
|
|
||||||
|
if (result === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
emailValidator: {
|
||||||
|
...result,
|
||||||
|
message: {
|
||||||
|
labelKey: 'LBL_VALIDATION_ERROR_MIN',
|
||||||
|
context: {
|
||||||
|
value: control.value,
|
||||||
|
min: '' + min
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export const maxValidator = (max: number): StandardValidatorFn => (
|
||||||
|
(control: AbstractControl): StandardValidationErrors | null => {
|
||||||
|
|
||||||
|
const result = Validators.max(max)(control);
|
||||||
|
|
||||||
|
if (result === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
emailValidator: {
|
||||||
|
...result,
|
||||||
|
message: {
|
||||||
|
labelKey: 'LBL_VALIDATION_ERROR_MAX',
|
||||||
|
context: {
|
||||||
|
value: control.value,
|
||||||
|
max: '' + max
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class RangeValidator implements ValidatorInterface {
|
||||||
|
|
||||||
|
applies(record: Record, viewField: ViewFieldDefinition): boolean {
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const definition = viewField.fieldDefinition;
|
||||||
|
|
||||||
|
return this.getRangeValidation(definition) !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getValidator(viewField: ViewFieldDefinition): StandardValidatorFn[] {
|
||||||
|
|
||||||
|
if (!viewField || !viewField.fieldDefinition) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const validation = this.getRangeValidation(viewField.fieldDefinition);
|
||||||
|
|
||||||
|
if (!validation) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const min = validation.min && parseInt('' + validation.min, 10);
|
||||||
|
const max = validation.max && parseInt('' + validation.max, 10);
|
||||||
|
const validations = [];
|
||||||
|
|
||||||
|
if (isFinite(min)) {
|
||||||
|
validations.push(minValidator(min));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isFinite(max)) {
|
||||||
|
validations.push(maxValidator(max));
|
||||||
|
}
|
||||||
|
|
||||||
|
return validations;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getRangeValidation(definition: FieldDefinition): ValidationDefinition {
|
||||||
|
|
||||||
|
if (this.isRangeValidation(definition.validation)) {
|
||||||
|
return definition.validation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!definition.validations || !definition.validations.length) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let validation: ValidationDefinition = null;
|
||||||
|
|
||||||
|
definition.validations.some(entry => {
|
||||||
|
validation = entry;
|
||||||
|
return this.isRangeValidation(entry);
|
||||||
|
});
|
||||||
|
|
||||||
|
return validation;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected isRangeValidation(validation: ValidationDefinition): boolean {
|
||||||
|
return validation && validation.type === 'range';
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue