[АНОНС] SendIt - "It's revolution, Johnny!"

Приветствую вас, мои читатели. Никто не просил, но я создал новый компонент для работы с формами на сайте. И имя ему — SendIt. Вам, наверное, интересно чего же такого революционного в моём пакет? Если коротко то, при его использовании не нужно вызывать сниппет для отправки формы. Просто добавьте форме 1 атрибут и она будет отправляться на почту. Подробности ниже.

1. Отправка простых форм.

Чтобы отправить форму нужно добавить ей атрибут data-si-form в качестве значения нужно указать имя формы (параметр formName у сниппета FormIt). Имя формы должно быть уникальным в пределах сайта. Оно используется для хранения данных формы в LocalStorage и Cookie.
В будущем планирую создать в админке интерфейс для управления формами, аналог Formalicious, только название попроще придумаю. И тогда по имени формы можно будет найти её в БД.

Несмотря на то, что вызывать сниппет необязательно, в большинстве случаев, вы не захотите использовать стандартные настройки. Чтобы задать свои параметры для формы, нужно создать пресет в файле sendit.inc.php (путь к файлу с пресетами можно будет изменить в системных настройках). Выглядит это так
<?php

return [
    'default' => [
        'validate' => 'phone:required,username[second]:required,user[*][name]:required,user[*][email]:email,politics:checkbox:required,email:email:required'
    ],
    'onestepform' => [
        'extends' => 'default',
        'redirectTo' => 1,
        'redirectTimeout' => 3000,
        'clearFieldsOnSuccess' => 1,
        'fieldNames' => 'phone==Телефон',
        'successMessage' => 'Форма отправлена!',
    ]
];
Обратите внимание на параметр extends — он позволяет наследовать параметры другого пресета, в данном случае с ключом default. Наследование не рекурсивное, т.е. если defaults тоже будет иметь параметр extends например со значением third, параметры пресета third унаследованы не будут.

Какие параметры доступны?
Вы можете использовать все те же параметры, что и при работе с AjaxFormItLogin. Но есть и отличия. В частности, чтобы передать псевдонимы полей, не нужно использовать параметр aliases, вместо этого следует использовать fieldNames.. Параметр transmittedParams вообще не используется. Все параметры пресета передаются в JS по умолчанию и изменить это нельзя.
Для удобства обработки полей в письме, все данные массива $_POST упаковываются в JSON. Это позволяет выводить поля в чанке письма таким образом
{set $fields = $fields | replace: '"' : '"' | fromJSON}
{set $fieldsAliases = $fieldsAliases | replace: '"' : '"' | fromJSON}

{foreach $fields as $k => $v}
    {if !($k in list ['fields', 'fieldsAliases'])}
    <p><strong>{$fieldsAliases ? $fieldsAliases[$k] : $k}</strong>: {$v | join: ', '}</p>
    {/if}
{/foreach}
Вам больше нет нужны передавать такой параметр как customValidators он будет сформирован автоматически на основании параметра validate. Так же больше не возникнет ситуации в которой пользователь получает сообщение об успешной отправке, хотя на самом деле форма отправлена не была по той причине, что в параметре validate было поле, которого нет в передаваемых данных. Теперь если поле есть в validate, у него нет псевдовалидатора checkbox и оно отсутствует в $_POST, это поле будет удалено из validate. Если же псевдовалидатор checkbox есть, а поля нет в $_POST, поле будет добавлено в $_POST с пустым значением. Как вы поняли, это позволяет валидировать чекбоксы как и все остальные поля. Сниппет-валидатор checkbox создавать не нужно, его роль только в ом, чтобы отметить поле типа чекбокс.

Для обработки форм используется сниппет FormIt, однако вы можете пожелать использовать свой сниппет. На здоровье! Более того, ваш сниппет может быть файловым, если на сайте установлен pdoTools. Кроме того, вы можете использовать валидацию FormIt, для этого нужно просто указать в пресете параметр validate.

