Добрый день.
В этом топике я расскажу о удобном jQuery-плагине для валидации веб-форм, простом и мощном, при том — совершенно неизбыточном. Если вам не интересны подробности создания и сравнение с аналогами (точнее — с аналогом), смотрите конец топика, там ссылка на примеры и исходный код.
Некоторое время назад мне пришлось дорабатывать клиент-сайд ресурса, включающего просто невероятное количество анкетных форм. Одной из неприятных особенностей этих форм было жуткое количество разнотипных правил валидации ввода и ещё большее количество взаимосвязей между полями.
Пример: если выбран чекбокс А, то в поле Х можно ввести только цифры, а поле Y должно быть скрыто, но если дополнительно выбрана радиокнопка Z, то поле Y нужно показать, а в поле X можно ввести всё, кроме цифр.
Иными словами — сущий ад, рождённый нездоровым сознанием маркетологов.
Несмотря на то, что существует немалое количество способов валидации содержимого полей ввода (вплоть до стандартных браузерных… только, к сожалению, не кроссбраузерных), существовало только одно подходящее клиентское решение, позволявшее устанавливать сложные связи между несколькими полями — фреймворк ZForms, который изначально и использовался на ресурсе. Пожалуй, на том, что он это умел, его плюсы и заканчивались, затем начинались сплошные минусы:
— Неочевидный и неудобный способ задания правил валидации в обработчике onclick (!). Существует ещё недокументированный способ задания этих правил через XML-подобные вставки напрямую в код страницы, но это ещё больший ужас.
— Фреймворк модифицирует DOM-дерево, при этом требуя особых условий к его структуре. Например, изменяемое при валидации свойство применяется не к полю, а… к его предку второго (!!) порядка, что нужно было учитывать при вёрстке.
— Валидируемые контролы, по сути, подменяются виджетами фреймворка, даже там, где это не требуется. В большинстве случаев это означает невозможность использования каких-либо других средств работы с полем. Не описать словами, сколько зла я сгенерировал, скрещивая ZForms с jQuery UI…
— Отвратительная событийная модель работы. ZForms работает только с событиями собственных виджетов, и подписаться можно также только на них. Доходило вплоть до того, что приходилось вешать проверку валидности на таймер.
— Куча багов (вылезающих, как обычно, уже на продакшене), исправлять которые приходилось влезая в минимизированный код фреймворка, либо костылируя этот код своим.
И, в конце концов, последняя версия ZForms вышла аж в 2009 году, и его jQuery-версия совсем не хотела работать с последними версиями библиотеки.
В общем, тут был явно тот случай, когда требовалось закатать рукава и решить задачу с нуля. Это я и сделал, написав jquery.lemongrab.
Основные идеи lemongrab таковы:
— Плагин не пытается быть чем-то, чем он не является. Он делает одну задачу, но делает это хорошо.
— Плагин использует возможности HTML5, при этом оставляя возможность работы на старых браузерах.
— Валидация задаётся максимально удобно для конкретного случая.
— Плагин не конфликтует с другими обработчиками.
Работа плагина тестировалась на всех современных и не очень браузерах, как десктопных, так и мобильных. В итоге, всё зависит от используемой версии jQuery — проблемы (впрочем, легко решённые) возникли только на IE младше 9 версии.
— Плагин умеет проверять состояние любых полей ввода, и в зависимости от заданных правил, менять состояния элементов (этих же, или любых других). Изменяемые состояния: валидность, обязательность, доступность, видимость.
Если с доступностью и видимостью всё понятно (это, соответственно, атрибут enabled и css-свойство display), то про валидность и обязательность стоит объяснить. И то и другое подсмотрено в том же ZForms; по сути эти атрибуты — просто классы, добавляемые к полю в случае, если оно валидно/невалидно и в случае, если оно обязательно должно быть заполнено (в этом случае ещё добавляется HTML5-атрибут required). Плагин не даст сабмитить форму, в которой есть поля с такими атрибутами (хотя и это настраивается).
— У плагина простая и очевидная событийная модель. Произошло событие, скажем, какой-то элемент стал валиден, — для него сгенерировалось событие lemongrab.valid. Перестал быть валиден — сгенерировалось lemongrab.novalid.
— Правила задаются в JSON, который может быть прописан как непосредственно в data-атрибуте валидируемого элемента, так и загружен при инициализации плагина. Первое удобно задании правил непосредственно в коде страницы, последнее — при выносе правил в отдельный файл (ZForms, кстати, так не умеет).
— Для валидации могут использоваться простые свойства (например checked/unchecked для checkbox), регулярные выражения, состояния наборов полей, и даже jQuery-селекторы. В случае, если и этого не хватает, для проверки состояния можно использовать пользовательскую функцию.
— Количество правил для элемента неограничено, и комбинироваться они могут как угодно. Плагину можно задать логику совмещения правил (и/или/не), для более сложных вариантов есть всё те же пользовательские функции.
— В плагине куча всяких маленьких дополнительных плюшечек, описанных в документации.
Как это выглядит?
Парочка наглядных примеров:
Поле будет валидно (ему добавится класс ACCEPTABLE), в случае соответствия его содержимого регэкспу:
Поле #id2 будет доступно для ввода, если выбрана вторая радиокнопка:
Документация и интерактивные примеры.
С тех пор, как я написал эту штуку, жизнь моя стала прельстива и любовна, чего и вам желаю, а потому выкладываю код в открытый доступ: репозиторий на github.
В этом топике я расскажу о удобном jQuery-плагине для валидации веб-форм, простом и мощном, при том — совершенно неизбыточном. Если вам не интересны подробности создания и сравнение с аналогами (точнее — с аналогом), смотрите конец топика, там ссылка на примеры и исходный код.
Некоторое время назад мне пришлось дорабатывать клиент-сайд ресурса, включающего просто невероятное количество анкетных форм. Одной из неприятных особенностей этих форм было жуткое количество разнотипных правил валидации ввода и ещё большее количество взаимосвязей между полями.
Пример: если выбран чекбокс А, то в поле Х можно ввести только цифры, а поле Y должно быть скрыто, но если дополнительно выбрана радиокнопка Z, то поле Y нужно показать, а в поле X можно ввести всё, кроме цифр.
Иными словами — сущий ад, рождённый нездоровым сознанием маркетологов.
Несмотря на то, что существует немалое количество способов валидации содержимого полей ввода (вплоть до стандартных браузерных… только, к сожалению, не кроссбраузерных), существовало только одно подходящее клиентское решение, позволявшее устанавливать сложные связи между несколькими полями — фреймворк ZForms, который изначально и использовался на ресурсе. Пожалуй, на том, что он это умел, его плюсы и заканчивались, затем начинались сплошные минусы:
— Неочевидный и неудобный способ задания правил валидации в обработчике onclick (!). Существует ещё недокументированный способ задания этих правил через XML-подобные вставки напрямую в код страницы, но это ещё больший ужас.
— Фреймворк модифицирует DOM-дерево, при этом требуя особых условий к его структуре. Например, изменяемое при валидации свойство применяется не к полю, а… к его предку второго (!!) порядка, что нужно было учитывать при вёрстке.
— Валидируемые контролы, по сути, подменяются виджетами фреймворка, даже там, где это не требуется. В большинстве случаев это означает невозможность использования каких-либо других средств работы с полем. Не описать словами, сколько зла я сгенерировал, скрещивая ZForms с jQuery UI…
— Отвратительная событийная модель работы. ZForms работает только с событиями собственных виджетов, и подписаться можно также только на них. Доходило вплоть до того, что приходилось вешать проверку валидности на таймер.
— Куча багов (вылезающих, как обычно, уже на продакшене), исправлять которые приходилось влезая в минимизированный код фреймворка, либо костылируя этот код своим.
И, в конце концов, последняя версия ZForms вышла аж в 2009 году, и его jQuery-версия совсем не хотела работать с последними версиями библиотеки.
В общем, тут был явно тот случай, когда требовалось закатать рукава и решить задачу с нуля. Это я и сделал, написав jquery.lemongrab.
Основные идеи lemongrab таковы:
— Плагин не пытается быть чем-то, чем он не является. Он делает одну задачу, но делает это хорошо.
— Плагин использует возможности HTML5, при этом оставляя возможность работы на старых браузерах.
— Валидация задаётся максимально удобно для конкретного случая.
— Плагин не конфликтует с другими обработчиками.
Работа плагина тестировалась на всех современных и не очень браузерах, как десктопных, так и мобильных. В итоге, всё зависит от используемой версии jQuery — проблемы (впрочем, легко решённые) возникли только на IE младше 9 версии.
Что lemongrab может?
— Плагин умеет проверять состояние любых полей ввода, и в зависимости от заданных правил, менять состояния элементов (этих же, или любых других). Изменяемые состояния: валидность, обязательность, доступность, видимость.
Если с доступностью и видимостью всё понятно (это, соответственно, атрибут enabled и css-свойство display), то про валидность и обязательность стоит объяснить. И то и другое подсмотрено в том же ZForms; по сути эти атрибуты — просто классы, добавляемые к полю в случае, если оно валидно/невалидно и в случае, если оно обязательно должно быть заполнено (в этом случае ещё добавляется HTML5-атрибут required). Плагин не даст сабмитить форму, в которой есть поля с такими атрибутами (хотя и это настраивается).
— У плагина простая и очевидная событийная модель. Произошло событие, скажем, какой-то элемент стал валиден, — для него сгенерировалось событие lemongrab.valid. Перестал быть валиден — сгенерировалось lemongrab.novalid.
— Правила задаются в JSON, который может быть прописан как непосредственно в data-атрибуте валидируемого элемента, так и загружен при инициализации плагина. Первое удобно задании правил непосредственно в коде страницы, последнее — при выносе правил в отдельный файл (ZForms, кстати, так не умеет).
— Для валидации могут использоваться простые свойства (например checked/unchecked для checkbox), регулярные выражения, состояния наборов полей, и даже jQuery-селекторы. В случае, если и этого не хватает, для проверки состояния можно использовать пользовательскую функцию.
— Количество правил для элемента неограничено, и комбинироваться они могут как угодно. Плагину можно задать логику совмещения правил (и/или/не), для более сложных вариантов есть всё те же пользовательские функции.
— В плагине куча всяких маленьких дополнительных плюшечек, описанных в документации.
Как это выглядит?
Парочка наглядных примеров:
Поле будет валидно (ему добавится класс ACCEPTABLE), в случае соответствия его содержимого регэкспу:
<form id="sample">
<input type="text" data-rule-valid='[{"key":"regexp","value":"^.{1,5}$"}]' /></code>
<script>$("#sample").lemongrab();</script>
</form>
Поле #id2 будет доступно для ввода, если выбрана вторая радиокнопка:
<form id="sample">
<fieldset id="selectbox">
<input type="radio" name="test" value="1" id="1" />
<input type="radio" name="test" value="2" id="2" />
<input type="radio" name="test" value="3" id="3" />
<input type="radio" name="test" value="4" id="4" />
</fieldset>
<input type="text" data-rule-enabled='[{"key":"c", "selector":"#3"}]' />
<script>$("#sample1").lemongrab();</script>
</form>
Документация и интерактивные примеры.
С тех пор, как я написал эту штуку, жизнь моя стала прельстива и любовна, чего и вам желаю, а потому выкладываю код в открытый доступ: репозиторий на github.