MODx FormIt. Создание форм с произвольной логикой

В этом руководстве для новичков я кратко расскажу о ключевых возможностях компонента FormIt и о механизме работы одноименного сниппета, который я использую на 99% процентах разрабатываемых мной сайтов на MODx Revolution. Надеюсь, что данная статья поможет лучше понять суть работы данного компонента, особенно, если вы только начали свой путь в изучении MODx Revolution.

Автор материала

Артем Зернов. Веб-разработчик, создатель проекта Лектория, эксперт MODX Revolution, директор веб-студии OpenColour. Youtube-канал OpenModx.

222
9 минут на прочтение
Теги по этой теме:

Для чего нужен FormIt?

Если вкратце, то FormIt — это компонент для MODx Revolution, представляющий из себя набор сниппетов и дополнительного интерфейса админки MODx для обработки значений форм и навешивания на них дополнительной логики при успешном/неуспешном заполнении.

Официальная страница документации компонента FormIt

Смотреть

Первая версия компонента вышла более 10 лет назад!

Как использовать

Все довольно просто. В коде вашего шаблона/чанка, где находится ваша форма в виде html-кода, перед этой формой ставите вызов сниппета FormIt.

Например:

[[!FormIt]]

или, если вы используете Fenom-синтаксис:

{'!FormIt' | snippet}

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

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

<h2>Контактная форма</h2>

[[!+fi.validation_error_message:notempty=<p>[[!+fi.validation_error_message]]</p>]]

<form action="[[~[[*id]]]]" method="post" class="form">
    <label for="name">
        Имя:
        <span class="error">[[!+fi.error.name]]</span>
    </label>
    <input type="text" name="name" id="name" value="[[!+fi.name]]" />

    <label for="email">
        Email:
        <span class="error">[[!+fi.error.email]]</span>
    </label>
    <input type="text" name="email" id="email" value="[[!+fi.email]]" />


    <label for="text">
        Сообщение:
        <span class="error">[[!+fi.error.text]]</span>
    </label>
    <textarea name="text" id="text" cols="55" rows="7" value="[[!+fi.text]]">[[!+fi.text]]</textarea>

    <br class="clear" />

    <div class="form-buttons">
        <input type="submit" value="Отправить" />
    </div>
</form>

Механика работы

При отправке данных формы POST запросом на адрес этой же страницы, сниппет FormIt делает обработку значений в соответствии с параметрами вызова сниппета. Если в сниппет был передан параметр submitVar, то при отстутсвии значения в этом поле POST запроса, будет считаться, что отправки формы не было. Это позволяет игнорировать POST-запросы других форм.

В примере ниже сниппет FormIt не будет реагировать на данные при отправке второй формы:

[[!FormIt?
    &submitVar=`myFormSubmit`
]]

<form action="" method="post">
    <input type="text" name="name">
    <button type="submit" name="myFormSubmit" value="1">Отправить</button>
</form>

<form action="" method="post">
    <input type="text" name="name">
    <input type="submit" value="Отправить">
</form>

Сама по себе механика работы FormIt глобально состоит из  3-х основных этапов:

  • Предварительная инициализация значений, запуск скриптов preHooks
  • Обработка POST-значений и запуск скриптов hooks
  • Постобработка значений, запуск скриптов renderHooks и запись плейсхолдеров

Базовые параметры FormIt и пример использования

Несмотря на то, что последние несколько лет я использую сниппет FormIt через компонент AjaxForm, вам в первую очередь необходимо понять механику работы FormIt, так как AjaxForm – это всего лишь обертка, позволяющая запускать FormIt асинхронно, без перезагрузки страницы.

Сам по себе сниппет FormIt имеет не так много родных параметров. Большинство параметров – это параметры, которые необходимы для запуска вызываемых скриптов (хуков). Поэтому, чем больше хуков вы используете, тем больше параметров нужно передать в сниппет FormIt.

Типичный мой вызов FormIt на Fenom выглядит так:

{'!FormIt' | snippet : [
    'hooks'=>'email',
    'submitVar'=>'mySubmitVar',
    'emailTpl'=>'email.questionForm',
    'emailTo'=>$_modx->config.my_admin_email,
    'emailFrom'=>$_modx->config.emailsender,
    'emailSubject'=>'Задан вопрос на сайте '~$_modx->config.site_url,
    'validate'=>'name:required,email:email:required,comment:required',
    'validationErrorMessage'=>'Укажите корректную информацию. Заполните все необходимые поля.',
    'successMessage'=>'Спасибо за ваш вопрос. Мы постараемся ответить на него в ближайшее время.',
    'errTpl'=>'[[+error]]' 
]}
<h2>Контактная форма</h2>

[[!+fi.validation_error_message:notempty=<p>[[!+fi.validation_error_message]]</p>]]

<form action="[[~[[*id]]]]" method="post" class="form">
    <label for="name">
        Имя:
        <span class="error">[[!+fi.error.name]]</span>
    </label>
    <input type="text" name="name" id="name" value="[[!+fi.name:htmlent]]" />

    <label for="email">
        Email:
        <span class="error">[[!+fi.error.email]]</span>
    </label>
    <input type="text" name="email" id="email" value="[[!+fi.email:htmlent]]" />


    <label for="text">
        Сообщение:
        <span class="error">[[!+fi.error.comment]]</span>
    </label>
    <textarea name="comment" id="text" cols="55" rows="7" value="[[!+fi.comment:htmlent]]">[[!+fi.comment:htmlent]]</textarea>

    <br class="clear" />

    <div class="form-buttons">
        <input type="submit" name="mySubmitVar" value="Отправить" />
    </div>
