Skip to main content

Form Validation

eSheet provides a validation system that respects conditional logic -- hidden fields are excluded from validation.

Validation API

Validation functions are exported from @esheet/core:

import { validateForm, validateField } from '@esheet/core';

Validation Rules

const handleSubmit = () => {
const formStore = ref.current?.getFormStore();
if (!formStore) return;

const errors = formStore.getState().getErrors();

if (errors.length > 0) {
console.log('Validation errors:', errors);
return;
}

// Form is valid -- proceed with submission
const responses = ref.current.getResponse();
submitToServer(responses);
};

Error Shape

const formStore = ref.current?.getFormStore();
const fieldErrors = formStore?.getState().getFieldErrors('field_id');

if (fieldErrors && fieldErrors.length > 0) {
console.log('Field errors:', fieldErrors);
}

Required Fields

When a field has required: true (or is made required by a conditional rule), it must have a non-empty response:

Field Type"Empty" definition
text, longtextanswer is undefined, null, or empty string
radio, dropdown, boolean, rating, sliderselected is undefined
check, multiselectdropdown, rankingselected is undefined or empty array
multitextAll values in multitextAnswers are empty
singlematrix, multimatrixNot all rows have selections
signaturesignatureData is undefined or empty
diagrammarkupData is undefined or empty

Conditional Awareness

Validation automatically respects conditional logic:

  • Hidden fields (visibility = false) -> not validated, even if required
  • Disabled fields are still validated by the current core validator unless hidden by visibility logic
  • Conditionally required fields -> validated only when the required rule evaluates to true

This means users are never blocked by fields they can't see or interact with.

Validation errors are returned as an array:

interface FieldError {
fieldId: string;
message: string;
}

Example:

[
{ "fieldId": "name", "message": "This field is required" },
{ "fieldId": "email", "message": "This field is required" }
]

Example: Submit with Validation

import { useRef, useState } from 'react';
import { EsheetRenderer } from '@esheet/renderer';
import type { EsheetRendererHandle } from '@esheet/renderer';

function ValidatedForm({ formData }) {
const ref = useRef<EsheetRendererHandle>(null);
const [errors, setErrors] = useState([]);

const handleSubmit = () => {
const formStore = ref.current?.getFormStore();
if (!formStore) return;

const validationErrors = formStore.getState().getErrors();

if (validationErrors.length > 0) {
setErrors(validationErrors);
return;
}

setErrors([]);
const responses = ref.current.getResponse();
// Submit responses...
};

return (
<div>
<EsheetRenderer ref={ref} formData={formData} />
{errors.length > 0 && (
<div style={{ color: 'red', margin: '1rem 0' }}>
<p>Please fix the following errors:</p>
<ul>
{errors.map((err) => (
<li key={err.fieldId}>
{err.message} ({err.fieldId})
</li>
))}
</ul>
</div>
)}
<button onClick={handleSubmit}>Submit</button>
</div>
);
}