Svelte 5 Form validation made simple.
In order to define intialValues you pass valibot schema.
const { values, errors, touched, markTouched, handleSubmit } = useForm({
initialValues: {
email: "",
password: "",
},
schema: signInSchema,
onSubmit(values) {
console.log("submitted ", values);
// TODO: add api call
},
});
Valibot schema that you'd use for values(email,password) i.e:
export const passwordPolicy = v.pipe(
v.string(),
v.trim(),
v.minLength(8, "Password must be at least 8 characters long."),
v.maxLength(64, "Password must be at most 64 characters long."),
v.regex(/[A-Z]/, "Password must contain at least 1 uppercase letter."),
v.regex(/[0-9]/, "Password must contain at least 1 number."),
v.regex(
/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]/,
"Password must contain at least 1 special character.",
),
);
export const signInSchema = v.object({
email: v.pipe(
v.string(),
v.trim(),
v.email("Please provide a valid email address."),
),
password: passwordPolicy,
});
In order to capture submitted values you simply do:
<form onsubmit={handleSubmit}>
To update each value you can simply use bind:value to individual writable signals,i.e $values.email
To mark any input element as touched you can use markTouched function with the name of the field in order for form to track its touched state,that way you can display errors conditionally only if you interacted with the form input, without using $touched.<fieldname>, you'd be displaying errors immediately.
<Input
id="email"
type="email"
placeholder="[email protected]"
bind:value={$values.email}
onblur={() => markTouched("email")}
/>
{#if $touched.email && $errors.email}
<FieldError>{$errors.email}</FieldError>
{/if}
If you'd like to adjust how fast validation parsing gets executed since by default we have debounce interval of 50ms you can adjust it by doing:
Example on how to define 500ms debounce(useful for searchbars that trigger api calls):
debounceInterval: 500
const { values, errors, touched, markTouched, handleSubmit } = useForm({
initialValues: {
email: "",
password: "",
},
schema: signInSchema,
debounceInterval:500
onSubmit(values) {
console.log("submitted ", values);
// TODO: add api call
},
});