Pull to refresh

Расширение возможностей Zend_Form с использованием ExtJS

Zend Framework
Zend Framework содержит удобное средство рендеринга форм – Zend_Form. Наиболее важными плюсами являются:
  • средства валидации данных (большое количество валидаторов);
  • средства фильтрации данных (например перевод дат в формат БД);
  • рендеринг формы с использованием декораторов;
  • экранирование выводимых данных.
Исходя из этого создать форму, обрабатываемую только серверной стороной не вызывает проблем. Однако сейчас этим уже никого не удивить. Отмечу, что Zend активно сотрудничает с Dojo для создания динамически обрабатываемых форм, но виджеты, разрабатываемые данной компанией, оставляют желать лучшего по сравнению с ExtJS. С этой точки зрения лучшим вариантом является корректировка рендеринга форм классом Zend_Form.

Наиболее интересным выглядит симбиоз ExtJS и Zend. Встроенная валидация полей виджета Ext.form.BasicForm может быть согласована с валидаторами серверной стороны. Здесь возможны существенные проблемы в виду использования различной философии при проверке полей. Например, в ExtJS использутся типы полей и дополнительные валидаторы, а в Zend_Form присутствуют только валидаторы. Но эта проблема разрешима, т.к. в клиентской части мы можем создавать свои типы данных, соответствующие функциям проверки, которые реализованы в Zend.

Обновлённый компонент на данном этапе должен выполнять две основные задачи: валидация и фильтрация данных, рендеринг форм. Поэтому в первую очередь было проведено сравнение возможностей двух библиотек, которые будут использованы при доработке компонента форм (Zend_Form и ExtJS.form.BasicForm). И в той, и в другой разработаны средства для решения поставленных задач. Поэтому основной проблемой является согласование функционала каждой из библиотек между собой.

Формулировка требований:
1. рендеринг формы;
2. валидация данных на клиенте (динамически, т.е. непосредственно после ввода данных, и до отправки формы);
3. вывод сообщений об ошибках с возможностью задания текста сообщения (динамически, т.е. непосредственно после ввода данных, и после отправки формы в случае, если ошибки были обнаружены уже на сервере);
4. фильтрация данных на клиенте (запрещение ввода недопустимых символов, ограничение по длине и т.п.);
5. валидация данных на сервере;
6. фильтрация данных на сервере.

1. Для решения первой задачи проще всего будет задействовать рендеринг компонентов формы при помощи стандартных классов, входящих в пакет Zend_Form_Element_*, и соответствующих им хелперов вида пакета Zend_View_Helper_*. Данные классы полностью отвечают за вывод полей формы на экран. Внешний вид самой формы, т.е. положение элементов на экране, подписей и т.п., определяется пакетом классов Zend_Form_Decorator_*. На мой взгляд, прибегать к добавлению новых декораторов следует только в том случае, если не удаётся придать нужный вид форме только при помощи CSS.
Из библиотеки ExtJS наиболее гибким элементом для работы с формами является объект Ext.form.BasicForm, который содержит базовый функционал для управления полями формы. Важным плюсом является возможность «накинуть» данный объект на существующую HTML форму. Таким образом, при отрисовке формы классом Zend_Form будет вставляться дополнительный код на javascript, отвечающий за связь с новым объектом Ext.form.BasicForm. Важно, что конфигурация формы, созданная на серверной стороне, будет определять опции полей для объекта на клиентской стороне. Т.е. конфигурационный массив будет передаваться в конструктор объекта Ext.form.BasicForm({…}), а также в функцию добавления полей Ext.form.BasicForm.add({…}). Таким образом, мы сможем рендерить стандартные формы только один раз задав их конфигурацию на сервере. Это сократит время, затрачиваемое на разработку новой формы в несколько раз.

