validateField static method

String? validateField({
  1. required FormFieldModel field,
  2. required Map<String, dynamic> formData,
  3. required List<NestedContext> contexts,
})

Implementation

static String? validateField({
  required FormFieldModel field,
  required Map<String, dynamic> formData,
  required List<NestedContext> contexts,
}) {
  // If field has no validations, it's valid
  if (field.validations == null || field.validations!.isEmpty) {
    return null;
  }

  // Get the current field's value
  final fieldKey = FormSchemaTraversal.getFormFieldKey(contexts);
  final fieldValue = getNestedFormValue(formData, fieldKey);

  // Check each validation rule
  for (final validationRule in field.validations!) {
    // First check if this validation rule should be applied based on its dependencies
    if (validationRule.dependencies.isNotEmpty) {
      var shouldApplyValidation = true;

      for (final dependency in validationRule.dependencies) {
        final resolvedFieldPath = _resolveTemplatedFieldPath(
          dependency.field,
          contexts,
        );

        final dependencyValue = getNestedFormValue(
          formData,
          resolvedFieldPath,
        );

        final conditionMet = _evaluateCondition(
          dependencyValue,
          dependency.operator,
          dependency.compareValue,
        );

        if (!conditionMet) {
          // Dependency not met, skip this validation rule
          shouldApplyValidation = false;
          break;
        }
      }

      // If dependencies are not met, skip this validation rule
      if (!shouldApplyValidation) {
        continue;
      }
    }

    // If all dependencies are satisfied (or no dependencies),
    // check the validation rule itself
    final validationPassed = _evaluateValidationRule(
      fieldValue,
      validationRule,
    );

    if (!validationPassed) {
      // Validation failed, return the validation's message
      return validationRule.message;
    }
  }

  // 📝⚠️ LEGACY NOTE: to support legacy required check
  // TODO: remove this once all forms are migrated
  if (field.required == true &&
      (fieldValue == null || fieldValue.toString().isEmpty)) {
    if (field.type == 'terms_checkbox') {
      if (fieldValue.toString() != 'true') {
        if (field.validations != null) {
          String? error;
          for (final validation in field.validations!) {
            error = validation.message;
            return getString(error);
          }
        }
        return '${getString(field.label)} ${getString('is_required')}';
      }
    } else if (fieldValue == null || fieldValue.toString().isEmpty) {
      return '${getString(field.label)} ${getString('is_required')}';
    }
  }

  // All validations and their dependencies passed
  return null;
}