Валидация с помощью Iodine
В данном разделе будет представлен пример того, как реализовать валидацию на стороне клиента с помощью библиотеки Iodine. Будем обрабатывать простую форму с двумя полями, поле ввода имени и E-mail.
Важно!
Валидация на стороне клиента небезопасна и должна быть реализована только для удобства пользователя.
Подключение библиотеки
Для простоты примера подключим её через CDN.
<script src="https://cdn.jsdelivr.net/npm/@caneara/iodine@8/dist/iodine.min.umd.js" defer></script>
Разметка формы
Ничего необычного, кроме атрибута novalidate
добавленного элементу формы. Он нужен для того, чтобы отключить встроенную в браузер валидацию.
<form action="[[~[[*id]]]]" method="post" novalidate>
<label> Имя
<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>Отправить</button>
</form>
Обработчик
Теперь нам предстоит добавить обработчик на событие fetchit:before
в котором и будет происходить валидация. Будем объяснять пошагово.
Добавление обработчика на событие
fetchit:before
.jsdocument.addEventListener('fetchit:before', (e) => { });
Получение ссылок на экземпляры классов
FormData
иFetchIt
.jsdocument.addEventListener('fetchit:before', (e) => { const { formData, fetchit } = e.detail; });
Библиотека Iodine может валидировать группу данных, если передать ей подготовленный объект в котором ключом будет являться название поля, а значением соответственно значение. Для этого нам всего лишь понадобиться превратить экземпляр FormData в простой объект.
jsdocument.addEventListener('fetchit:before', (e) => { const { formData, fetchit } = e.detail; const fields = Object.fromEntries(formData.entries()); });
Подготовим правила валидации полей.
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'], }; });
Произведем валидацию, записав результат в переменную.
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); });
Напишем условие при котором если валидация успешна, то завершаем работу нашего обработчика с помощью
return
. А далее вызываем методpreventDefault()
у нашего события, чтобы прекратить отправку формы.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(); });
Далее перебираем наши поля.
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)) { } });
Если поле валидно (речь идёт именно о состоянии валидации каждого поля, а не всех), то очищаем его ошибки с помощью метода
clearError()
, иначе добавляем ошибку полю воспользовавшись методомsetError()
.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); } });
Готово! Вот таким образом мы можем добавить валидацию используя библиотеку Iodine, но помните, на стороне клиента она небезопасна. И поэтому при вызове сниппета нужно воспользоваться средствами валидации FormIt или если вы используете собственный сниппет, то производить её еще и там.
Пример вызова сниппета с валидацией FormIt:
[[!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',
]}
Со списком всех валидаторов FormIt можете ознакомиться на сайте документации компонента.