Нечасто, но бывают кейсы, когда вы заранее не знаете какой объем данных будет отправлен через форму. Например, форма с возможностью зарегистрировать несколько человек на мероприятие. По каждому участнику нужно передать одинаковы набор данных, допустим ФИО и телефон. Проще всего создать такую форму
<form data-si-form="regPeople">
        <label>
            <input type="text" name="fio[0]"  placeholder="ФИО">
            <p class="color_error px-15 fs-16-12" data-si-error="fio[0]"></p>
        </label>
        <label>
            <input type="email" name="email[0]"  placeholder="Email">
            <p class="color_error px-15 fs-16-12" data-si-error="email[0]"></p>
        </label>
        <label>
            <input type="text" name="fio[1]"  placeholder="ФИО">
            <p class="color_error px-15 fs-16-12" data-si-error="fio[1]"></p>
        </label>
        <label>
            <input type="email" name="email[1]"  placeholder="Email">
            <p class="color_error px-15 fs-16-12" data-si-error="email[1]"></p>
        </label>
        <button type="submit">Оправить</button>
    </form>
Такой вариант позволяет с помощью JS добавлять N пар полей fio-email, но как их валидировать? При использовании SendIt допускается использовать такую запись
'validate' => 'fio[*]:required,email[*]:required:email'
Так же обратите внимание, блок для вывода ошибок валидации определяется не классом, а атрибутом data-si-error с именем валидируемого поля. В отличие от класса, тут есть больше вариантов селекторов, в частности класс «email[1]» при попытке получить по нему DOMElement в JS привёл бы к ошибке.

По умолчанию, форма отправляется по событию «submit», однако бывают ситуации, когда нам нужно отправить какое-то поле после изменения, например, кода делаем регистрацию по телефону и нужно выслать код подтверждения, или при вводе, когда хотим вывести подсказки. SendIt позволяет это сделать добавив полю или всей форме атрибут data-si-event, который поддерживает два значения change и input. Все события должны быть инициированы пользователем, т.е. event.isTrusted должно быть true. Думаю это ограничение положительно скажется на количестве спама. Однако, защита от отправки форм ботами этим не ограничивается. После первого клика пользователем, в куки добавляется параметр, который позволяет идентифицировать запрос, как запрос отправленный пользователем.
Для защиты от внешнего доступа SendIt генерирует токен, которым подписывается каждый запрос на сервер.

Как вы можете влиять на все эти процессы? Конечно же через события в JS. Вам доступны следующие события
  • si:init — возникает после загрузки всех модулей
  • si:send:before — возникает перед отправкой данных на сервер, позволяет изменить параметры или прервать отправку.
  • si:send:reset — возникает перед сбросом введенных данных, позволяет отменить сброс.
  • si:send:after — возникает сразу после получения ответа от сервера и до выполнения обработчиков success или error, позволяет отменить дальнейшие действия
  • si:send:success — возникает если задача выполнена успешно, позволяет отменить обработчик success
  • si:send:error — возникает если задача не выполнена, позволяет отменить обработчик error
  • si:send:finish — возникает после выполнения всех обработчиков
С базовым функционалом всё. Но возможности SendIt не ограничиваются отправкой простых форм.

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

Я знаю, что вы всегда мечтали дать пользователям сайта возможность отправлять на сервер огромные файлы. Поздравляю, теперь вы можете это сделать. SеndIt умеет загружать файлы пачками отдельно от остальных полей с отображением прогресса загрузки каждого отдельного файла. После загрузки, пользователь может удалить один или все файлы и загрузить новые. Файлы можно прикрепить к письму передав всего один параметр. При этом сервер не будет захламляться, все загруженные файлы после обновления страницы или закрытия вкладки браузера будут удалены с сервера. Для любителей всё контролировать так же предусмотрено событие fu:before:add — срабатывает после полной загрузки файла и перед добавлением его в список загрузок.

