MODX - Форма обратной связи (FormIt)

Урок, на котором рассмотрим создание формы обратной связи в CMF MODX Revolution, используя компоненты AjaxForm и FormIt.

Назначение компонентов FormIt и AjaxForm

FormIt – это компонент (сниппет) для MODX Revolution, предназначенный для обработки формы на стороне сервера. Он может осуществлять проверку полей формы (валидацию) перед дальнейшими действиями, защищать сайт от получения спама, отправлять данные формы на почту, хранить копии заполненных форм, осуществлять редирект на другую страницу (например, после успешной отправки формы на email), выполнять функцию автоответчика и многое другое.

Но для того чтобы работать с FormIt через AJAX необходимо использовать дополнительный компонент AjaxForm.

Принцип работы формы обратной связи

Перед тем как перейти к разработке формы обратной связи в MODX Revolution, рассмотрим основной алгоритм её работы.

MODX - Схема работы формы обратной связи
MODX - Схема работы формы обратной связи

После открытия некоторой страницы с формой (она берётся из чанка, указанного в параметре &form вызова сниппета AjaxForm при формировании страницы на сервере), пользователь переходит к её заполнению. Завершив заполнение, пользователь нажимает на кнопку "Отправить" и компонент AjaxForm (код JavaScript) отправляет её на сервер посредством AJAX. На сервере данный компонент запускает сниппет FormIt и передаёт ему данные формы. Обработав эти данные, сниппет FormIt формирует ответ, который через компонент AjaxForm передаётся клиенту и отображается на странице пользователю. Ответ может быть положительным (это значит, что форма прошла валидацию и, например, данные были успешно отправлены на почту) или отрицательным (например, при заполнении формы пользователь допустил некоторые ошибки).

Создание формы обратной связи

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

  1. Установить компоненты FormIt (из репозитория modx.com) и AjaxForm (из репозитория modstore.pro).
  2. Создать HTML форму в чанке (пример формы можно взять из чанка tpl.AjaxForm.example).
  3. Создать ресурс, в котором будет выводиться форма и шаблон. Подключить данный шаблон к ресурсу.
    MODX - Шаблон для ресурса Форма обратной связи
    MODX - Шаблон для ресурса Форма обратной связи

    MODX - Ресурс Форма обратной связи
    MODX - Ресурс Форма обратной связи
  4. Добавить в созданный шаблон вызов сниппета AjaxForm и параметры, необходимые для его работы.

Рассмотрим шаги 2 и 4 более подробно.

Создание HTML формы в чанке

Создание HTML формы обратной связи можно осуществить посредством копирования заготовки tpl.AjaxForm.example. Например, присвоим скопированному чанку имя tpl.AjaxForm. Этот чанк, уже содержит готовую HTML-форму, состоящую из 3 полей: Имя, E-mail и Сообщение. Основные действия, которые надо производить с формой в основном будут сводиться к добавлению новых категорий или к удалению существующих. Под категорией будем понимать группу связанных между собой элементов: метка (label), элемент формы (input, select, textarea) и элемент span (используется для отображения ошибки валидации).

MODX - Чанк, содержащий HTML код формы обратной связи
MODX - Чанк, содержащий HTML код формы обратной связи

Основные моменты:

  • Текст метки (элемента label). Обычно берётся либо из словаря (для многоязычных сайтов) или указывается непосредственно с помощью текста.
  • Элемент span, должен иметь атрибут class со значением error_name, в котором фразу name необходимо изменить на значение атрибута name элемента формы, вслед за которым он расположен.
Внимание: использование плейсхолдера [[+fi.name]] в качестве значения атрибута value элемента формы и плейсхолдера [[+fi.error.name]] в качестве контента элемента span актуально только для классической работы с FormIt, т.е. без AJAX. Они используются для заполнения формы при её повторной отправке для того чтобы сохранить значения введённые пользователем и отобразить ошибки валидации.

Например, добавим в HTML форму поле для ввода телефонного номера:

<div class="control-group">
  <label class="control-label" for="af_phone">Телефон:</label>
  <div class="controls">
    <input type="text" id="af_phone" name="phone" value="" placeholder="">
    <span class="error_phone"></span>
  </div>
</div>  

В итоге данный чанк будет содержать следующий HTML-код:

<form action="" method="post" class="ajax_form af_example form-horizontal">
  <div class="control-group">
    <label class="control-label" for="af_name">Имя*</label>
    <div class="controls">
      <input type="text" id="af_name" name="name" value="" placeholder="Введите имя">
      <span class="error_name"></span>
    </div>
  </div>
  <div class="control-group">
    <label class="control-label" for="af_email">E-mail*</label>
    <div class="controls">
      <input type="email" id="af_email" name="email" value="" placeholder="Введите email">
      <span class="error_email"></span>
    </div>
  </div>
  <div class="control-group">
    <label class="control-label" for="af_phone">Телефон</label>
    <div class="controls">
       <input type="text" id="af_phone" name="phone" value="" placeholder="Введите номер телефона">
      <span class="error_phone"></span>
    </div>
  </div>
  <div class="control-group">
    <label class="control-label" for="af_message">Сообщение*</label>
    <div class="controls">
      <textarea id="af_message" name="message" rows="5"></textarea>
      <span class="error_message"></span>
    </div>
  </div>
  <div class="control-group">
    <div class="controls">
      <button type="reset" class="btn btn-default">Очистить</button>
      <button type="submit" class="btn btn-primary">Отправить</button>
    </div>
  </div>
