Powered by CodeIgniter

Уроки

(28)
14
16 голосов
Учиться, учиться и еще раз учиться — развитие личности идет таким путем.
Известное дело — разработку любого веб-приложения можно поделить на этапы, а сами этапы — на типовые задачи. Одной из наиболее часто встречающихся типовых задач является работа с формами. Каждый раз, когда программисту приходится сталкиваться с ней, можно словить некоторое уныние, если надоевшая рутина не оформлена подобающим образом. Прежде, чем уйти под кат, покажу вам, как реализована работа с формами в cogear:
$this->form->set('add-comments') ->input('subject',array('validation' => 'required|max_length[80]')) ->editor('body',array('validation'=>'required|min_length[5]')) ->buttons('send'); if($result = $this->form->result()){ if($this->form->save('comments',$result)){ redirect('/node_url'); } } $this->form->compile();
Выше показана наиболее простая, но очень эффективная форма работы, простите за каламбур, с формами.

Один код в ответе за все


Нет нужды создавать отдельные методы контроллера для ловли данных — все функции на себя берет один кусочек кода.

Первым делом мы задаем id формы, который пригодится нам при использовании хуков или же при ином деле.
$this->form->set('add-comments') После этого цепочкой задаются элементы и их параметры, а также кнопки формы.
// Добавляем поле типа "текст" ->input('subject', array('validation' => 'required|max_length[80]')) // Добавляем поле типа "редактор" ->editor('body',array('validation'=>'required|min_length[5]')) // Задаем кнопки ->buttons('send');
Сразу же небольшое отступления для ответов на возможные вопросы:
1. При формировании вывода label к элементу берется на основании указанной, либо общей переменной перевода (общие хранятся в разделе edit).
Допустим, у нас есть языковой файл, в котором заданы названия и описания наших полей.
[my_form] subject = "Заголовок комментария" subject_description = "Укажите заголовок комментария. Не более 80 символов." body = "Текст" body_description = "Текст комментария не должен быть слишком коротким – от 5 символов и больше, пожалуйста." // Функция-ярлык для задания текущего раздела классу i18n d('my_form'); $this->form->set('add-comments') ->input('subject', array('validation' => 'required|max_length[80]')) ->editor('body',array('validation'=>'required|min_length[5]')) ->buttons('send'); if($result = $this->form->result()){ if($this->form->save('comments',$result)){ redirect('/node_url'); } } $this->form->compile(); Если перед выводом формы задать текущий раздел переводов, то на выходе мы получим форму следующего вида:

2. Обработка ошибок идет автоматически на базе указанных правил. Никаких дополнительных действий с вашей стороны не требуется.

Работа с ошибками

Вы отправляете форму, и если валидация не проходит, форма выводится по-новой с отображением ошибок.


Можно усовершенствовать форму, добавив валидацию на Javascript до ее отправки.
// Функция-ярлык для задания текущего раздела классу i18n d('my_form'); $this->form->set('add-comments') ->input('subject', array('validation' => 'required|max_length[80]','js_validation'=>'required|length[5,80]')) ->editor('body',array('validation'=>'required|min_length[5]','js_validation'=>'required|length[5,-1]')) ->buttons('send'); if($result = $this->form->result()){ if($this->form->save('comments',$result)){ redirect('/node_url'); } } $this->form->compile();
Обновив страницу увидим, что теперь скрипты не дадут нам отправить форму до того, как она будет заполнена корректно.


Если вы уже задались вопросом, почему отличаются правила для пре- и пост-валидации, отвечаю:
— Для пре-валидации используется доработанный класс MooTools.Floor Form Check.
— Для пост-валидации используется доработанная библиотека CodeIgniter (который лежит в основе движка).

Напоследок приведу более развернутый пример — с упрощенным созданием/редактированием топиков.

