Вэб формы - techart/bitrix.tao GitHub Wiki

Формы в ТАО.Bitrix реализованы на основе инфоблоков. Т.е. данные, отправленные с формы, будут сохраняться как элементы инфоблока.

Создание новой формы

  1. Создаем инфоблок, где будут храниться данные, отправленные с формы. Т.е., описывая свойства инфоблока (properties), мы описываем поля, которые будут выводиться на форме + поля, необходимые для работы с данными в админке или еще где-то.

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

// local/bundles/Feedback/lib/Infoblock/Questions.php
namespace App\Bundle\Feedback\Infoblock;

use TAO\Infoblock;

class Questions extends Infoblock
{
	public function title()
	{
		return 'Задать вопрос';
	}

	public function properties()
	{
		return array(
			'name' => array(
				'NAME' => 'Имя',
				'SORT' => '100',
				'PROPERTY_TYPE' => 'S',
				'IS_REQUIRED' => 'Y',
			),
			'email' => array(
				'NAME' => 'E-Mail',
				'SORT' => '200',
				'PROPERTY_TYPE' => 'S',
			),
			
			'text' => array(
				'NAME' => 'Комментарий',
				'SORT' => '600',
				'PROPERTY_TYPE' => 'S',
				'ROW_COUNT' => '5',
			),
			'answer' => array(
				'NAME' => 'Текст ответа',
				'SORT' => '700',
				'PROPERTY_TYPE' => 'S',
				'ROW_COUNT' => '5',
			),
		);

	}

}
  1. Описываем класс формы.

Например, Questions.php (local/forms/Questions.php.).

// local/forms/Questions.php
namespace App\Form;

class Questions extends \TAO\Form
{
	public function options()
	{
		return array(
			'infoblock' => 'questions',
			'layout' => 'block',
			'show_labels' => true,
			'show_placeholders' => false,
			'submit_text' => 'Оставить сообщение',
		);
	}

	public function styles()
	{
		return array('name' => 'width:100%;', 'email' => 'width:100%;', 'text' => 'width:100%;');
	}

	public function properties()
	{
		$props = parent::properties(); //получаем родительские свойства
		unset($props['answer']); //отключаем ненужные свойства на форме
		return $props;
	}
}

Стандартные опции при настройке формы:

  • infoblock - символьный код инфоблока, где будут храниться данные с формы.

  • ajax - подключение режима отправки формы по ajax.

  • error_title - вывод заголовка ошибки в режиме ajax.

  • layout - подключение шаблона формы. В стандартном решении предоставляются на выбор 2 шаблона: table, block.

  • return_url - url, по которому будет выводиться сообщение об отправке данных с формы. Применяется для режима ajax.

  • on_ok - если проверка отработает успешно.

  • on_error - соответственно, если проверка выдаст ошибку. На данные опции можно повесить свою javascript-функцию для какой-либо дополнительной обработки при успешной проверке формы или наоборот, неуспехе. Для подключения необходимо в настройку передать имя функции-обработчика.

public function options()
{
    return [
        //....
	'on_error' => 'function_name',
	'on_ok' => 'function_name',
    ];
}

javascript-функция должна принимать 3 аргумента: ajax-ответ; jquery-объект формы; параметры, с которыми создавалась форма.

  • before_submit -
  • ok_message - сообщение после отправки данных с формы.
  • mail_event - настройка события отправки писем. В качестве значения устанавливается мнемокод события.
  • post_active - переводить ли запись в активный режим (чекбокс «Активность») после записи данных с формы.
  • show_labels - выводить / не выводить lable. По умолчанию выводятся.
  • show_placeholders - выводить / не выводить плейсхолдеры. По умолчанию не выводятся.
  • submit_text - текст кнопки.

Где хранить класс формы

Предполагается два места хранения классов:

  • в корне проекта, в общей папке для форм: /local/forms/MyForm.php
  • в бандле: /local/bundles/MyBundle/lib/Form/MyForm.php. Важно указывать название папки для форм как Form, иначе не найдет файл.

Приоритет при подключении формы на сайте строится по следующему алгоритму:

  • система для создания объекта формы будет искать файл в корне проекта в папке /local/forms/.
  • Если такого файла нет, то поиск продолжится в бандле: /local/bundles/MyBundle/lib/Form/.

Если бандлов больше одного и названия форм совпадают, то приоритет загрузки будет у первого объявленного бандла.

Организация полей для обязательного заполнения

  • Метод required() - возвращает массив полей, обязательных для заполнения.
public function required()
    {
        return array(
            'name' => 'Ведите ваше имя!',
            'email' => 'Введите ваш E-mail!',
        );
    }

Подключение стилей и скриптов при описании класса формы

В классе формы можно подключать свои стили или js-скрипты.

  • styles() - настройка стилей полей, свойств (property). Ключ массива - имя поля, свойства. Т.е. настроки описываются непосредственно в массиве.