Ну и вишенка на этом шикарном торте: сохранение данных форм. Значения всех полей, кроме паролей, форм с атрибутом data-si-form сохраняются в localStorage и не теряются при перезагрузке страницы, однако удаляются после отправки формы. Конечно же есть события
  • sf:set — возникает перед установкой сохраненных данных формы, позволяет это прервать установку значений или изменить данные
  • sf:save — возникает перед сохранением данных формы, позволяет это сохранение прервать или изменить данные
  • sf:remove — возникает перед удалением данных формы, позволяет это удаление прервать
Есть ещё модуль уведомлений. Из коробки используется библиотека IziToast. Их можно использовать отдельно от остального функционала. Я реализовал возможность обновления данных в уведомлении и передачу индивидуальных параметров для каждого уведомления, если нужно. Так, например, для отображения прогресса загрузки файлов, используются изменённые параметры.

В конце ещё пару слов о серверной части. Компонент генерирует системное событие OnGetFormParams, используя его можно на лету менять параметры отправки формы. В частности если вы используете Formalicious, то можно получить параметры заданные в нём и добавить их к параметрам пресета из файла.

Поддержка AjaxFormItLogin прекращена, однако весь функционал будет доступен в SendIt.

Посмотреть на работу SendIt можно на демо-сайте
О возможности скачать пакет для установки будет сообщено отдельно.

Спасибо за внимание!
Артур Шевченко
22 августа 2023, 15:44
modx.pro
3
1 397
+14
Поблагодарить автора Отправить деньги

Комментарии: 6

Дима Касаткин
22 августа 2023, 17:05
0
Интересное решение, особенно то, что не требует вызова сниппета!
Будем пробовать на следующем же проекте!

В будущем планирую создать в админке интерфейс для управления формами, аналог Formalicious, только название попроще придумаю.
Может я в своём стиле конечно, но товарищи, Formalicious — OpenSource компонент. И сделан достаточно универсально. Я недавно использовал его, нашел кучу несоответствий документации неочевидных моментов, подготовил код для PR как в него (в том числе русские лексиконы), так и в его доку.

Пожалуйста, давайте объединять усилия, вместо того, чтобы параллельно разрабатывать одинаковое. Для платных компонентов это имеет понятный смысл, а в данном случае, ну уж какое есть название, в крайнем случае его форкнуть, Formalicious этот и допилить поддержку. Он совсем не плох, но может быть ещё лучше, если приделать к нему работу без перезагрузки и в админке причесать!

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

P.S. Ура, красивая демо-страница :) отдельное спасибо за неё
    Артур Шевченко
    22 августа 2023, 17:20
    +1
    Тут такое дело, я с ExtJs не дружу. Делать хочу на Vue. Я посмотрел Formalicious он сложноват для рядового пользователя. Там нет того, чего мне бы хотелось, например возможность выбирать валидаторы для поля из списка, добавлять полю атрибуты, выбирать для поля чанк. Выбор параметров я бы переделал. В общем, мне проще сделать с нуля так как я хочу, чем допилить.
    Что же до интеграции SendIt, то его можно хоть с MiGX сопрячь через плагин, который передаст массив параметров в SendIt, а как и откуда ты эти параметры возьмешь другой вопрос.
    Дима Касаткин
    22 августа 2023, 17:18
    0
    @Артур Шевченко лови донатик, восполни потраченные на написание анонса калории :)

    Друзья, всем кому интересны новые компоненты, не забывайте тоже про раздел Поблагодарить автора под каждым постом здесь!
      Артур Шевченко
      22 августа 2023, 17:23
      0
      Спасибо за донатик))) А калорий я потратил больше, чем рассчитывал. Думал управлюсь за пару дней, потратил 4 и это я ещё документацию не писал.
      deleted
      24 августа 2023, 05:03
      0
      А с рекапчей будет совместимо?
        Артур Шевченко
        24 августа 2023, 09:59
        0
        Из коробки нет, но ты можешь добавить проверку сам. Я надеюсь, что предпринятых программных мер будет достаточно для блокировки спама от ботов, ну а к людям нужен индивидуальный подход.
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        6