</form>

Создание кода, содержащего вызов сниппета AjaxForm

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

[[!AjaxForm? 
  &form=`tpl.AjaxForm` 
  &snippet=`FormIt` 
  &hooks=`FormItSaveForm,email`
  &emailSubject=`Тестовое сообщение`
  &emailTo=`myemail@mail.ru`
  &emailFrom=`no-reply@mysite.com`
  &emailTpl=`tpl.email`
  &validate=`name:minLength=^2^,email:email:required,message:minLength=^10^`
  &validationErrorMessage=`В форме содержатся ошибки!`
  &successMessage=`Сообщение успешно отправлено`
]]

Разберём основные параметры:

  • &form – отвечает за чанк, содержащий форму (tpl.AjaxForm).
  • &snippet - сниппет, обрабатывающий форму (FormIt).
  • &hooks – хуки, которые будет выполнять сниппет FormIt после успешной проверки формы (1 - FormItSaveForm, 2 - email). Хуки - это скрипты, которые запускаются после того когда форма прошла валидацию (проверку). Они указываются через запятую и запускаются последовательно один за другим. Если в одном из них произошла ошибка, то остальные не запускаются. В этом уроке будем использовать 2 хука. Хук FormItSaveForm предназначен для сохранения формы в базе данных. Хук email предназначен для отправки данных формы на почту.
  • &emailSubject, &emailTo, &emailFrom, &emailTpl – параметры, значения которых использует хук email. Они предназначены для указания темы письма (&emailSubject), адреса отправки (&emailTo), заголовка From (&emailFrom), шаблона письма (&emailTpl).
  • &validate – параметр, на основании значения которого осуществляется валидация формы. Значения параметра представляет собой список элементов, разделённых между собой запятыми. Каждый элемент состоит из имени элемента формы (который нужно проверить) и правила (требования к нему), разделённые между собой с помощью знака двоеточия. Например, валидатор name:minLength=^2^ проверяет, чтобы поле name содержало не меньше 2 символов. Валидатор email:email:required проверяет, чтобы поле mail содержало адрес электронной почты. С основными правилами создания валидаторов можно познакомиться на странице "FormIt Validators".
  • &validationErrorMessage - содержит сообщение, которое будет выводиться, если в форме содержатся ошибки.
  • &successMessage - сообщение, которое увидит пользователь, если сообщение будет успешно отправлено.

Осталось только создать чанк tpl.email, который будет содержать шаблон письма.

<h3>Сообщение</h3>
<p>От кого: [[+name]]</p>
<p>E-mail: [[+email]]</p>
<p>Телефон: [[+phone]]</p>
<p>Сообщение: [[+message]]</p>
MODX - Чанк tpl.email
MODX - Чанк tpl.email
Внимание: Для вывода значений полей формы, используется плейсхолдеры.

Демонстрация работы формы обратной связи

Основные моменты при работе с формой обратной связи на странице продемонстрируем с помощью следующих изображений.

MODX - Незаполненная форма обратной связи
MODX - Незаполненная форма обратной связи

MODX - Форма обратной связи, не прошедшая валидацию
Форма обратной связи, не прошедшая валидацию

Сообщение, об успешной отправке формы
Сообщение, об успешной отправке формы

Просмотр заполненной формы в панели управления MODX
Просмотр заполненной формы в панели управления MODX

Письмо, пришедшее на почтовый ящик
Письмо, пришедшее на почтовый ящик


   MODX Revo 0    8440 +1