public function styles()
    {
        return array('name' => 'width:100%;', 'email' => 'width:100%;', 'text' => 'width:100%;');
    }
  • useStyles() - подключение файлов стилей.
public function useStyles()
    {
        parent::useStyles();
        $this->bundle->useStyle('form-cat.css');
    }
  • useScripts() - подключение своих скриптов.
public function useScripts()
    {
        parent::useScripts(); // подключаем дефолтные скрипты
        $this->bundle->useScript('newform.js');
    }

Вывод формы на странице

Для установки формы на странице достаточно воспользоваться следующим методом.

print  \TAO::form('NameForm')->render();

Опции можно добавлять непосредственно перед выводом формы. Для этого можно воспользоваться методом setOption().

Например, подключить другой шаблон формы.

print  \TAO::form('NameForm')
    ->setOption('layout','Name')
    ->render();

Переопределение и хранение шаблонов

Для вывода формы используются следующие шаблоны:

  • form.phtml - вывод самой формы с полями.
  • layout-block.phtml - шаблон отображения, сверстанный на основе блоков div.
  • layout-table.phtml - шаблон отображения, сверстанный на основе таблицы.

При формировании имени лэйаута в заголовке файла должно быть указано ключевое слово layout-name.phtml.

Где хранить переопределенные или собственные шаблоны? Есть два варианта:

  • в шаблонах бандла - /local/bundles/NameBundle/views/forms/. Если классы форм хранятся в бандле.
  • в корневой папке шаблонов - /local/views/forms/. Если классы форм хранятся в корневом каталоге (/local/forms/).

Для переопределения копируем нужный шаблон в соответствующую папку.

Получение опций в шаблоне

Опции доступны в шаблоне через метод option().

<?= $this->option('option-name')?>

Отключение полей

Как правило, не все поля требуется выводить на форме, какие-то должны быть доступны только в админке, или одна и та же форма должна иметь каждый раз свой набор полей при ее использовании.

Способ 1: через свойства (properties)

Отключаем поля (свойства) в классе описания формы в методе properties().

// local/forms/Questions.php

class Questions extends \TAO\Form
{
    ...
    public function properties()
        {
	    $props = parent::properties(); 
	    unset($props['answer']); //отключаем ненужные свойства на форме
	    return $props;
	}
}

Способ 2: через опции (options)

Для каждого отключаемого поля отмечаем опцию в методе options().

// local/forms/Questions.php

class Questions extends \TAO\Form
{
    public function options()
	{
	     return array(
	         'disable_field_myproperty' => true,
	     );
	}    
}

Где,

  • disable_field_myproperty - имя отключаемого свойства.
  • disable_field_ - ключевое слово,
  • myproperty - имя свойства.

Способ 3: через метод disableFields()

У класса Form есть замечательный метод отключения полей (свойств) - disableFields(), который можно применить при вызове формы. И перечислить в нем поле или поля (свойства), которые необходимо отключить.

print  \TAO::form('Questions')->disableFields('myproperty')->render();
print  \TAO::form('Questions')->disableFields('myproperty1','myproperty2')->render();

Данный метод устанавливает опцию disable_field_myproperty в true, подставив в имя переданный аргумент.

Способ 4: включение отключенных в опциях полей

Для случаев, когда у одной формы требуется вывести поля (свойства), которые ранее были отключены в опциях (disable_field_myproperty => true), можно воспользоваться методом enableFields().

print  \TAO::form('Questions')->enableFields('myproperty')->render();

Метод включает к выводу ранее отключенные поля (свойства) в опциях.

Хитрая валидация

В случаях, когда требуется реализация какой-то особой валидации полей, отличающейся от стандартной, прийдется писать реализацию самостоятельно. Для этих целей в библиотеке класса форм (Form) есть метод validate($values). Который на входе принимает значения полей, а на выходе получает массив ошибок валидации.

Метод необходимо переопределить в классе описания собственной формы. Незабываем вернуть родительский массив ошибок. Если их нет, то массив будет пустой.

// class MyForm extends \TAO\Form

public function validate($values)
    {
        $errors = parent::validate($values); // вернем родительский массив ошибок
	    if (!preg_match('{^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$}', $values['phone'])) {
	        $errors['phone_num'] = 'Некорректный номер телефона!';
	}
	    return $errors;
    }

Формирование заголовков сообщений с формы в админке (метод postTitle)

По умолчанию заголовки сообщений с формы в админке формируются автоматически с помощью метода postTitle(). Который при формирует сторку на основе значения полей name и email - name / email. Если поля не заполнены, то выводититя дата и время добавления.

Заголовок сообщения можно изменять под свои нужды. Для этого достаточно переопределить данный метод в классе формы.

// local/forms/Questions.php

class Questions extends \TAO\Form
{
    ...
    public function postTitle()
        {
	    return date('d.m.Y - H:i') . $this->values['name'] . $this->values['text'];
	}
} 
⚠️ **GitHub.com Fallback** ⚠️