</form>

Этот вызов означает, что прежде, чем выполнить хук email, отправляющий письмо по заданному адресу, FormIt проверит, заполнены ли поля name, email и comment. Также поле email будет проверено на предмет соответствия шаблону email-адресов. Если все проверки будут пройдены, то только в этом случае произойдет отправка и будет выведено сообщение об успешности отправки формы. Или же будет выведена ошибка:

[[!+fi.validation_error_message:notempty=<p>[[!+fi.validation_error_message]]</p>]]

Если бы мы не указывали хук email, то параметры:

    'emailTpl'=>'email.questionForm',
    'emailTo'=>$_modx->config.my_admin_email,
    'emailFrom'=>$_modx->config.emailsender,
    'emailSubject'=>'Задан вопрос на сайте '~$_modx->config.site_url,

Не имели бы смысла.

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

Вместо заключения

Для первого обзора FormIt, выраженного в виде небольшой статьи, получилось довольно сумбурно, но думаю, что суть вы уловили. В следующих статьях я постараюсь подрбонее рассказать о самописных хуках и сценариях их использования.

Курс по теме

Также я записывал отдельный курс по созданию Landing Page на MODx, в рамках которого я также показывал, как реализуется простая форма обратной связи и форма с более сложным набором полей.

Подробнее

Весь набор параметров FormIt

Параметр Значение по-умолчанию
preHooks
Набор скриптов или сниппетов, запускаемых в любом случае. Если сниппет возвращает false, то дальнейший запуск хуков прекращается. Можно использовать для подстановки значений в форму по-умолчанию. При этом значения полей будут устанавливаться только в том случае, если не было отправки формы. Подробнее о хуках см. ниже
 
renderHooks
Набор скриптов или сниппетов (хуков), запускаемых после всех других хуков (hooks и preHooks). Запускаются независимо от того, была ли отправка формы или нет. Могут использоваться для трансформации полей перед отображением в форме (например, чтобы преобразовать html-символы  в соответствующие коды)
 
hooks
Набор скриптов или сниппетов, запускаемых при отправке формы. Используются для обработки значений пришедших из формы и реализации дополнительной логики. Например, для отправки письма на почту, для отправки данных в сервис рассылки или CRM или для авторизации пользователя.
 
submitVar
Поле формы, используемое как индикатор отправки формы.
 
validate
Разделенные запятой правила валидации полей формы. Каждое правило представляет из себя имя поля и затем через двоеточие указываются правила валидации. Например: username:required,email:email:required. Весь список встроенных валидаторов FormIt можно посмотреть здесь.
 
validationErrorMessage
Сообщение об ошибке, которое будет помещено в плейсхолдер [[!+fi.validation_error_message]] в случае, если валидация одного или нескольких полей не пройдет.
A form validation error occurred. Please check the values you have entered.
validationErrorBulkTpl
HTML-чанк используемый для вывода сообщения об ошибке для каждого поля. В чанке может исползоваться плейсхолдер [[+error]]
[[+error]]
errTpl
Html-обертка для вывода ошибки. Это не чанк, это именно html-код. Например <span>[[+error]]</span>
[[+error]]
customValidators
Список ползовательских валидаторов (сниппетов), которые могут использоваться в параметре validate
 
clearFieldsOnSuccess
Если установлено, то при успешной отправке формы, значения плейсхолдеров полей формы будут очищены.
true
store
Если установлено, то значения формы будут сохранены в кэше или в сессии для повторного вызова.
0
storeTime
Если store установлен, то в данном парамере указывается время в секундах для хранения данных в сессии или кэше
300
storeLocation
Может принимать значения cache или session. Место хранения данных формы.
cache
placeholderPrefix
Префикс, используемый для всех плейсхолдеров, устанавливаемых текущим вызовом сниппета FormIt. Обращаем внимание на точку на конце!
fi.
successMessage
Если не используется хук redirect (который делает редирект в случае успешной отправки формы), то здесь указывается сообщение об успешной отправке формы.
 
successMessagePlaceholder
Название плейсхолдера, в котором будет лежать сообщение об успешной отправке формы.
fi.successMessage
redirectTo
ID страницы, на которую будет произведен редирект в случае успешной отправки. Актуально только, если в списке хуков параметра hooks используется хук redirect.
 
allowFiles
Если вы разрешаете отправку файлов через форму, то необходимо установить это поле. По-умолчанию оно уже включено. 
true
attachFilesToEmail
Актуально, если вы используете хук email в параметре hooks  и если вы хотите прицепить отправляемые через форму файлы к письму. При этом не забывайте добавлять к вашей форме атрибут enctype="multipart/form-data"
true

Начальный курс по теме

Артем Зернов
Мы используем куки на нашем сайте. Продолжая просмотр, вы соглашаетесь с условиями пользовательского соглашения
Пожалуйста, подождите. Процесс оформления заказа может занимать до 30 секунд.