[FetchIt] - Полноценная замена AjaxForm без зависимостей
Представляю вашему вниманию новый бесплатный компонент MODX Revolution для обработки и отправки форм, который пришёл на замену AjaxForm. И давайте начнём сразу с преимуществ и различий:

FetchIt не имеет никаких зависимостей, тогда как у AjaxForm их три:
Встраивание вашей вёрстки, добавление всплывающих сообщений и модальных окон, это задачи которые Вы сможете решить очень просто.
Сразу отвечу на этот предсказуемый вопрос, ведь я в организации modx-pro и мог бы выпустить новую мажорную версию и разработчики могли бы обновиться. Причин два: во-первых это название – AjaxForm, дело в том, что аббревиатура AJAX которая расшифровывается как Asynchronous Javascript and XML для данного компонента не подходит, он для отправки форм использует Fetch API. Во-вторых, изменения большие и обратную совместимость всё равно сохранить было невозможно.
Для быстрого старта Вам необходимо вызвать сниппет FetchIt который идёт в компоненте, передав ему основные параметры которые совпадают по названию с параметрами AjaxForm.
или на fenom
На сайте с документацией есть подробное описание миграции, но тут опишу вкратце. Параметры frontend_css и formSelector убраны за ненадобностью, а frontend_js и objectName были перемещены в системные настройки и называются fetchit.frontend.js и fetchit.frontend.js.classname соответственно.
Компонент не регистрирует стили. Так что вам самим нужно позаботиться о них (речь о стилях отвечающих за невалидным состоянием полей). Есть две настройки fetchit.frontend.input.invalid.class и fetchit.frontend.custom.invalid.class отвечающие за добавление классов полям ввода и кастомным элементам (например элементам-обёрткам).
Вывод всплывающих сообщений также перекладывается на плечи самих разработчиков, но реализация максимально простая и в документации уже есть подробные примеры популярных и не очень библиотек: SweetAlert2, Notyf, iziToast, Notiflix.Notify, Notie, Awesome Notifications, Toastify JS, AlertifyJS, PNotify, toastr и даже наш любимый jGrowl.
Изменились селекторы, теперь не используются CSS классы, которые предназначены для определения стилей. Вместо них дата-атрибуты. Опять же, призываю вас на сайт документации, где подробно описаны примеры типовых решений разметок Bootstrap, Bulma, UIkit, Fomantic-UI, Pico.css, Cirrus CSS, turretcss и Vanilla.
Если у вас была какая-то логика связанная с отправкой формы (Например, дополнительная отправка данных в CRM или аналитические сервисы и метрики), то нужно будет немного переписать. jQuery больше нет и у AjaxForm было одно событие на фронте, а в FetchIt их пять:
Ниже пример в котором добавляется новое поле перед отправкой формы:
или отправляем данные в CoMagic после успешной отправки формы:
На этом думаю пока что достаточно, как уже несколько раз было упомянуто выше, больше примеров и описание API на сайте с документацией. Компонент уже доступен для установки на маркетплейсе modstore.pro и modx.com.
Документация
Репозиторий на GitHub
☕ Угостить чашкой кофе

