Skip to content
Playground

Validation

By default form data will be validated by HTML5 validation and provided validator only on submission.

By utilizing Svelte 5 reactivity, we can easily implement live validation.

<script lang="ts">
import { SvelteMap } from "svelte/reactivity";
import Ajv from "ajv";
import { Form, type Errors, type Schema } from "@sjsf/form";
import { translation } from "@sjsf/form/translations/en";
import { theme } from "@sjsf/form/basic-theme";
import {
AjvValidator,
addFormComponents,
DEFAULT_AJV_CONFIG,
} from "@sjsf/ajv8-validator";
const validator = new AjvValidator(
addFormComponents(new Ajv(DEFAULT_AJV_CONFIG))
);
const schema: Schema = {
type: "string",
minLength: 7,
};
let form: Form<any, any>;
let value = $state("initial");
let errors: Errors = $state.raw(new SvelteMap());
$effect(() => {
value;
errors = form.validate();
});
</script>
<Form
bind:this={form}
bind:value
bind:errors
{...theme}
{schema}
{validator}
{translation}
onSubmit={console.log}
/>

While it is possible, this approach has low efficiency, because usually revalidation of the whole form when changing one field does not make sense.

Inputs validation

Instead of full form revalidation, we propose to perform revalidation of only the input field and full validation of the form when submitting.

<script lang="ts">
import { ON_CHANGE, ON_INPUT, AFTER_SUBMITTED } from "@sjsf/form";
import CustomForm from "@/components/custom-form.svelte";
import { objectSchema } from "./_demo-schemas";
</script>
<CustomForm
schema={objectSchema}
inputsValidationMode={ON_INPUT | ON_CHANGE | AFTER_SUBMITTED}
novalidate
onSubmit={console.log}
/>

The form in this example will only revalidate input fields on the input and change events after the first submission of the form.

Focus on first error

You can achieve focus on the first error by using the focusOnFirstError function.

<script lang="ts">
import { focusOnFirstError } from "@sjsf/form/focus-on-first-error";
import CustomForm from "@/components/custom-form.svelte";
import { objectSchema } from "./_demo-schemas";
</script>
<CustomForm
schema={objectSchema}
novalidate
onSubmitError={focusOnFirstError}
/>

  1. focusOnFirstError will try to find a focusable element and focus it.
  2. If it’s not found, it will try to find an errors list and scroll it into view.
  3. If it’s not found, it will return false.

Errors list

Creating a list of errors is pretty simple.

<script lang="ts">
import type { ErrorObject } from 'ajv';
import type { Errors } from "@sjsf/form";
import { SvelteMap } from 'svelte/reactivity';
import CustomForm from "@/components/custom-form.svelte";
import { objectSchema } from './_demo-schemas';
let errors: Errors<ErrorObject> = $state.raw(new SvelteMap());
</script>
<CustomForm
bind:errors
schema={objectSchema}
novalidate
onSubmit={console.log}
/>
{#if errors.size > 0}
<div style="padding-top: 1rem;">
<span style="font-size: larger; font-weight: bold;">Errors</span>
<ui style="color: red;">
{#each errors as [field, fieldErrors] (field)}
{#each fieldErrors as err}
<li>"{err.propertyTitle}" {err.message}</li>
{/each}
{/each}
</ui>
</div>
{/if}