
Validation with Iodine
This section shows how to implement client-side validation using the Iodine library. We will handle a simple form with two fields: name and email.
Important!
Client-side validation is not secure and should only be used to improve user experience.
Including the library
For simplicity we will load it via CDN.
<script src="https://cdn.jsdelivr.net/npm/@caneara/iodine@8/dist/iodine.min.umd.js" defer></script>Form markup
Nothing special, except the novalidate attribute on the form element to disable built-in browser validation.
<form action="[[~[[*id]]]]" method="post" novalidate>
<label> Name
<input type="text" name="name" value="[[+fi.name]]" />
<span data-error="name">[[+fi.error.name]]</span>
</label>
<label> E-mail
<input type="email" name="email" value="[[+fi.email]]" />
<span data-error="email">[[+fi.error.email]]</span>
</label>
<button>Submit</button>
</form>Handler
Add a handler for the fetchit:before event where validation will run. Step by step:
Add a handler for
fetchit:before.jsdocument.addEventListener('fetchit:before', (e) => { });Get references to the
FormDataandFetchItinstances.jsdocument.addEventListener('fetchit:before', (e) => { const { formData, fetchit } = e.detail; });Iodine can validate a set of data if you pass it an object whose keys are field names and values are the corresponding values. Convert the FormData instance to a plain object.
jsdocument.addEventListener('fetchit:before', (e) => { const { formData, fetchit } = e.detail; const fields = Object.fromEntries(formData.entries()); });Define validation rules for the fields.
jsdocument.addEventListener('fetchit:before', (e) => { const { formData, fetchit } = e.detail; const fields = Object.fromEntries(formData.entries()); const rules = { name: ['required', 'minLength:5'], email: ['required', 'email'], }; });Run validation and store the result.
jsdocument.addEventListener('fetchit:before', (e) => { const { formData, fetchit } = e.detail; const fields = Object.fromEntries(formData.entries()); const rules = { name: ['required', 'minLength:5'], email: ['required', 'email'], }; const validation = Iodine.assert(fields, rules); });If validation succeeds, exit the handler with
return. Otherwise callpreventDefault()on the event to stop form submission.jsdocument.addEventListener('fetchit:before', (e) => { const { formData, fetchit } = e.detail; const fields = Object.fromEntries(formData.entries()); const rules = { name: ['required', 'minLength:5'], email: ['required', 'email'], }; const validation = Iodine.assert(fields, rules); if (validation.valid) { return; } e.preventDefault(); });Loop over the fields.
jsdocument.addEventListener('fetchit:before', (e) => { const { formData, fetchit } = e.detail; const fields = Object.fromEntries(formData.entries()); const rules = { name: ['required', 'minLength:5'], email: ['required', 'email'], }; const validation = Iodine.assert(fields, rules); if (validation.valid) { return; } e.preventDefault(); for (const [ name, field ] of Object.entries(validation.fields)) { } });For each field: if it is valid, clear its error with
clearError(); otherwise set the error withsetError().jsdocument.addEventListener('fetchit:before', (e) => { const { formData, fetchit } = e.detail; const fields = Object.fromEntries(formData.entries()); const rules = { name: ['required', 'minLength:5'], email: ['required', 'email'], }; const validation = Iodine.assert(fields, rules); if (validation.valid) { return; } e.preventDefault(); for (const [ name, field ] of Object.entries(validation.fields)) { if (field.valid) { fetchit.clearError(name); continue; } fetchit.setError(name, field.error); } });
Done. You now have client-side validation with Iodine. Remember that client-side validation is not secure, so use FormIt validation when calling the snippet, or perform validation in your own snippet as well.
Example snippet call with FormIt validation:
[[!FetchIt?
&form=`myForm.tpl`,
&validate=`name:required:minLength=^5^,email:required:email`
]]{'!FetchIt' | snippet: [
'form' => 'myForm.tpl',
'validate' => 'name:required:minLength=^5^,email:required:email',
]}See the FormIt validators documentation for the full list.
