Skip to content

Commit

Permalink
chore: cleanup and deprecate validateField
Browse files Browse the repository at this point in the history
Related to #1147
  • Loading branch information
Skaiir committed Apr 19, 2024
1 parent 5bef6df commit 1f1efd0
Showing 1 changed file with 79 additions and 76 deletions.
155 changes: 79 additions & 76 deletions packages/form-js-viewer/src/core/Validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,51 +10,23 @@ const PHONE_PATTERN =
const VALIDATE_FEEL_PROPERTIES = ['min', 'max', 'minLength', 'maxLength'];

export class Validator {
constructor(expressionLanguage, conditionChecker, form) {
constructor(expressionLanguage, conditionChecker, form, formFieldRegistry) {
this._expressionLanguage = expressionLanguage;
this._conditionChecker = conditionChecker;
this._form = form;
this._formFieldRegistry = formFieldRegistry;
}

/**
* @deprecated use validateFieldInstance instead
*/
validateField(field, value) {
const { type, validate } = field;

let errors = [];

if (type === 'number') {
const { decimalDigits, increment } = field;

if (value === 'NaN') {
errors = [...errors, 'Value is not a number.'];
} else if (value) {
if (decimalDigits >= 0 && countDecimals(value) > decimalDigits) {
errors = [
...errors,
'Value is expected to ' +
(decimalDigits === 0
? 'be an integer'
: `have at most ${decimalDigits} decimal digit${decimalDigits > 1 ? 's' : ''}`) +
'.',
];
}

if (increment) {
const bigValue = Big(value);
const bigIncrement = Big(increment);

const offset = bigValue.mod(bigIncrement);

if (offset.cmp(0) !== 0) {
const previousValue = bigValue.minus(offset);
const nextValue = previousValue.plus(bigIncrement);

errors = [
...errors,
`Please select a valid value, the two nearest valid values are ${previousValue} and ${nextValue}.`,
];
}
}
}
errors = runNumberValidation(field, value, errors);
}

if (!validate) {
Expand All @@ -68,65 +40,96 @@ export class Validator {
this._form,
);

if (evaluatedValidation.pattern && value && !new RegExp(evaluatedValidation.pattern).test(value)) {
errors = [...errors, `Field must match pattern ${evaluatedValidation.pattern}.`];
errors = runPresetValidation(field, evaluatedValidation, value, errors);

return errors;
}
}

Validator.$inject = ['expressionLanguage', 'conditionChecker', 'form', 'formFieldRegistry'];

// helpers //////////

function runNumberValidation(field, value, errors) {
const { decimalDigits, increment } = field;

if (value === 'NaN') {
errors = [...errors, 'Value is not a number.'];
} else if (value) {
if (decimalDigits >= 0 && countDecimals(value) > decimalDigits) {
errors = [
...errors,
'Value is expected to ' +
(decimalDigits === 0
? 'be an integer'
: `have at most ${decimalDigits} decimal digit${decimalDigits > 1 ? 's' : ''}`) +
'.',
];
}

if (evaluatedValidation.required) {
const isUncheckedCheckbox = type === 'checkbox' && value === false;
const isUnsetValue = isNil(value) || value === '';
const isEmptyMultiselect = Array.isArray(value) && value.length === 0;
if (increment) {
const bigValue = Big(value);
const bigIncrement = Big(increment);

const offset = bigValue.mod(bigIncrement);

if (isUncheckedCheckbox || isUnsetValue || isEmptyMultiselect) {
errors = [...errors, 'Field is required.'];
if (offset.cmp(0) !== 0) {
const previousValue = bigValue.minus(offset);
const nextValue = previousValue.plus(bigIncrement);

errors = [
...errors,
`Please select a valid value, the two nearest valid values are ${previousValue} and ${nextValue}.`,
];
}
}
}

if ('min' in evaluatedValidation && (value || value === 0) && value < evaluatedValidation.min) {
errors = [...errors, `Field must have minimum value of ${evaluatedValidation.min}.`];
}
return errors;
}

if ('max' in evaluatedValidation && (value || value === 0) && value > evaluatedValidation.max) {
errors = [...errors, `Field must have maximum value of ${evaluatedValidation.max}.`];
}
function runPresetValidation(field, validation, value, errors) {
if (validation.pattern && value && !new RegExp(validation.pattern).test(value)) {
errors = [...errors, `Field must match pattern ${validation.pattern}.`];
}

if ('minLength' in evaluatedValidation && value && value.trim().length < evaluatedValidation.minLength) {
errors = [...errors, `Field must have minimum length of ${evaluatedValidation.minLength}.`];
}
if (validation.required) {
const isUncheckedCheckbox = field.type === 'checkbox' && value === false;
const isUnsetValue = isNil(value) || value === '';
const isEmptyMultiselect = Array.isArray(value) && value.length === 0;

if ('maxLength' in evaluatedValidation && value && value.trim().length > evaluatedValidation.maxLength) {
errors = [...errors, `Field must have maximum length of ${evaluatedValidation.maxLength}.`];
if (isUncheckedCheckbox || isUnsetValue || isEmptyMultiselect) {
errors = [...errors, 'Field is required.'];
}
}

if (
'validationType' in evaluatedValidation &&
value &&
evaluatedValidation.validationType === 'phone' &&
!PHONE_PATTERN.test(value)
) {
errors = [...errors, 'Field must be a valid international phone number. (e.g. +4930664040900)'];
}
if ('min' in validation && (value || value === 0) && value < validation.min) {
errors = [...errors, `Field must have minimum value of ${validation.min}.`];
}

if (
'validationType' in evaluatedValidation &&
value &&
evaluatedValidation.validationType === 'email' &&
!EMAIL_PATTERN.test(value)
) {
errors = [...errors, 'Field must be a valid email.'];
}
if ('max' in validation && (value || value === 0) && value > validation.max) {
errors = [...errors, `Field must have maximum value of ${validation.max}.`];
}

return errors;
if ('minLength' in validation && value && value.trim().length < validation.minLength) {
errors = [...errors, `Field must have minimum length of ${validation.minLength}.`];
}
}

Validator.$inject = ['expressionLanguage', 'conditionChecker', 'form'];
if ('maxLength' in validation && value && value.trim().length > validation.maxLength) {
errors = [...errors, `Field must have maximum length of ${validation.maxLength}.`];
}

// helpers //////////
if ('validationType' in validation && value && validation.validationType === 'phone' && !PHONE_PATTERN.test(value)) {
errors = [...errors, 'Field must be a valid international phone number. (e.g. +4930664040900)'];
}

if ('validationType' in validation && value && validation.validationType === 'email' && !EMAIL_PATTERN.test(value)) {
errors = [...errors, 'Field must be a valid email.'];
}

return errors;
}

/**
* Helper function to evaluate optional FEEL validation values.
*/
function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form) {
const evaluatedValidate = { ...validate };

Expand Down

0 comments on commit 1f1efd0

Please sign in to comment.