… class Index extends Controller{ … /** * Создание и редактирование топиков. * * @param int $id id топика * @return void */ function createdit($id = FALSE){ // Функция-ярлык для задания текущего раздела классу i18n d('node_edit'); // Определяем, существует ли топик if($id && $node = $this->db->get_where('nodes',array('id'=>$id))->row()){ /* * Если топик существует задаем иной заголовок страницы * Строка перевода выглядит следующим образом * … * edit = "Редактирование топика '%s'" * … */ title(t('edit',$node->name)); } else { // Можно указать раздел перевода и явным образом title(t('node_edit create')); } // Задаем имя формы $this->form->set('node-createdit') // Добавляем поле типа "текст" ->input('subject', array('validation' => 'required|max_length[80]','js_validation'=>'required|length[-1,80]')) // Добавляем поле типа "редактор" ->editor('body',array('validation'=>'required|min_length[5]','js_validation'=>'required|length[5,-1]')) // Задаем кнопки // Если топик не сущесвует или мы не в режим редактирования, то будет отображена кнопка "Сохранить" вместо "Создать". ->buttons(empty($node) ? 'create' : 'save'); // Если топик существует — заполняем форму его значениями if(!empty($node)){ $this->form->set_values($node); } // Ловим результат обработки формы if($result = $this->form->result()){ // Если топик существует — обновляем его if(!empty($node) && $this->form->update('nodes',$result,array('id'=>$node->id)){ redirect('/nodes/'.$node->id); } // Создаем новый топик elseif($this->form->save('comments',$result)){ redirect('/'.$this->form->insert_id); } } // Выводим форму $this->form->compile(); } … }
Разумеется, в данном топик показаны самые простые примеры работы с формами в cogear — для простоты восприятия и наглядности.
Наша реализация работы с формами хорошо себя зарекомендовала за последний год — она позволяет сократить время на разработку типовых задача ввода и обработки информации до минимума. Да, в кому-то она может показаться не идеальной, но

Надеюсь, вам понравился краткий экскурс в собственные задумки.

Если есть вопрос — задавайте, если хотите продолжения — будет и оно.
21:53 ← 21 февраля 2010 Отправить в Твиттер adminadmin  RSS comments 12

Комментарии (12) ↓

Ildar Ildar time 23:27 ← 21 февраля 2010 #
В переводе есть «subject_description» а в форме о нем не упоминает, он добавляется автоматически?
Автор
admin admin time 23:57 ← 21 февраля 2010 #
Как же не упоминает? Вглядись внимательнее.
Minister Minister time 02:09 ← 22 февраля 2010 #
Действительно, я тоже не вижу ни одного упоминания. Даже поиском по странице прошелся :))
agoodis agoodis time 02:15 ← 22 февраля 2010 #
Я понял description автоматически добавляется после поля.
inetlover inetlover time 08:48 ← 22 февраля 2010 #
Считаю, что это одно из главных достоинств движка, я на своей практике ни где подобного не встречал. По аналогии я сделал себе нужные формы с нужными полями, но не смог только сделать radio поля.

Был бы очень рад, если продолжение или Урок был бы посвящен созданию radio полей в профиле, с помощью которых дать юзеру возможность выбирать, например: браузер которым пользуется или мужчина он или женщина или его знак зодиака, а потом где-нибудь отображать всю эту статистику.

Мне кажется, такая фишка будет интересна, так как будет показывать из каких людей и с какими предпочтениями состоит сообщество.
Автор
admin admin time 10:42 ← 22 февраля 2010 #
Хорошо, договорились, будет урок по radio-кнопкам.
Minister Minister time 11:06 ← 22 февраля 2010 #
Тогда можно заодно будет описать как делаются checkbox, select, upload.
Автор
admin admin time 11:07 ← 22 февраля 2010 #
Хорошо, будет.
inetlover inetlover time 11:54 ← 22 февраля 2010 #
Спасибо большое! :-)
Ramir Ramir time 16:46 ← 21 января 2011 #
Дима, а как сделать проверку поля своей функцией?
Интресует проверка правильности даты.
inetlover inetlover time 23:04 ← 21 января 2011 #
Интресует проверка правильности даты.
Если речь идет про поле datetime, то достаточно добавить 'validation'=>'required' ->datetime('birth',array('range'=>'1900-'.date('Y'),'value'=>date('Y-m-d H:i:s'),'validation'=>'required'))
Ramir Ramir time 00:35 ← 22 января 2011 #
БлагоДарю, но не совсем то. Есть 2 поля: дата начала и дата конца. Нужно проверить, чтобы дата конца была больше даты начала.