Pull to refresh

Работа с формами

Reading time6 min
Views3.6K
Известное дело — разработку любого веб-приложения можно поделить на этапы, а сами этапы — на типовые задачи. Одной из наиболее часто встречающихся типовых задач является работа с формами. Каждый раз, когда программисту приходится сталкиваться с ней, можно словить некоторое уныние, если надоевшая рутина не оформлена подобающим образом. Прежде, чем уйти под кат, покажу вам, как реализована работа с формами в 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();


* This source code was highlighted with Source Code Highlighter.


Выше показана наиболее простая, но очень эффективная форма работы, простите за каламбур, с формами.

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


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

Первым делом мы задаем id формы, который пригодится нам при использовании хуков или же при ином деле.
$this->form->set('add-comments')

* This source code was highlighted with Source Code Highlighter.

После этого цепочкой задаются элементы и их параметры, а также кнопки формы.
    // Добавляем поле типа "текст"
    ->input('subject', array('validation' => 'required|max_length[80]'))
    // Добавляем поле типа "редактор"
    ->editor('body',array('validation'=>'required|min_length[5]'))
    // Задаем кнопки
    ->buttons('send');

* This source code was highlighted with Source Code Highlighter.


Сразу же небольшое отступления для ответов на возможные вопросы:
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();


* This source code was highlighted with Source Code Highlighter.


Если перед выводом формы задать текущий раздел переводов, то на выходе мы получим форму следующего вида:


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();

* This source code was highlighted with Source Code Highlighter.


Обновив страницу увидим, что теперь скрипты не дадут нам отправить форму до того, как она будет заполнена корректно.


Если вы уже задались вопросом, почему отличаются правила для пре- и пост-валидации, отвечаю:
— Для пре-валидации используется доработанный класс 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();
  }
  …
}


* This source code was highlighted with Source Code Highlighter.


Разумеется, в данном топик показаны самые простые примеры работы с формами в cogear — для простоты восприятия и наглядности.
Наша реализация работы с формами хорошо себя зарекомендовала за последний год — она позволяет сократить время на разработку типовых задача ввода и обработки информации до минимума. Да, в кому-то она может показаться не идеальной, но

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

Если есть вопрос — задавайте, если хотите продолжения — будет и оно.

Как вы организуете работу с формами?
Tags:
Hubs:
+5
Comments23

Articles