Комментарии (81)

  1. Паевл # 0
    Добрый вечер Шеф!!! Давно пользуюсь вашим сайтом, очень многое здесь узнал, и много нашел ответов на свои вопросы!!! Хотел задать вопрос по этой теме:

    Как можно сделать чтобы окно об успешной отправки сообщения появлялась по середине страницы. И как можно сделать так чтобы в окне об успешной отправки были включены данные введенные в форму, то есть в input. пример (). Может нужно какой та плейсхолдер, и как его правильно применить.

    Заранее спасибо!
    1. Александр Мальцев # 0
      Здравствуйте!
      Для этого Вам необходимо открыть файл default.js, находящийся в каталоге /assets/components/ajaxform/js/ и произвести в нём следующие изменения:
      1. Добавить строчку ($.jGrowl.defaults.position = 'center'):
      $(document).ready(function() {
        $.jGrowl.defaults.closerTemplate = '<div>[ '+afConfig.closeMessage+' ]</div>';
        // настраиваем позицию
        $.jGrowl.defaults.position = 'center';
      });
      
      2. Можно чтобы не гонять их обратно с сервера, при нажатию на кнопку «Отправить» сохранить их, а потом если с сервера пришёл ответ success, добавить их к сообщению:
      2.1. Получаем нужные данные:
      $(document).on('submit', afConfig.formSelector, function(e) {
        // получить значение поля name
        name = $('.ajax_form input[name="name"]').val();
        ...
      
      2.2. Добавляем их к сообщению:
      AjaxForm.Message = {
        success: function(message, sticky) {
          if (message) {
            if (!sticky) {sticky = false;}
            // Добавляем данные формы к сообщению (message)
            $.jGrowl(message + "Имя: " + name, {theme: 'af-message-success', sticky: sticky});
          }
        }
        ,error: function(message, sticky) {
        ...
      
      1. Павел # 0
        Спасибо огромное ШЕФ все сработало!!!

        Хотел только еще спросить одну деталь, как сделать чтоб имя (name) в окне (af-message-success) как то выделялось например красным цветом, как ему присвоить стиль CSS в скрипте???
        1. Александр Мальцев # 0
          Ну также как и обычно.
          1. С помощью атрибута style (не рекомендуется).
          // Добавляем данные формы к сообщению (message)
          message += '<span style="color:red">Имя: ' + name + '</span>';
          $.jGrowl(message + "Имя: " + name, {theme: 'af-message-success', sticky: sticky});
          
          2. С помощью класса (рекомендуется).
          // Добавляем данные формы к сообщению (message)
          message += '<span class="red">Имя: ' + name + '</span>';
          $.jGrowl(message + "Имя: " + name, {theme: 'af-message-success', sticky: sticky});
          
          После этого необходимо добавить в CSS:
          .red {
            color: red;
          }
          
          1. Павел # 0
            Еше раз большое спасибо ШЕФ!!! За ваш сайт и вашу помощь!!!
    2. Александр # +1
      Спасибо за консультации!
      124print.ru/about.html
      1. Александр Мальцев # 0
        Спасибо, Александр.
      2. Алексей # 0
        Подскажи, где может быть ошибка. Код полностью скопировал с твоей статьи. Компонент выдаёт сообщение «Форма содержит ошибки».
        В журнале ошибок такая запись:
        [2016-01-17 11:35:40] (ERROR @ /assets/components/ajaxform/action.php) [FormIt] Произошла ошибка при попытке отправить почту. Пустое тело сообщения
        Не пойму куда копать.

        До этого сам настраивал через Ajax, ошибок нигде нет, но письма не приходят.
        Пробовал отдельно через FormIt делать. Письма отправляются, но приходят в таком виде:
        [[+name]] прислал сообщение:
        [[+message]]
        Ответить [[+name]] на почту [[+email]].
        1. Александр Мальцев # 0
          1. Проверьте параметр &emailTpl — он должен содержать чанк, содержащий тело сообщение.
          [[!AjaxForm? 
            &emailTpl=`tpl.email`
          
          2. Проверьте, чтобы у формы был метод отправки (POST) и она имела класс ajax_form:
          <form action="" method="post" class="ajax_form af_example form-horizontal">\
          
          1. Алексей # 0
            Заработало после того как сделал так
            form action="/[[~[[*id]]]]"
            Теперь вот не могу понять, почему с моей формой отправки, которая взята из шаблона не приходят письма и ошибок нет…
            1. Александр Мальцев # 0
              Не знаю чем Вам помочь, но при отправке формы через AJAX значение атрибута action не должно играть ни какой роли. Т.к. настройка, куда отправить форму уже определяется в коде JavaScript в качестве параметра метода jQuery post().
        2. Anna # 0
          Здравствуйте! подскажите пожалуйста, у меня все работает, и сообщения приходят, только не появляются всплывающие аjax-сообщения типа «сообщение отправлено», пересматривала все вроде правильно не могу разобратся
          1. Александр Мальцев # 0
            Здравствуйте.
            Для начала проверьте, есть ли в консоли ошибки.
          2. Anna # 0
            Пишет вот такую ошибку, кажется что то с джеквери ???
            Uncaught TypeError: jQuery.curCSS is not a functionz.getValues @ VM71:1jQuery.extend.fxe @ VM71:1(anonymous function) @ VM71:1jQuery.extend.dequeue @ jquery-2.1.4.js:3931(anonymous function) @ jquery-2.1.4.js:3973jQuery.extend.each @ jquery-2.1.4.js:376jQuery.fn.jQuery.each @ jquery-2.1.4.js:141jQuery.fn.extend.queue @ jquery-2.1.4.js:3966jQuery.fn.extend.animate @ VM71:1(anonymous function) @ jquery.jgrowl.min.js:1jQuery.event.dispatch @ jquery-2.1.4.js:4437elemData.handle @ jquery-2.1.4.js:4123jQuery.event.trigger @ jquery-2.1.4.js:4352(anonymous function) @ jquery-2.1.4.js:4903jQuery.extend.each @ jquery-2.1.4.js:376jQuery.fn.jQuery.each @ jquery-2.1.4.js:141jQuery.fn.extend.trigger @ jquery-2.1.4.js:4902(anonymous function) @ jquery.jgrowl.min.js:1jQuery.event.dispatch @ jquery-2.1.4.js:4437elemData.handle @ jquery-2.1.4.js:4123jQuery.event.trigger @ jquery-2.1.4.js:4352(anonymous function) @ jquery-2.1.4.js:4903jQuery.extend.each @ jquery-2.1.4.js:376jQuery.fn.jQuery.each @ jquery-2.1.4.js:141jQuery.fn.extend.trigger @ jquery-2.1.4.js:4902e.extend.render @ jquery.jgrowl.min.js:1e.extend.update @ jquery.jgrowl.min.js:1(anonymous function) @ jquery.jgrowl.min.js:1
            1. Александр Мальцев # 0
              Попробуй подключить библиотеку jQuery в разделе head, до вызова других js-скриптов.
              1. Анна # 0
                jquery в head стоит выше других скриптов, если убрать или поставить выше файл interface.js в котором находится функция evаl (я в ней ничего не понимаю), форма работает отлично, но тогда не работают другие элементы сайта, без которых теряется вся идея сайта, как их совместить?
            2. Юрий # 0
              Александр, не подскажете, как сделать форму с возможностью прикрепления и отправки файла? Например, для службы поддержки, чтобы пользователь мог отправить скриншоты или вордовский или екселевский файл?
              1. Александр Мальцев # 0
                Попробуй добавить к форме атрибут:
                enctype="multipart/form-data"
                
              2. петрович # 0
                На скрине в письме есть IP пользователя, чем такое реализовать?
                1. Александр Мальцев # 0
                  1. Добавить в вызов сниппета AjaxForm новый хук (например, customHook):
                  &hooks=`customHook,FormItSaveForm,email`
                  
                  2. Добавить скрытое поле в форму (tpl.AjaxForm):
                  <input type="hidden" name="remote_addr" id="remote_addr" value="[[+fi.remote_addr]]">
                  
                  3. Создать сниппет customHook:
                  <?php
                  $hook->setValue('remote_addr', $_SERVER['REMOTE_ADDR']);
                  return true;
                  
                  4. В чанке tpl.email добавить строчку:
                  <p>IP адрес: [[+remote_addr]]</p>
                  
                2. Роман # 0
                  Подскажите пожалуйста, как сделать так, чтобы все работало если при условии я убираю поле для ввода сообщения, оставляю только первые три.
                  1. Александр Мальцев # 0
                    1. Убрать в форме соответствующий блок
                    2. В вызове сниппета в параметре validate убрать проверку поля message:
                    &validate=`name:minLength=^2^,email:email:required`
                    
                  2. Миха # 0
                    Добрый день, подскажите пож-та как сделать переадресацию на страницу «Спасибо ...» вместо появления сообщения «форма отправлена успешно». Очень надо для настройки целей в Гугл Аналитике, т.к. я не понимаю как подвязать такой тип события в Гугл Аналитике как цель конверсии… :(

                    Спасибо!
                    1. Александр Мальцев # 0
                      Найдите на сервере файл assets/components/ajaxform/js/default.js.
                      Добавьте строчку
                      window.location = "http://mysite.ru/";
                      
                      перед строчкой
                      AjaxForm.Message.success(response.message);
                      
                    2. Сергей # 0
                      А как прикрутить reCaptche от google?
                      1. Александр Мальцев # 0
                        Как это сделать расскажу в отдельной статье.
                        1. Сергей # 0
                          Спасибо Вам, будем ждать!
                      2. Сергей # 0
                        И не подскажите как сделать как у вас систему комментирования… оч понарвилась)
                        1. Александр Мальцев # 0
                          С помощью сниппета TicketComments.
                          Как это сделать рассмотрено в этой статье:
                          MODX — Создание шаблона для постов.
                        2. Anton # 0
                          Здравствуйте, давно читаю ваш сайт, очень много полезной информации, спасибо за ваш труд) Такой вопрос подскажите как реализовать связанные списки при изпользовании Formit, например в первом списке выбираем город, а во втором списке выводится список районов этого города?! Использую просто вызов формит на странице без ajax. Спасибо.
                          1. Александр Мальцев # 0
                            Здравствуйте.
                            Без ajax это можно сделать через отдельный файл js, который использовать для хранения необходимых данных в виде массива json. После этого на JavaScript необходимо написать скрипт, который будет при выборе города выбирать из этого массива необходимые данные и отображать их во втором списке.
                            Что-то наподобие этого: itchief.ru/lessons/bootstrap-3/bootstrap-3-modal-window#comment-827
                          2. Алексей # 0
                            Добрый день.
                            Делаю всё по вашему уроку, но у меня при правильном заполнении формы, при нажатии отправить поля и кнопки становятся не активными, и форма виснет, вверху справа никаких сообщений не выходит, только рядом с полями если не заполнено. В head страницы AjaxForm не прописывает assets/components/ajaxform/js/default.js прописывает только файл стилей, так и должно быть? пробывал в ручную указать default.js — не помогло. В чём может быть дело?
                            1. Александр # 0
                              Проверяйте что делали, потому что я 5 минут назад по этой инструкции сделал форму и всё работает.
                            2. Владимир # 0
                              Добрый день. Сделал форму отправки через AjaxForm все, как сказано. Выдает сообщение «форма содержит ошибку» и в поле email адрес подсвечивается красным. Указывал емейл рабочий свой. в форме emailTo указал емейл созданный на хостинге. В чем может быть проблема?
                              1. Александр Мальцев # 0
                                В emailTo необходимо указывать адрес куда Вы хотите отправить. Для начало проверьте, вообще работает ли отправка почты с сайта на Вашем хостинге.
                                1. Владислав # 0
                                  здравствуйте, уважаемый Александр!
                                  Подскажите пожалуйста, что необходимо изменить в вызове формы, чтобы письмо переадресовывалось на несколько адресов? Спасибо.
                                  1. Александр Мальцев # 0
                                    Это делается через запятую:
                                    &emailTo=`mail1@email.com,mail2@email.com,mail3@email.com`
                                    
                                    Если Вам необходим переслать копию письма, то через emailCC:
                                    &emailCC=`email4@domain.com,email5@domain.com`
                                    
                                    А также если необходимо отправить копии скрытым адресатам, адреса которых не показываются другим участникам отправки:
                                    &emailBCC=`email6@domain.com,email7@domain.com`
                                    
                              2. Владимир # 0
                                Версия MODX Revolution 2.5.0-pl
                                Пробовал несколько раз с разными формами отправки.
                                Делал на Openserver ошибки нет, но и писем тоже ))
                                1. Александр Мальцев # 0
                                  Надо проверять на сервере. На openserver может использоваться заглушка (например, на Denwer все отправленные письма сохраняются в виде файлов с расширением eml в каталог tmp/!sendmail/..).
                                  Сначала лучше проверить работает ли вообще отправка почты. Для этого можно воспользоваться сниппетом QuickEmail.
                                  1. Владимир # 0
                                    Установил на сервере сниппет QuickEmail. Вызываю кодом:
                                    [[!QuickEmail?
                                    	&debug=`1`
                                    	&to=`твойEmail`
                                    ]]
                                    На страничке пишет:
                                    Send Failed
                                    Mailer error info: Невозможно запустить функцию mail.
                                    Я новичок в modx. Так думаю настройки почты не сделаны. Где их делать?
                                    1. Александр Мальцев # 0
                                      Тут дело не в настройках. У Вас на сервере нет php-функции mail с помощью которой можно было бы отправлять почту.
                                      1. Владимир # 0
                                        Это надо в техподдержку хостинга обращаться?
                                        1. Александр Мальцев # 0
                                          Да.
                                2. Владимир # 0
                                  а в сниппетах formIt и AjaxForm ее нет? Тогда как ее подключить?
                                  1. Александр Мальцев # 0
                                    Её подключать не надо. Вы ж не настраиваете серевер, а покупаете хостинг. Посмотрите поддерживает ли хостинг библиотеку phpMailer и функцию mail.
                                    1. Владимир # 0
                                      Спасибо! Причина нашлась. В техподдержке ответили, что с одного из сайтов аккаунта была обнаружена рассылка спама, поэтому отключили функцию. Надо проверить на вирусы и вредоносный код.
                                  2. Алексей # 0
                                    Добрый день! Форму подключил, все работает. Только, возникла проблема со спамом. Подскажите как защитить форму от спам роботов. Капчу ставить не вариант. И еще вопрос по теме — спам также лезет в виде СМС, (номер телефона реализован через ссылку «tel»). Как защититься? Спасибо!
                                    1. Александр Мальцев # 0
                                      Здраствуйте. Добавить любое невидимое поле. Например:
                                      <input type="hidden" name="workemail" value="">
                                      
                                      В FormIt добавить проверку, т.е. проверить что оно является пустое:
                                      [[!FormIt? &validate=`workemail:blank`]]
                                      
                                      Спам робот будет его заполнять, а в FormIt валидация такого поля не пройдёт.
                                      Но некоторые спам роботы такое поле могут видетm. В этом случае его можно сделать обычным полем, а скрыть с помощью CSS:
                                      <input type="text" id="workemail" name="workemail" value="">
                                      
                                      #workemail {
                                        display:none;
                                      }
                                      
                                      Можно ещё использовать хук spam:
                                      [[!FormIt? &hooks=`spam` &spamCheckIp=`true`]]
                                      
                                      Не совсем понял про номер телефона, но можно его указывать не в HTML. А сделать так, чтобы он показывался посредством JavaScript.
                                      1. Алексей # 0
                                        Спасибо. Дополнения внес буду надеяться, что защитит.
                                        А телефон сделан так:
                                        <a href="tel:+788888888"> ПОЗВОНИТЬ </a>
                                        на мобильных устройствах при нажатии набирается номер. Вот, я думаю через эту ссылку и приходят СМС. Как закрыть ссылку от роботов не знаю. Подскажите решение.
                                        1. Александр Мальцев # 0
                                          Попробуйте убрать номер телефона из HTML. Т.е. сделать как-то так:
                                          <a id="tel" href="#"> ПОЗВОНИТЬ </a>
                                          
                                          А при нажатии на ссылку, перехватывать это событие с помощью JavaScript (jQuery) и подставлять в неё необходимый номер телефона. Дополнительно номер телефона можно закодировать с помощью btoa:
                                          $('#tel').click(function(){
                                            $(this).attr('href',window.atob('dGVsOis3ODg4ODg4ODg='));
                                          });
                                          
                                          1. Алексей # 0
                                            Большое спасибо за ответ. Буду пробовать
                                    2. Алексей # 0
                                      Здравствуйте Александр.
                                      Вопрос не совсем по теме, но очень для меня актуальный.
                                      Подскажите, как вывести на сайте чекбокс, при активации которого должно передаваться значение в дополнительное TV (я уже создал TV с значениями: значение==up и значением по умолчаниюзначение==down) и менять его значение которое затем должно передаваться в шаблоны и чанки изменяя значения в TV. И соответственно, измененные значения TV должны повлечь изменение в выводимых на фронтэнд данных. И нужно, чтоб отправка данных в TV происходила сразу после активации чакбокса или селекта, без кнопки «отправить форму».
                                      Спасибо.
                                      1. Виталий # 0
                                        Здравствуйте, Александр.

                                        Обращаюсь за помощью к Вам, т.к. в нете ничего не нашел или никому это не нужно?

                                        У меня простая форма без Ajax с редиректом.
                                        При наличии ошибок в заполненной форме появляются соответствующие подсказки «Это поле обязательно для заполнения.» и т.п., но при этом страница прокручивается к самому верху, а если страница длинная и форма в самом низу, то посетитель может просто подумать, что все отправилось и пойти дальше.
                                        Как сделать, чтобы форма при наличии ошибок оставалась на месте?

                                        И параллельно второй вопрос. Форма находится в модальном окне Bootstrap 3. При наличии ошибок в форме модальное окно закрывается и узнать о наличии ошибок можно только повторно нажав на кнопку вызова модального окна.
                                        Соответственно вопрос — как сделать, чтобы при наличии ошибок в форме окно не закрывалось до из исправления.

                                        Спасибо!
                                        1. Александр Мальцев # 0
                                          Это делается очень просто. Только Вы не можете оставить её на месте, необходимо прокрутить до неё. Для этого необходимо нужному элементу создать идентификатор (id) и указать его в параметре action через #:
                                          <form id="formit" action="[[~[[*id]]]]#formit" method="post" class="form">
                                          ...
                                          
                                          Для решения второго вопроса лучше использовать AJAX. Без него только перезагрузка. Единственное что можно сделать — это прокрутить до нужного места на странице и открыть модальное окно с помощью JavaScript. Но данное решение будет выглядеть для посетителя как-то странно, поэтому его лучше не использовать.
                                          1. Виталий # 0
                                            Александр, огромное спасибо за оперативный ответ. Со статичной формой все получилось, сейчас модальной займусь.
                                            Отдельное огромное спасибо за сайт вообще. Сейчас активно осваиваю Bootstrap3 и где-то 70-80% информации беру именно с Вашего сайта.
                                        2. Игорь Денисов # 0
                                          Здравствуйте Александр!
                                          Наверное, Вы лишний раз здесь вставили email:
                                          [[!AjaxForm?
                                              &validate=`name:minLength=^2^,email:email:required,message:minLength=^10^`
                                          ]]
                                          
                                          Или я что-то путаю?)
                                          1. Александр Мальцев # 0
                                            Здравствуйте, Игорь.
                                            Первый email — это имя поля. Второй — это валидатор, который проверяет имеет ли это поле валидный email адрес. Третии параметр (required) — указывает, что это поле является обязательным, т.е. не может содержать пустое значение.
                                            1. Игорь Денисов # 0
                                              Извиняюсь… думал опечатка ))
                                              Спасибо Вам, сейчас у себя тоже поправлю!
                                          2. Игорь Денисов # 0
                                            Здравствуйте Александр!
                                            Что-то я прям все никак не могу подружиться с формой обратной связи!)
                                            Теперь у меня почему-то перестала работать форма
                                            В логе пишет вот что:
                                            (ERROR @ .../core/components/formit/model/formit/fihooks.class.php : 552) [FormIt] Произошла ошибка при попытке отправить почту. Невозможно запустить функцию mail.
                                            На поддержке у хостинга создал тикет, объяснил им что так-то так-то, ошибку из лога и все такое им написал. Они мне отправили библиотеку PHPMailer и установки которые нужно прописать в feedback.php который лежит по адресу вместе со всеми остальными его файлами /core/model/modx/mail/phpmailer/
                                            Вроде бы сделал все как сказали, но увы не помогло, может я что не так делаю…
                                            Может быть Вы мне сможете помочь, уже второй день бьюсь над этой проблемой!
                                            Заранее спасибо!
                                            1. Александр Мальцев # 0
                                              Это ошибка означает, что у Вас на хостинге не поддерживается функция mail. Библиотека PHPMailer работает на основе функции mail.
                                            2. Игорь # 0
                                              Здравствуйте.
                                              Может Вы сможете мне помочь? голову сломал уже.
                                              Поставил обратную связь с помощью ajaxForm письма отправляются, но при этом перезагружается страница и не появляются оповещения об успешном отправлении. Неудобно тем что форма внизу сайта, а после перезагрузки возвращается вверх.
                                              в консоли ошибка default.js:11 Uncaught TypeError: $ is not a function
                                              1. Евгений # 0
                                                Эта ошибка означает, что вы вызываете jquery до того, как его подключили. Проверьте очерёдность подключения скриптов. Что бы страница не обновлялась нужно сделать следущее: повесим на форму id=«send_form», предотвратить обновление можно например так
                                                $(function(){
                                                
                                                $('#send_form').on('submit', function(e){
                                                	e.preventDefault();
                                                	тут ваш код - обработчик
                                                });	
                                                
                                                });
                                                
                                              2. Growing # 0
                                                Доброго времени суток, Александр!
                                                Спасибо за урок, очень доступно.
                                                Подскажите пожалуйста, если форма построена на связке ajax+formIt, как можно передать значение селектбокса из одной формы в другую? Т.е. необходимо сделать так, чтобы выбранный в одной форме после отправки первой формы стал активным во второй?
                                                В сообществе обсуждения подобных решений не нашёл…
                                                1. Александр Мальцев # 0
                                                  При отправке формы сохраняйте значение в переменную и если ответ пришёл успешный, то проводите операции во второй форме (делайте элемент активным и устанавливайте ему значение из переменной):
                                                  // переменная, которая будет использоваться для хранения значения селектбокса
                                                  var valueFromForm1;
                                                  // при отправке формы
                                                  $(document).on('submit', '.ajax_form1', function() {
                                                    // сохраняем значение селектбокса
                                                    valueFromForm1 = $('#myselect').val();
                                                  });
                                                  // при получении ответа от сервера
                                                  $(document).on('af_complete', function(event, response) {
                                                    if (response.success==true && valueFromForm1) {
                                                      //... здесь прописывайте ваши действия для второй формы
                                                    }
                                                  });
                                                  </script>
                                                  1. Growing # 0
                                                    Принцип дошёл, как всегда всё доступно)
                                                    Спасибо, Шеф.
                                                2. Kirill # 0
                                                  Александр добрый день! Подскажите пожалуйста, бьюсь 3-ий день как сделать, чтобы письмо с формы отправлялось разным получателям. Например у меня есть radio
                                                  Черный белый и красный
                                                  При выборе разного цвета уходит на разные почты
                                                  И также чтобы в почте в пиьме цвета остались
                                                  1. Александр Мальцев # 0
                                                    Необходимо сделать следующее:
                                                    1. В чанке tpl.AjaxForm добавить поле (адрес для отправки) и радиопереключатели (цвета и адреса для отправки в виде data-атрибутов):
                                                    <input type="text" id="af_addressTo" name="addressTo" hidden>
                                                    <div class="radio">
                                                      <label>
                                                        <input type="radio" name="color[]" value="black" data-address-to="black@mail.ru" checked [[!+fi.color:FormItIsChecked=`blue`]]>
                                                        Чёрный
                                                      </label>
                                                    </div>
                                                    <div class="radio">
                                                      <label>
                                                        <input type="radio" name="color[]" value="white" data-address-to="white@mail.ru" [[!+fi.color:FormItIsChecked=`blue`]]>
                                                        Белый
                                                      </label>
                                                    </div>
                                                    <div class="radio">
                                                      <label>
                                                        <input type="radio" name="color[]" value="red" data-address-to="red@mail.ru" [[!+fi.color:FormItIsChecked=`blue`]]>
                                                        Красный
                                                      </label>
                                                    </div>
                                                    
                                                    2. В чанк tpl.AjaxForm добавить ещё скрипт, который будет в поле addressTo подставлять значение из радиокнопок:
                                                    <script>
                                                    jQuery(function(){
                                                      $('#af_addressTo').val($('input[name="color[]"]:checked').attr('data-address-to'));
                                                      $('input[name="color[]"]').change(function(){
                                                        $('#af_addressTo').val($('input[name="color[]"]:checked').attr('data-address-to'));
                                                        console.log($('#af_addressTo').val());
                                                      });
                                                    });
                                                    </script>
                                                    
                                                    3. В качестве значения параметра emailTo установить имя поля, содержащего адрес для отправки:
                                                    [[!AjaxForm? 
                                                      &form=`tpl.AjaxForm` 
                                                      &snippet=`FormIt` 
                                                      &hooks=`FormItSaveForm,email`
                                                      &emailSubject=`Тестовое сообщение`
                                                      &emailTo=`[[+addressTo]]`
                                                      &emailFrom=`no-reply@mysite.com`
                                                      emailFromName=`Мой сайт`
                                                      &emailTpl=`tpl.email`
                                                      &validate=`name:minLength=^2^,email:email:required,message:minLength=^10^`
                                                      &validationErrorMessage=`В форме содержатся ошибки!`
                                                      &successMessage=`Сообщение успешно отправлено`
                                                    ]]
                                                    
                                                    4. В чанк email.tpl (шаблон письма) добавить строчку:
                                                    <p>Цвет: [[+color]]</p>
                                                    
                                                  2. Natalia # 0
                                                    Добрый день,

                                                    у меня сайт на openserver. Сделала форму по Вашим инструкциям и при заполнении и отправке заполненной формы не выходит сообщение что сообщение успешно отправлено/не отправлено и соответственно письма на ящик не приходят. В админке modx отправленные сообщения есть. В openserver настройку на отправку писем с ящика сделала и все равно без толку. Пожалуйста, можете подсказать в каком направлении искать решение проблемы, Спасибо
                                                    1. Александр Мальцев # 0
                                                      Здравствуйте. Насчёт openserver не подскажу, т.к. с ним не знаком. Но подобный локальный веб-сервер, например, denwer (денвер), их не отправляет, а использует заглушку (т.е. складывает их в директорию sendmail в виде файлов). Скорее тоже самое делает и openserver. Если Вы хотите по-настоящему отправлять почту, то необходимо использовать реальный веб-сервер.
                                                      1. Natalia # 0
                                                        Александр, спасибо за ответ, а в денвере при отправке формы появляется окно об успешной отправке? Дело в том, что я настроила в openserver отправку писем через smtp и по идее письма должны отправляться. Вот я и пытаюсь понять, то ли у меня ошибка в форме, то ли не получается настроить сервер на отправку почты
                                                        1. Александр Мальцев # 0
                                                          В Denwer появляются сообщение об успешной отправке, но письма отправляются в файл. Т.е. они складываются в директорию !sendmail, которая находится в каталоге tmp. В Denwer нет Mail Server, поэтому они физически не могут быть отправлены на реальную почту. В openserver тоже наверно нет Mail Server. Чтобы это осуществить необходимо либо установить сервер, либо использовать удалённый сервер. Посмотрите может в настройках openserver есть возможность выбрать использование удалённого SMTP сервера. Если есть, то сделайте необходимые настройки и перезапустите openserver.
                                                          Чтобы не мучить FormIt сначала попробуйте использовать дополнение для MODX Revolution QuickEmail. Он предназначен для проверки отправки сообщений на почту. Как только настроите почту, перейдёте к FormIt.
                                                      2. kalisto # 0
                                                        Письма в openserver смотрите в папке ваш_диск:\OpenServer\userdata\temp\email — они туда складываются в виде *.txt файла
                                                      3. kalisto # 0
                                                        Александр! Каким образом включить задержку всплывающего сообщения или вообще включить возможность закрытия попапа самому поль-лю?
                                                        1. Александр Мальцев # +1
                                                          Для отображение сообщений дополнение ajaxForm использует jQuery плагин jGrowl.
                                                          В этом дополнение настройка сообщения осуществляется в файле default.js, который находится в директории /assets/components/ajaxform/js.
                                                          Для этого необходимо открыть его и внести необходимые изменения:
                                                          //...
                                                          //noinspection JSUnusedGlobalSymbols
                                                          AjaxForm.Message = {
                                                              success: function (message, sticky) {
                                                                  if (message) {
                                                                      if (!sticky) {
                                                                          sticky = false;
                                                                      }
                                                                      $.jGrowl(message, {theme: 'af-message-success', sticky: sticky});
                                                                  }
                                                              },
                                                              error: function (message, sticky) {
                                                                  if (message) {
                                                                      if (!sticky) {
                                                                          sticky = false;
                                                                      }
                                                                      $.jGrowl(message, {theme: 'af-message-error', sticky: sticky});
                                                                  }
                                                              },
                                                              info: function (message, sticky) {
                                                                  if (message) {
                                                                      if (!sticky) {
                                                                          sticky = false;
                                                                      }
                                                                      $.jGrowl(message, {theme: 'af-message-info', sticky: sticky});
                                                                  }
                                                              },
                                                          //...
                                                          
                                                          Устаноить время задержки осуществляется с помощью параметра life.
                                                          Например, для сообщения успеха (success) установим задержку 10сек (10000):
                                                          //...
                                                              success: function (message, sticky) {
                                                                  if (message) {
                                                                      if (!sticky) {
                                                                          sticky = false;
                                                                      }
                                                                      $.jGrowl(message, {theme: 'af-message-success', sticky: sticky, life: 10000});
                                                                  }
                                                          //...
                                                          
                                                          Для того чтобы пользователь сам мог бы закрывать сообщение, параметру sticky необходимо установить значение true.
                                                          Например, для успешного сообщения:
                                                          //...
                                                              success: function (message, sticky) {
                                                                  if (message) {
                                                                      if (!sticky) {
                                                                          sticky = false;
                                                                      }
                                                                      $.jGrowl(message, {theme: 'af-message-success', sticky: true});
                                                                  }
                                                          //...
                                                          
                                                          1. kalisto # 0
                                                            Спасибо Вам большое!!!
                                                        2. qurusan # 0
                                                          Вопрос посложнее. Как подключить несколько форм на странице через аяксформ, при этом в каждой форме находится reCaptcha от гугл? Существует ли такой способ вообще?
                                                          1. Александр Мальцев # 0
                                                            Да, Google reCaptcha позволяет это сделать. Но, не знаю поддерживают ли какие-то компоненты MODX (например, ReCaptchaV2) это. Надо, проверить…

                                                            Если нет, то это придётся реализовать самостоятельно. Сам принцип как это сделать можно посмотреть здесь: itchief.ru/lessons/php/how-to-install-recaptcha-on-website#comment-2852
                                                          2. Василий # 0
                                                            Доброго дня, Шеф!
                                                            Вопрос не по теме немного.
                                                            Можно ли в modx по получении email запускать какой-то сниппет, своего рода обработчик почты?
                                                            Если можно, то как это реализовать? Я не представляю
                                                            1. Александр Мальцев # 0
                                                              Здравствуйте. Необходимо написать свой хук и указать его в качестве параметра сниппета FormIt hooks.
                                                              1. Василий # 0
                                                                Не встречались готовые решения? Откровенно говоря, программист из меня никакой((
                                                                1. Александр Мальцев # 0
                                                                  Это зависит от того, что вы хотите сделать. Может быть, есть и готовые примеры…
                                                                  Общий принцип такой:
                                                                  1. Создаёте новый сниппет.
                                                                  2. Для получения email используйте в нём следующую строчку:
                                                                  $email = $hook->getValue('email');
                                                                  
                                                                  3. Далее пишите код, клоторый будет выполнять необходимые действия.
                                                                  4. Подключаете сниппет к вызову сниппета FormIt как хук (hook):
                                                                  [[!FormIt?
                                                                    &hooks=`myhook,email`
                                                                    ...
                                                                  

                                                            Вы должны авторизоваться, чтобы оставлять комментарии.