FetchIt не имеет никаких зависимостей, тогда как у AjaxForm их три:
- Большая библиотека jquery.
- Плагин для работы с формами jquery-form.
- И jGrowl для показа уведомлений.
Встраивание вашей вёрстки, добавление всплывающих сообщений и модальных окон, это задачи которые Вы сможете решить очень просто.
Почему не AjaxForm 2.0.0?
Сразу отвечу на этот предсказуемый вопрос, ведь я в организации modx-pro и мог бы выпустить новую мажорную версию и разработчики могли бы обновиться. Причин два: во-первых это название – AjaxForm, дело в том, что аббревиатура AJAX которая расшифровывается как Asynchronous Javascript and XML для данного компонента не подходит, он для отправки форм использует Fetch API. Во-вторых, изменения большие и обратную совместимость всё равно сохранить было невозможно.
Быстрый старт
Для быстрого старта Вам необходимо вызвать сниппет FetchIt который идёт в компоненте, передав ему основные параметры которые совпадают по названию с параметрами AjaxForm.
[[!FetchIt?
&snippet=`FormIt`
&form=`myForm.tpl`
&hooks=`email`
&emailSubject=`Тема письма`
&emailTo=`info@domain.com`
&validate=`name:required,email:required`
&validationErrorMessage=`В форме содержатся ошибки!`
&successMessage=`Сообщение успешно отправлено`
]]или на fenom
{'!FetchIt' | snippet : [
'snippet' => 'FormIt',
'form' => 'myForm.tpl',
'hooks' => 'email',
'emailSubject' => 'Тема письма',
'emailTo' => 'info@domain.com',
'validate' => 'name:required,email:required',
'validationErrorMessage' => 'В форме содержатся ошибки!',
'successMessage' => 'Сообщение успешно отправлено',
]}Миграция с AjaxForm
На сайте с документацией есть подробное описание миграции, но тут опишу вкратце. Параметры frontend_css и formSelector убраны за ненадобностью, а frontend_js и objectName были перемещены в системные настройки и называются fetchit.frontend.js и fetchit.frontend.js.classname соответственно.
Компонент не регистрирует стили. Так что вам самим нужно позаботиться о них (речь о стилях отвечающих за невалидным состоянием полей). Есть две настройки fetchit.frontend.input.invalid.class и fetchit.frontend.custom.invalid.class отвечающие за добавление классов полям ввода и кастомным элементам (например элементам-обёрткам).
Вывод всплывающих сообщений также перекладывается на плечи самих разработчиков, но реализация максимально простая и в документации уже есть подробные примеры популярных и не очень библиотек: SweetAlert2, Notyf, iziToast, Notiflix.Notify, Notie, Awesome Notifications, Toastify JS, AlertifyJS, PNotify, toastr и даже наш любимый jGrowl.
Изменились селекторы, теперь не используются CSS классы, которые предназначены для определения стилей. Вместо них дата-атрибуты. Опять же, призываю вас на сайт документации, где подробно описаны примеры типовых решений разметок Bootstrap, Bulma, UIkit, Fomantic-UI, Pico.css, Cirrus CSS, turretcss и Vanilla.
Если у вас была какая-то логика связанная с отправкой формы (Например, дополнительная отправка данных в CRM или аналитические сервисы и метрики), то нужно будет немного переписать. jQuery больше нет и у AjaxForm было одно событие на фронте, а в FetchIt их пять:
Ниже пример в котором добавляется новое поле перед отправкой формы:
document.addEventListener('fetchit:before', (e) => {
const { formData } = e.detail;
formData.set('newField', 'Значение нового поля'); // Добавляем новое поле
})или отправляем данные в CoMagic после успешной отправки формы:
document.addEventListener('fetchit:success', (e) => {
const { formData } = e.detail;
Comagic.addOfflineRequest({
name: formData.get('name'),
email: formData.get('email'),
phone: formData.get('phone'),
message: formData.get('message'),
group_id: 1234
});
})На этом думаю пока что достаточно, как уже несколько раз было упомянуто выше, больше примеров и описание API на сайте с документацией. Компонент уже доступен для установки на маркетплейсе modstore.pro и modx.com.
Документация
Репозиторий на GitHub
☕ Угостить чашкой кофе
Комментарии: 60
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
Вопрос: есть ли какая то реализация антиспама?
Компонент только для ModX 2?
Значит подождем.
компонент работает, только в журнал ошибок сыпет:
MODX Revolution 2.8.4-pl
PHP Version 8.1.10
Исправил.
Версия 1.0.0 доступна на modstore.pro
Она же будет доступна после модерации на modx.com
Вызов такой:
1. Всё остальное работает? Отправляется ли форма, работает ли валидация?
2. Сколько вызовов FetchIt есть на странице? Если больше одного, то покажи их тоже.
3. Есть ли в консоли js какие-то ошибки?
2. Один вызов FetchIt на странице
3. В консоли браузера ошибок нет, в админке тоже
Но вот что за прикол не знаю, только что проверил отправку и все сработало и форма очистилась…
Интересный прикол.
Но не понятно в чем преимущество удаления зависимости от jquery?
99% сайтов на modx используют эту либу.
Да и говорить что она огромная, это смешно, по сути весит как одна картинка на любом сайте да и в браузере уже у всех в кеше есть.
Я (очень) далеко не первый кто прыгает в поезд тенденции отказа от jQuery, которая возникла по объективным причинам. Главная из которых: сам JavaScript её почти/уже догнал по функционалу и удобству.
Использовать jQuery только чтобы навесить один обработчик на событие и добавить/удалить css класс с нескольких элементов — это одеть медведя в меховую шубу! Вот если вы сфинкс в Сибири, то надевать шубу (использовать jQuery) имеет смысл.
Ну и прекрасно, но это к чему? Это же аргумент в пользу FetchIt. Следите за руками:
— Если (как вы утверждаете) 99% сайтов на MODX используют jQuery, то AjaxForm будет работать на 99% сайтах, остальным сайтам (1%) которые без jQuery, придется тянуть зависимость только чтобы работал AjaxForm.
— Если (как вы утверждаете) 99% сайтов на MODX используют jQuery, то FetchIt будет работать на 100% сайтах, даже у тех где используется jQuery.
На это уже @Артур Шевченко ответил, но я дополню, больше не для вас, а для всех кто так думает. FetchIt делает больше и лучше за 300 строчек кода чем AjaxForm за более чем 12 000.
Именно поэтому я реализовал JS API (документация) таким образом, чтобы можно было реализовать разные сценарии.
Кстати, в версии альфа такая возможность была в коробке, но я выпилил в пользу API, но если люди захотят, то могу вернуть эту возможность.
Какие задачи связанные с отправкой формы нельзя решить используя AjaxFormitLogin?
AjaxForm тянул jQuery и jGrowl, AjaxFormitLogin тянет IziToast только для того, чтобы из коробки были уведомления. В документации написано как отключить их и заменить.
Fetch API не позволяет отслеживать процесс загрузки файлов, а мне это нужно.
Добавление и/или изменение значений отправляемых на сервер, например. Или ты хочешь предложить манипулировать DOM для этого?
Ну мне то объяснять уж не стоило. Ответ на вопрос «Почему?» я знаю, тут другой несколько вопрос «Зачем?». Каждый раз когда зависимость обновиться, нужно будет обновить компонент? Ну прикольно. А еще бывают «прикольные приколы», когда разработчик sweetalert2 захочет выразить свой личный протест в OpenSource проекте, то как быть с этим?
Тут важно, не каждая зависимость это плохо, но это тот самый случай, когда легко и безболезненно можно обойтись и без него.
Позиция ясна. А это единственная причина? Fetch API пока не позволяет. Но знаешь в чём загвоздка? Работа над введением этой возможности ведётся и оно точно появится, а ведётся ли работа над асинхронностью в XMLHttpRequest?
Грубо говоря да, но при желании всегда можно расширить класс.
Нет смысла обновлять то, что и так работает.
Понятное дело не использовать подключение зависимостей через cdn.
Когда такая возможность появится — перепишу.
Хорошо, ты не смог придумать, а я представь — смог. Тык, тык и тык.
Прости, но мне придётся поязвить — ты же обязательно покажешь как расширить класс? Т.е. для простой задачи добавить и/или изменить значение в форму перед её отправкой, нужно манипулировать с DOM или расширить класс? Прикольно.
Я уже понял. Именно с этим лозунгом ты сменил jquery-form на XMLHttpRequest
Ты проигнорировал вопрос про асинхронность в XMLHttpRequest, но это приводит к более веселой ситуации: А когда в XMLHttpRequest появится (спойлер — не появится, но есть библиотеки-обёртки над ним в которых реализована асинхронность) ты обратно перепишешь с Fetch API на XMLHttpRequest?
Я согласен, что это не самое удобное решение, но вынужден повторить — в моей практике нечасто встречаются кейсы требующие манипулировать значениями перед отправкой, поэтому я и не добавил дополнительных событий.
Нет, лозунг был другой: одна отключаемая зависимость лучше двух обязательных.
Потому что счёл его риторическим, логично же что никаких работ по усовершенствованию не ведётся, разработан новый API и его развивают.
Ты меня за идиота принимаешь? Я решаю возникающие у меня задачи, удобным для меня способом. Мне нужно показывать процесс загрузки, Fetch API этого не умеет, я использовал XMLHttpRequest. По-моему всё логично.
Мне кажется ты упускаешь суть: ты писал компонент с целью внедрения Fetch API, я писал компонент с целью повысить удобство собственной работы и отказаться от использования jQuery. Не вижу причин по которым я обязан был использовать Fetch вместо XMLHttpRequest. Для пользователя компонента это вообще не важно, что там под капотом, главное это стабильное выполнение необходимых ему функций.
И наконец, всё что ты перечислил в качестве проблем AjaxFormitLogin, всего лишь твоё скромное мнение, о чем ты забыл упомянуть, отчего кому-то может показаться, что перечисленные тобой «проблемы» действительно серьезно могу усложнить жизнь пользователю моего компонента. Я думаю тот, кому понадобится больше событий и API, легко поймёт, что всё это есть в FetchIt, и выберет именно его.
Причем для Формы файловая «ссылка» срабатывает
Спасибо за ответ!
2. Есть черновой вариант полной поддержки MODX 3, но я занят по работе и кое-что масштабное готовлю для сообщества.
Как будет время доделаю
Столкнулся с такой ситуацией:
Если добавляю сниппет на страницу – выводится форма и отрабатывает проверка полей с выводом нотификаций без перезагрузки страницы. Т.е. все работает.
Но если я вызываю сниппет в модальном окне — сниппет запускается при нажатии на кнопку ( через QuickView или через режим Ajax в FancyBox3 ) то при отправке формы происходит перезагрузка страницы.
Пробовал добавлять в модалку , сниппет добавляет при запуске и скрипты и стили и Но при отправке перезагружает всю страницу и все(
Подскажите куда копать?
Всё что вы говорите, верно и дело в том, что данная версия компонента и не предусматривает такого функционала. Об этом нигде и не заявлялось. Я озабочен такой ситуацией и в будущем реализую такой функционал, спасибо!
пока такой костыль, но работает
а, еще чтобы FetchIt был подключен всегда и объявлена переменная FetchIt до запуска вышенаписанного кода, в футере например вызываю пустой FetchIt
Подскажите, как наиболее правильно отправлять цель в Яндекс-Метрику при отправке формы?
добавить обработчик на событие «fetchit:success»
docs.modx.pro/components/fetchit/frontend/events
Я пробую скомпоновать что-то из примеров выше и документации — не отправляет. :)
Я могу это так вставить на страницу с формами?
«не могу найти указанный ключ формы (action)»
Вызываю некэшированно. Не понимаю в чем проблема (