2,4. Библиотека ExtJS содержит необходимый функционал для валидации данных непосредственно при вводе. Для этого необходимо добавлять поля, используя конструкторы специальных объектов, таких как Ext.form.HtmlEditor (упрощённый аналог FCKEditor), Ext.form.DateField (аналог календаря из Yahoo UI) и т.п. Кроме того, существует возможность устанавливать специальные подтипы полей, которые определены в статическом объекте Ext.form.VTypes. Важно то, что в этот объект могут быть добавлены новые подтипы, что упрощает синхронизацию валидаторов Zend Framework и ExtJS.
Также необходимо учесть, что ExtJS располагает дополнительными полями, такими как Ext.form.HtmlEditor, Ext.form.DateField и др. Поэтому необходимо реализовать серверные классы пакета Zend_Form_Element_* и соответствующих им классов Zend_View_Helper_* для простой и корректной работы с этими компонентами UI. В будущем, используя аналогичный механизм, будет возможно добавить новый элемент UI, разработав его клиентский объект, что допускается библиотекой ExtJS, и отвечающий ему серверный аналог. Таким образом набор компонентов может пополняться независимо разными людьми, т.к. они будут соответствовать двум общедоступным стандартам Zend Framework и ExtJS.
Фильтрация данных на клиентской части осуществляется также при помощи описанных выше объектов и подтипов, и останавливаться на этом пункте подробнее не имеет смысла.

3. Для вывода ошибок в ExtJS используется компонент Ext.QuickTips. Возможны 4 варианта отображения попапов с сообщениями, которые задаются свойством Ext.form.Field.msgTarget. Таким образом, для использования этого механизма необходимо инициализировать стандартный объект и установить тип уведомлений.
Согласно принятой схеме работы с формами (вся конфигурация устанавливается на серверной стороне) текст сообщений об ошибках будет задаваться для объекта класса Zend_Form, что делается установкой свойства, содержащего объект класса Zend_Translate. Последний будет содержать сообщения об ошибках для всех полей формы. Однако возможно существует вариант задания текста напрямую для каждого элемента формы. Данный вопрос нуждается в дополнительном исследовании.
На клиентской стороне, используя функционал, предлагаемый библиотекой ExtJS, также можно задать текст ошибок. Соответственно задача заключается синхронизации кода клиентской части и серверной, которая будет осуществляться на стадии рендеринга формы, когда с использованием конфигурации объекта Zend_Form и объектов Zend_Form_Element_* будет создаваться javascript код объекта Ext.BasicForm с добавлением всех необходимых полей.

5,6. Данная функциональность реализуется в Zend Framework при помощи двух пакетов: Zend_Validate_* и Zend_Filter_*. При создании объекта Zend_Form можно задавать несколько валидаторов или фильтров для каждого элемента формы. Существует 2 варианта проверки переданных данных: функция Zend_Form::isValid(), которая принимает массив и проверяет все данные на корректность, и функция Zend_Form::isValid(), которая служит для валидации частично переданных данных, например при Ajax проверках. Соответственно всегда можно добавить свой валидатор, используя интерфейс Zend_Validate_Interface.

Единственным существенным минусом существующих механизмов работы с данными форм является отсутствие поддержки валидации сразу по нескольким полям, например проверка совпадения password и confirm password. Кроме того следует обратить внимание, что некоторые механизмы требуют выполнения Ajax запросов для проверки данных. Это необходимо реализовать в качестве модуля form в MVC Zend Framework, т.к. в большинстве случаев это будут стандартные запросы.
Таким образом, мы получим достаточно удобный механизм создания автоматически валидируемых форм согласно заданной конфигурации. Однако, необходимо провести более тщательный анализ и создать подробную спецификацию того как должен работать данный механизм.

P.S. До начала собственно процесса кодирования хотелось бы услышать здоровую критику. Скорее всего что-то не было учтено сейчас, поэтому надеюсь это статья поможет спроектировать данный функционал с достаточной степенью абстракции. По завершении работ я представлю на суд хаброобщественности код данного компонента.
Tags:zendextjszend frameworkzend_formextjs.form
Hubs: Zend Framework
Total votes 16: ↑13 and ↓3+10
Views1.2K

Popular right now