Часть 08 - валидация формы
В предыдущей части разработки компонента мы добавили форму для добавления и редактирования сообщения. Но любая форма перед отправкой требует определенной проверки.
Проверка на стороне клиента
На стороне клиента проверка формы осуществляется при помощи JavaScript. Внесите изменения в файл admin/views/helloworld/tmpl/edit.php:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Загружаем тултипы. JHtml::_('behavior.tooltip'); // Загружаем проверку формы. JHtml::_('behavior.formvalidation'); ?> <form action="<?php echo JRoute::_('index.php?option=com_helloworld&layout=edit&id=' . (int) $this->item->id); ?>" method="post" name="adminForm" id="helloworld-form" class="form-validate"> <fieldset> <legend><?php echo JText::_('COM_HELLOWORLD_HELLOWORLD_DETAILS'); ?></legend> <ul> <?php foreach ($this->form->getFieldset() as $field) : ?> <li><?php echo $field->label; echo $field->input; ?></li> <?php endforeach; ?> </ul> </fieldset> <div> <input type="hidden" name="task" value="" /> <?php echo JHtml::_('form.token'); ?> </div> </form>
Наша форма теперь содержит css-класс form-validate
и вызов JHtml::_('behavior.formvalidation');
, который сообщает Joomla о том, что необходимо использовать JavaScript для валидации формы.
Примечание: Если JHtml::_('behavior.tooltip'); не подключено - возникает онибка яваскрипт "window.addEvent is not a function"
Теперь внесем изменения в файл admin/models/forms/helloworld.xml, чтобы показать, что поле приветствия необходимо проверить:
<?xml version="1.0" encoding="utf-8"?> <form addrulepath="/administrator/components/com_helloworld/models/rules" > <fieldset> <field name="id" type="hidden" /> <field name="greeting" type="text" label="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_LABEL" description="COM_HELLOWORLD_HELLOWORLD_FIELD_GREETING_DESC" size="40" class="inputbox validate-greeting" validate="greeting" required="true" default="" /> </fieldset> </form>
Здесь мы добавили форме аттрибут addrulepath
, который понадобится нам для её проверки на стороне сервера. Значение этого аттрибута указывает путь, по которому находятся файлы, содержащие правила проверки.
Для поля мы добавили css-класс validate-greeting
и аттрибут required
со значением true
. Это означает, что поле является обязательным и должно быть проверено обработчиком валидатора формы фреймворка Joomla. Также мы добавили аттрибут validate
со значением greeting
. Значение указывает, какой файл необходимо использовать для проверки на стороне сервера.
Создайте файл admin/models/forms/helloworld.js:
window.addEvent('domready', function() { document.formvalidator.setHandler('greeting', function (value) { regex=/^[^0-9]+$/; return regex.test(value); }); });
Еще одна ремарка:
Можно задать правило проверки глобально для всего сайта, а не только конкретно для этой формы переопределив файл \media\system\js\validate.js в шаблне.
Там надо добавить эту функцию в поле инициализации класса JFormValidator примерно так:
............. var JFormValidator = new Class({ initialize : function () { this.handlers = {}; this.custom = {}; this.setHandler("username", function (a) { regex = /[<|>|"|'|%|;|(|)|&]/i; return !regex.test(a) }); ....... ....... this.setHandler('greeting',function (value) { regex=/^[^0-9]+$/; return regex.test(value); }); ..............
Мы добавили обработчик проверки полей у которых прописан css-класс validate-greeting
. Каждый раз, когда поле будет изменено, будет запущен обработчик для проверки формы на валидность. В нашем случае мы проверяем поле на отсутствие цифр.
Теперь добавляем проверку формы, когда будет нажата кнопка "Сохранить". Создайте файл admin/views/helloworld/submitbutton.js:
Joomla.submitbutton = function(task) { if (task == '') { return false; } else { var isValid = true; var action = task.split('.'); if (action[1] != 'cancel' && action[1] != 'close') { var forms = $$('form.form-validate'); for (var i = 0; i < forms.length; i++) { if (!document.formvalidator.isValid(forms[i])) { isValid = false; break; } } } if (isValid) { Joomla.submitform(task); return true; } else { alert(Joomla.JText._('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE', 'Some values are unacceptable')); return false; } } };
Эта функция проверяет, что все формы, содержащие css-класс form-validate
- валидны. Обратите внимание на то, что функция также выводит предупредительное сообщение, которое будет переведено фреймворком Joomla.
Внесем изменения в класс представления HelloWorldViewHelloWorld
, чтобы он мог использовать созданные javascript файлы:
admin/views/helloworld/view.html.php
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Подключаем библиотеку представления Joomla. jimport('joomla.application.component.view'); /** * HTML представление редактирования сообщения. */ class HelloWorldViewHelloWorld extends JViewLegacy { /** * Сообщение. * * @var object */ protected $item; /** * Объект формы. * * @var object */ protected $form; /** * JavaScript файл валидации формы. * * @var string */ protected $script; /** * Отображает представление. * * @param string $tpl Имя файла шаблона. * * @return void * * @throws Exception */ public function display($tpl = null) { try { // Получаем данные из модели. $this->form = $this->get('Form'); $this->item = $this->get('Item'); $this->script = $this->get('Script'); // Устанавливаем панель инструментов. $this->addToolBar(); // Отображаем представление. parent::display($tpl); // Устанавливаем документ. $this->setDocument(); } catch (Exception $e) { throw new Exception($e->getMessage()); } } /** * Устанавливает панель инструментов. * * @return void */ protected function addToolBar() { JFactory::getApplication()->input->set('hidemainmenu', true); $isNew = ($this->item->id == 0); JToolBarHelper::title($isNew ? JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_NEW') : JText::_('COM_HELLOWORLD_MANAGER_HELLOWORLD_EDIT'), 'helloworld'); JToolBarHelper::apply('helloworld.apply', 'JTOOLBAR_APPLY'); JToolBarHelper::save('helloworld.save'); JToolBarHelper::cancel('helloworld.cancel', $isNew ? 'JTOOLBAR_CANCEL' : 'JTOOLBAR_CLOSE'); } /** * Метод для установки свойств документа. * * @return void */ protected function setDocument() { $document = JFactory::getDocument(); $document->addScript(JURI::root() . $this->script); $document->addScript( JURI::root() . "administrator/components/com_helloworld/views/helloworld/submitbutton.js"); JText::script('COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE'); } }
Теперь представление добавляет два javascript файла и включает перевод javascript используя Joomla функцию JText::script()
.
Заключительным шагом является реализация метода getScript()
в модели HelloWorldModelHelloWorld
:
admin/models/helloworld.php
/** * Метод для получения скрипта, который будет включен в форму. * * @return string Файл скрипта. */ public function getScript() { return 'administrator/components/' . $this->option . '/models/forms/helloworld.js'; }
Добавьте его после метода getForm()
.
Проверка на стороне сервера
В файле admin/models/forms/helloworld.xml мы указали, что функция валидации на стороне сервера будет использовать файл с именем greeting и файл должен находиться в administrator/components/com_helloworld/models/rules. Создаем необходимый файл admin/models/rules/greeting.php:
<?php // Запрет прямого доступа. defined('_JEXEC') or die; // Подключаем библиотеку formrule. jimport('joomla.form.formrule'); /** * Правило формы для проверки поля приветствия. */ class JFormRuleGreeting extends JFormRule { /** * Регулярное выражение. * * @var string */ protected $regex = '^[^0-9]+$'; }
Все что мы сделали, это добавили регулярное выражение, которое проверяется родительским классом JFormRule с помощью метода test().
Добавляем языковые константы
Откройте файл admin/language/en-GB/en-GB.com_helloworld.ini и добавьте:COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE=”Some values are unacceptable”
Откройте файл admin/language/ru-RU/ru-RU.com_helloworld.ini и добавьте:COM_HELLOWORLD_HELLOWORLD_ERROR_UNACCEPTABLE=”Некоторые значения не валидны”
Собираем пакет установки компонента
Не забудьте поменять номер версии в файле helloworld.xml:
<version>0.0.8</version>
helloworld.xml
<?xml version="1.0" encoding="utf-8"?> <extension type="component" version="2.5.0" method="upgrade"> <name>COM_HELLOWORLD</name> <!-- Следующие элементы необязательны --> <creationDate>Июль 2012</creationDate> <author>Вася Пупкин</author> <authorEmail>Ваш e-mail</authorEmail> <authorUrl>Ваш сайт</authorUrl> <copyright>Информация о копирайте</copyright> <license>Информация о лицензии</license> <!-- Версия записывается в таблицу компонентов --> <version>0.0.8</version> <!-- Описание необязательно --> <description>COM_HELLOWORLD_DESCRIPTION</description> <!-- Запускается при установке --> <install> <sql> <file driver="mysql" charset="utf8">sql/install.mysql.utf8.sql</file> </sql> </install> <!-- Запускается при удалении --> <uninstall> <sql> <file driver="mysql" charset="utf8">sql/uninstall.mysql.utf8.sql</file> </sql> </uninstall> <!-- Запускается при обновлении --> <update> <schemas> <schemapath type="mysql">sql/updates/mysql</schemapath> </schemas> </update> <!-- Раздел основных файлов сайта --> <!-- Обратите внимание на значение аттрибута folder: Этот аттрибут описывает папку нашего пакета-установщика из которой должны копироваться файлы. Поэтому указанные в этом разделе файлы будут скопированы из папки /site/ нашего пакета-установщика в соответствующую папку установки. --> <files folder="site"> <filename>index.html</filename> <filename>controller.php</filename> <filename>helloworld.php</filename> <folder>language</folder> <folder>models</folder> <folder>views</folder> </files> <media destination="com_helloworld" folder="media"> <filename>index.html</filename> <folder>images</folder> </media> <!-- Администрирование --> <administration> <!-- Раздел Меню --> <menu img="../media/com_helloworld/images/hello-16x16.png">COM_HELLOWORLD_MENU</menu> <!-- Раздел основных файлов администрирования --> <!-- Обратите внимание на значение аттрибута folder: Этот аттрибут описывает папку нашего пакета-установщика из которой должны копироваться файлы. Поэтому указанные в этом разделе файлы будут скопированы из папки /admin/ нашего пакета-установщика в соответствующую папку установки. --> <files folder="admin"> <filename>index.html</filename> <filename>controller.php</filename> <filename>helloworld.php</filename> <folder>controllers</folder> <folder>models</folder> <folder>sql</folder> <folder>tables</folder> <folder>views</folder> </files> <languages folder="admin"> <language tag="en-GB">language/en-GB/en-GB.com_helloworld.ini</language> <language tag="en-GB">language/en-GB/en-GB.com_helloworld.sys.ini</language> <language tag="ru-RU">language/ru-RU/ru-RU.com_helloworld.ini</language> <language tag="ru-RU">language/ru-RU/ru-RU.com_helloworld.sys.ini</language> </languages> </administration> </extension>
Содержимое директории с кодом:
helloworld.xml
site/index.html
site/helloworld.php
site/controller.php
site/language/index.html
site/language/en-GB/index.html
site/language/en-GB/en-GB.com_helloworld.ini
site/language/ru-RU/index.html
site/language/ru-RU/ru-RU.com_helloworld.ini
site/models/index.html
site/models/helloworld.php
site/views/index.html
site/views/helloworld/index.html
site/views/helloworld/view.html.php
site/views/helloworld/tmpl/index.html
site/views/helloworld/tmpl/default.xml
site/views/helloworld/tmpl/default.php
admin/index.html
admin/controller.php
admin/helloworld.php
admin/controllers/index.html
admin/controllers/helloworld.php
admin/controllers/helloworlds.php
admin/language/index.html
admin/language/en-GB/index.html
admin/language/en-GB/en-GB.com_helloworld.ini
admin/language/en-GB/en-GB.com_helloworld.sys.ini
admin/language/ru-RU/index.html
admin/language/ru-RU/ru-RU.com_helloworld.ini
admin/language/ru-RU/ru-RU.com_helloworld.sys.ini
admin/models/index.html
admin/models/helloworld.php
admin/models/helloworlds.php
admin/models/fields/index.html
admin/models/fields/helloworld.php
admin/models/forms/index.html
admin/models/forms/helloworld.js
admin/models/forms/helloworld.xml
admin/models/rules/index.html
admin/models/rules/greeting.php
admin/sql/index.html
admin/sql/install.mysql.utf8.sql
admin/sql/uninstall.mysql.utf8.sql
admin/sql/updates/index.html
admin/sql/updates/mysql/index.html
admin/sql/updates/mysql/0.0.1.sql
admin/sql/updates/mysql/0.0.4.sql
admin/tables/index.html
admin/tables/helloworld.php
admin/views/index.html
admin/views/helloworld/index.html
admin/views/helloworld/view.html.php
admin/views/helloworld/submitbutton.js
admin/views/helloworld/tmpl/index.html
admin/views/helloworld/tmpl/edit.php
admin/views/helloworlds/index.html
admin/views/helloworlds/view.html.php
admin/views/helloworlds/tmpl/index.html
admin/views/helloworlds/tmpl/default.php
admin/views/helloworlds/tmpl/default_body.php
admin/views/helloworlds/tmpl/default_foot.php
admin/views/helloworlds/tmpl/default_head.php
language/index.html
language/en-GB/index.html
language/en-GB/en-GB.com_helloworld.sys.ini
language/ru-RU/index.html
language/ru-RU/ru-RU.com_helloworld.sys.ini
media/index.html
media/images/index.html
media/images/hello-16x16.png
media/images/hello-48x48.png
Запакуйте директорию в архивный файл (zip, tar, tar.gz, bz2) или скачайте его напрямую c GitHub. Далее установите его, используя менеджер расширений Joomla. Теперь попробуйте добавить/отредактировать приветствие, указав в нем цифры. Форма не должна пройти валидацию:
В следующей части мы добавим поддержку категорий.
Код для этой части
Скачать com_helloworld часть 8
Актуальный код части 8 на GitHub