- Главная страница
- Конструктор форм
«Конструктор форм» (formkit) — приложение Webasyst для форм обратной связи, заявок и виджетов на сайте. Соберите форму из 24 типов полей без единой строчки кода, оформите одной из 5 готовых тем (одна базовая и четыре премиум), встройте на сайт так, как удобно, и получайте заявки в Email, SMS, VK, Telegram, amoCRM или Bitrix24. Статусы, статистика и три уровня защиты от спама — уже внутри.
Формы разделены на поля и элементы — от простого текстового ввода до диапазона, рейтинга, карточек выбора и капчи. Каждое поле настраивается отдельно: маска ввода, ограничение длины со счётчиком символов, диапазон дат, подстановка значения по умолчанию со сдвигом от текущего момента.
Уведомления о новой заявке приходят туда, где удобно: на email с HTML-шаблоном письма, по SMS, в VK, в Telegram — или сразу сделкой в amoCRM либо лидом в Bitrix24 с помощью плагинов. Каждый канал включается независимо для каждой формы.
Пять готовых тем оформления (Базовая и 4 премиум: Vega , Orion , Epsilon , Proxima ) задают не только цвета и шрифты, а весь визуальный стиль формы, попапа и виджета. Ширина, скругления, рамка, центрирование — без единой строчки CSS.
Начало работы
Установите приложение через Инсталлер Webasyst — оно появится в общем списке приложений слева. При первой установке автоматически создаются 7 демо-форм и 2 демо-заявки, чтобы сразу увидеть, как это работает вживую.
- Откройте приложение «Конструктор форм» и нажмите «Создать форму».
- На вкладке «Добавление полей» соберите форму из нужных полей и элементов — кнопками «Добавить поле» / «Добавить элемент», порядок меняется перетаскиванием.
- На вкладке «Дизайн» выберите тип формы (кнопка с модальным окном, виджет, встройка в текст и т.д.) и оформление.
- На вкладке «Уведомления» включите каналы, куда должны приходить заявки.
- На вкладке «Встроить на сайт» скопируйте код и вставьте его в шаблон темы или в HTML-блок страницы.
<!-- Пример для формы с ID 1 -->
{$wa->formkit->getForm(1)} Код вставки принимает номер формы — его видно в списке «Все формы» рядом с каждой строкой. Работает в любом месте, где разрешён Smarty: в шаблонах темы, на странице сайта, в блоге.
Размещение на сайте
Тип размещения задаётся на вкладке «Дизайн» формы, один и тот же код вставки работает для любого варианта — переключать тип можно в любой момент без изменения кода на странице.
Способ 1. Привязка формы к кнопкам или ссылкам на сайте
Скопируйте код формы и вставьте его в настройках темы дизайна, в раздел Основные настройки → Прочее → Дополнительный код , а если такой настройки в вашей теме нет — прямо в файл index.html. Так форма будет доступна на всех страницах сайта. Если форма нужна только на одной странице, код вставки можно разместить в настройках конкретной страницы в бэкенде Webasyst.
При создании формы на вкладке «Дизайн» укажите тип Модальное окно без кнопки , а в настройке Селектор триггера — URL-хэш, например #mini-forma. Такой способ удобен тем, что клиенту можно сразу отправить ссылку с открытой формой, достаточно добавить этот хэш в конец адреса страницы: https://example.com/#zapis-na-priem.
После этого в теме дизайна в настройках любой кнопки или ссылки можно указать в качестве URL этот же хэш — и по нажатию на такую кнопку или ссылку будет открываться окно формы.
Способ 2. Добавление кнопки с модальным окном
Если выбрать тип формы Кнопка с модальным окном , то кнопка будет выводиться там, куда вставлен код формы, например на текстовую страницу магазина. Добавление кода на такие страницы следует осуществлять исключительно в режиме HTML. По клику посетитель видит форму в попапе поверх страницы, сайт при этом не покидается и не перезагружается.
Способ 3. Добавление прямо в текст страницы
Если выбран тип формы Встроить на страницу , то форма будет выводиться прямо в том месте страницы, куда вставлен код, без кнопки и всплывающего окна. Для того, чтобы форма удачно вписалась на страницу, выберите подходящий размер формы, включите или отключите рамку. Если форма должна находиться в уже готовом контейнере со своими отступами, включите в настройках формы режим «Без отступов».
Способ 4. Виджет в углу сайта и компактный виджет с формой
Для размещения виджета достаточно выбрать тип формы Виджет в нижнем углу сайта и один раз вставить код в файлы темы, например в index.html или в настройки темы дизайна, в раздел Основные настройки → Прочее → Дополнительный код . По клику посетителя форма разворачивается поверх содержимого страницы.
Дизайн и оформление
Вкладка «Дизайн» формы отвечает за тип размещения и визуальное оформление. В премиум-версии приложения есть возможность выбрать помимо дефолтного варианта оформления одну из 4 премиум-тем: Vega, Orion, Epsilon, Proxima. Меняет не только цвета, но и весь визуальный стиль полей. Премиум-оформление добавляет анимации кнопок, появления и исчезновения модальных окон.
Защита от заявок и спама
На вкладке «Настройки» формы — три независимых уровня защиты, работают без дополнительных сервисов:
- HoneyPot («Защита от спама», включена по умолчанию) — на форму добавляется скрытое поле, которое видят и заполняют только боты. Обычные посетители его не замечают, а заявка с заполненным скрытым полем тихо отбрасывается.
- Ограничить отправку с одного IP — по умолчанию один IP-адрес сможет отправить не более 5 заявок в час, после достижения лимита форма скрывается от этого посетителя. Так же исключается спам-рассылка заявок с одного компьютера.
- Ограничить работу формы по времени — форма принимает заявки только в указанный период, затем скрывается на сайте, а отправка перестаёт работать — в том числе у посетителей, которые открыли страницу заранее и с тех пор не обновляли её в браузере.
Четвёртый уровень — поле-элемент Капча , которое можно добавить в саму форму как обычное поле. Доступны два типа:
- Стандартная капча Webasyst — картинка с кодом, ничего дополнительно настраивать не нужно.
- Yandex SmartCaptcha — клиентский и серверный ключ выдаются на cloud.yandex.ru/services/smartcaptcha для конкретного домена сайта. Доступен невидимый режим — проверка идёт в фоне без взаимодействия посетителя, дополнительное окно появляется, только если поведение показалось Яндексу подозрительным.
SMS уведомления
Использует общий SMS-шлюз Webasyst — отдельного аккаунта заводить не нужно, но отправка платная: баланс и тариф настраиваются один раз в Настройках Webasyst → SMS, действуют сразу для всех приложений, использующих SMS.
VK уведомления
Уведомление приходит в личные сообщения сообщества ВКонтакте.
В настройках вашего сообщества откройте Управление → Дополнительно → Работа с API → Ключи доступа и создайте новый ключ с правом «Сообщения сообщества». Такой токен не имеет срока действия, пока вы не отзовёте его вручную.
Вставьте этот токен в поле «Токен сообщества» в приложении.
В поле «ID получателя» укажите числовой ID профиля ВКонтакте (не логин и не ссылку на профиль) — можно несколько через запятую, максимум 5. Узнать свой числовой ID можно через сторонние сервисы, такие как regvk.com/id.
ВКонтакте разрешает сообществу писать только тем пользователям, которые уже сами хотя бы раз написали этому сообществу — иначе отправка не пройдёт. Это ограничение самого ВКонтакте. Если вы хотите получать уведомления, обязательно начните диалог (напишите первое сообщение) с вашим сообществом.
Telegram уведомления
Уведомление приходит от собственного Telegram-бота.
Создайте бота через @BotFather в Telegram: команда /newbot , следуйте подсказкам — в конце BotFather пришлёт токен, скопируйте его в поле «Токен бота».
Узнайте свой числовой Chat ID через @userinfobot — просто напишите ему (/start).
Вставьте ID в поле «Chat ID получателя», можно несколько через запятую, максимум 5. Для групп и каналов ID начинается со знака «−».
Telegram не позволяет боту первым написать пользователю, получатель должен сам хотя бы раз написать боту (например, отправить команду /start), иначе сообщения не будут доходить.
Интеграция с amoCRM
Отдельный плагин «Интеграция с amoCRM» — устанавливается через Инсталлер дополнительно к самому приложению. Подключение аккаунта amoCRM — одно на весь аккаунт Webasyst (раздел «Плагины»), а отправлять туда заявки или нет — решает каждая форма своим тумблером на вкладке «Уведомления».
В amoCRM откройте раздел «amoМаркет» → кнопку с тремя точками в правом верхнем углу → «Создать интеграцию» → «Внешняя интеграция».
Заполните «Название интеграции» и «Описание» (обязательны для сохранения, подойдёт любой текст), в поле «Ссылка для перенаправления» вставьте значение из настроек плагина, обязательно отметьте «Предоставить доступ: Все».
После сохранения на вкладке «Установленные» скопируйте ID интеграции и секретный ключ, вставьте их вместе с поддоменом аккаунта в настройках плагина formkit и нажмите «Подключить amoCRM».
После подключения плагин при каждой заявке ищет контакт в amoCRM по телефону или email — находит, привязывает к нему новую сделку и дополняет только пустые поля контакта; не находит — создаёт новый контакт. Заголовок сделки собирается по шаблону с переменными полей заявки.
На вкладке каждого поля формы есть блок «Отправить в amoCRM» — выпадающий список полей сделки вашего аккаунта (обновляется кнопкой в настройках плагина) либо телефон/email/имя контакта. Если поле сделки в amoCRM само является закрытым списком (выпадающий список, радио-кнопки, мультисписок), редактор вариантов формkit-поля автоматически блокируется и заполняется точным списком значений из amoCRM — это исключает расхождение текста между формой и CRM. На вкладке «Уведомления» формы можно также выбрать воронку, этап и ответственного менеджера для новой сделки.
Интеграция с Bitrix24
Отдельный плагин «Интеграция с Bitrix24». Подключение — входящим вебхуком, одно на весь портал, каждая форма включает канал своим тумблером на вкладке «Уведомления».
В Bitrix24 откройте раздел Приложения → «Разработчикам» → «Другое» → «Входящий вебхук», в блоке «Настройка прав» доступа отметьте «CRM» и «Пользователи» и сохраните.
Bitrix24 выдаст готовую ссылку вида https://портал.bitrix24.ru/rest/1/xxxxxxxxxxxxxxxx/ — скопируйте её целиком (она содержит ключ доступа, храните как пароль).
Вставьте ссылку в поле «Ссылка на вебхук» настроек плагина и нажмите «Подключить Bitrix24» — плагин сразу проверит связь с порталом.
Каждая заявка становится лидом. Поле «Поле в Bitrix24» на вкладке поля формы — телефон, email или имя лида (подставляются по умолчанию для полей соответствующего типа), любое произвольное поле лида из вашего портала, либо «Только в комментарии к лиду». Всё, что не привязано ни к одному полю, всё равно попадает в текст комментария — заявка никогда не теряет данные. На вкладке «Уведомления» формы можно выбрать этап и ответственного менеджера.
Премиум-возможности
- 4 дополнительные темы дизайна — Vega, Orion, Epsilon, Proxima
- Экспорт заявок в CSV — одна, выбранные или все сразу
- Экспорт и импорт самих форм — перенос формы между сайтами файлом
- Тестовая отправка для каналов Email, SMS, VK и Telegram (тестовая отправка в amoCRM и Bitrix24 премиум-ограничением не считается — это часть отдельных плагинов)
JS-события на сайте
Публичный скрипт формы диспатчит нативные CustomEvent на document — пригодятся, если нужно добавить свою реакцию на действия формы, например отправить событие в свою систему аналитики.
| Свойство | Тип данных | Описание |
|---|---|---|
| formkit:render | Форма инициализирована в DOM (один раз на форму на странице) | { formNumber, root } |
| formkit:open | Форма-попап или виджет открылась | { formNumber } |
| formkit:submit | Заявка успешно отправлена | { formNumber, data } |
document.addEventListener('formkit:submit', function (event) {
console.log(event.detail.formNumber, event.detail.data);
})
document.addEventListener('formkit:open', function (event) {
console.log(event.detail.formNumber);
})
document.addEventListener('formkit:render', function (event) {
var root = event.detail.root; // корневой элемент .formkit-root
})
formNumber в event.detail совпадает с номером в коде вставки формы. Это удобно, если события нужно различать между несколькими формами на одной странице.
Хуки для плагинов
«Конструктор форм» поддерживает плагины на платформе Webasyst — функциональность расширяется без изменения кода ядра. Плагин размещается в wa-apps/formkit/plugins/[plugin_id]/ , обязательный файл lib/config/plugin.php ничем не отличается от плагинов других приложений Webasyst: name, description, version, vendor, handlers.
<?php
return [
'name' => 'Моё название',
'description' => 'Что делает плагин',
'version' => '1.0.0',
'vendor' => 1000000,
'handlers' => [
'formkit_submission_after_save' => 'onSubmissionSaved',
],
]; Каждый обработчик, указанный в handlers, обязан быть реализован соответствующим методом класса плагина, иначе событие не сработает, даже если метод существует, но не прописан в plugin.php.
Ниже все события приложения (хуки), в порядке момента срабатывания: сначала поток приёма заявки, затем регистрация новых типов полей и каналов уведомлений, инъекция интерфейса в бэкенде и на публичной форме, и отдельная публичная точка входа для плагинов без сессии Webasyst.
События приёма заявки
Все три события объявляются в момент обработки отправленной формы, до, во время и сразу после сохранения заявки.
formkit_submission_before_validate
Срабатывает после того, как определён список активных полей формы, до цикла валидации. Нужен плагинам условной логики — например, если поле «Компания» показывается только при выборе типа клиента «Юрлицо». Такой плагин проверяет значения полей и здесь помечает те, что должны быть скрыты по текущим условиям — тогда они не будут требоваться как обязательные при отправке формы.
| Свойство | Тип данных | Описание |
|---|---|---|
| form | array | Форма (decoded, включая settings) |
| fields | array | Активные поля формы, без учёта скрытия |
| posted_fields | array | Значения из $_POST['fields'] после обрезки пробелов (trim) |
| hidden_field_ids | array | Заполняет обработчик — ID полей, которые считать скрытыми |
Поля, чей id попал в hidden_field_ids , не проверяются на обязательность и не попадают в переменные уведомлений ( {$field_N} ). Их посланное значение всё равно сохраняется как есть.
Реально влияет на дальнейшую обработку только hidden_field_ids — именно его контроллер считывает обратно после события. Изменение form, fields или posted_fields в обработчике не отражается на валидации и сохранении заявки.
<?php
public function onBeforeValidate(&$params)
{
foreach ($params['fields'] as $field) {
$conditions = $field['config']['conditions'] ?? null;
if ($conditions && !myConditionsEngine::isVisible($conditions, $params['posted_fields'])) {
$params['hidden_field_ids'][] = (int)$field['id'];
}
}
} formkit_submission_compute_fields
Срабатывает после успешной валидации, до сохранения заявки в БД. Назначение — плагины вычисляемых полей: пересчитать значение на сервере, не доверяя тому, что посчитал браузер.
| Свойство | Тип данных | Описание |
|---|---|---|
| form | array | Форма |
| fields | array | Поля формы, уже прошедшие валидацию |
| data | array | [field_id => значение] — можно перезаписывать |
| posted_fields | array | Сырые значения из $_POST['fields'] |
<?php
public function onComputeFields(&$params)
{
foreach ($params['fields'] as $field) {
if ($field['type'] !== 'formula') {
continue;
}
$params['data'][$field['id']] = myFormulaEngine::evaluate(
$field['config']['expression'] ?? '',
$params['data']
);
}
} formkit_submission_after_save
Срабатывает сразу после сохранения заявки и отправки всех включённых уведомлений — не только штатных (email/SMS/VK/Telegram), но и через formkit_notify_channels (например, amoCRM или Bitrix24). Основное назначение — интеграции с внешними системами.
| Свойство | Тип данных | Описание |
|---|---|---|
| submission_id | int | ID сохранённой заявки |
| form | array | Форма |
| data | array | [field_id => значение], уже после formkit_submission_compute_fields |
| vars | array | Готовые переменные для уведомлений: id, form_name, date, ip, field_N — человекочитаемые значения |
<?php
public function onSubmissionSaved(&$params)
{
if (empty($this->getSettings('enabled'))) {
return;
}
myExternalApiClient::pushLead($params['form'], $params['vars']);
} Для интеграций с CRM есть более удобный путь — регистрация как канала уведомлений (formkit_notify_channels, ниже), с готовым UI: тумблер, настройки, кнопка теста. Событие formkit_submission_after_save при этом остаётся рабочим для тех, кому весь этот UI не нужен.
Реестры
В отличие от событий выше, эти два события — регистрация: обработчик не реагирует на что-то произошедшее, а объявляет новую сущность, которую ядро начинает использовать наравне со встроенными. Оба срабатывают один раз за запрос.
formkit_field_types
Регистрирует новый тип поля — ядро после этого умеет его рендерить на публичной форме и подставлять значение в переменные уведомлений.
| Свойство | Тип данных | Описание |
|---|---|---|
| types | array | Заполняет обработчик — массив описаний новых типов |
| types[].type | string | Машинное имя типа. Совпадает с уже существующим — регистрация игнорируется |
| types[].template_path | string | Абсолютный путь к Smarty-шаблону рендера поля на публичной форме |
| types[].notification_variable | bool | Участвует ли значение поля в {$field_N} — необязательно |
| types[].format_callback | callable | function(string $value, array $config): string — форматирование значения для уведомления и CSV, необязательно |
<?php
class myFormulaPlugin extends waPlugin
{
public function registerFieldTypes(&$params)
{
$params['types'][] = [
'type' => 'formula',
'template_path' => $this->path . '/templates/public/fields/formula.html',
'notification_variable' => true,
'format_callback' => ['myFormulaHelper', 'formatValue'],
];
}
} formkit_notify_channels
Регистрирует канал уведомлений — появляется на вкладке «Уведомления» формы наравне с Email/SMS/VK/Telegram и участвует в отправке при получении заявки. Именно так реализованы плагины amoCRM и Bitrix24.
| Свойство | Тип данных | Описание |
|---|---|---|
| channels | array | Заполняет обработчик — массив описаний каналов |
| channels[].id | string | Машинное имя канала, например amocrm |
| channels[].label | string | Название в UI, необязательно — по умолчанию id |
| channels[].enabled_key | string | Ключ в form.settings, хранящий состояние тумблера |
| channels[].settings_template | string | Абсолютный путь к Smarty-партиалу настроек канала, необязательно |
| channels[].plugin_id | string | ID вашего плагина — обязателен вместе с settings_template, иначе переводы резолвятся по домену локализации formkit |
| channels[].send_callback | callable | function(array $form, array $vars, array $attachments): void — вызывается при получении заявки |
| channels[].test_callback | callable | function(array $form, array $vars): array{success, error, sent_at} — кнопка тестовой отправки, необязательно |
Регистрация без send_callback или enabled_key игнорируется целиком. Тумблер «Включено/Выключено» сохраняется автоматически ядром, плагину не нужен свой JS для этого. Сохранение остальных полей внутри settings_template (токены, адреса и т.п.) забота плагина , своим экшеном.
<?php
class myAmoCrmPlugin extends waPlugin
{
public function registerNotifyChannel(&$params)
{
$params['channels'][] = [
'id' => 'amocrm',
'label' => 'amoCRM',
'enabled_key' => 'notify_amocrm_enabled',
'settings_template' => $this->path . '/templates/notify/AmoCrmSettings.html',
'plugin_id' => 'amo',
'send_callback' => ['myAmoCrmSender', 'send'],
];
}
} Инъекция интерфейса
formkit_field_edit_sections
Добавляет свою секцию в единый диалог редактирования поля в бэкенде — тот же диалог для всех типов полей, секции показываются и скрываются в зависимости от выбранного типа. Срабатывает один раз на загрузку страницы редактора формы, не на каждое открытие диалога.
| Свойство | Тип данных | Описание |
|---|---|---|
| sections | array | Заполняет обработчик — массив описаний секций |
| sections[].html | string | Готовый HTML секции, отрендеренный на вашей стороне |
| sections[].types | array | Список типов полей, для которых показывать секцию. Не указано — секция показывается для всех типов |
HTML рендерьте сами через wa()->getView()->fetch(...) — ядро его не экранирует, только оборачивает в контейнер, который сам показывается и скрывается при переключении типа поля в диалоге.
<?php
class myConditionsPlugin extends waPlugin
{
public function registerFieldEditSection(&$params)
{
$params['sections'][] = [
'html' => wa()->getView()->fetch($this->path . '/templates/FieldEditSection.html'),
];
}
} Диалог рендерится один раз на страницу, поэтому чтобы секция знала, для какого именно поля она сейчас открыта, и получила его полный конфиг. Строка таблицы полей несёт весь конфиг поля в data-config (JSON), а на document диспатчится JS-событие formkit:field-edit-open в конце открытия диалога — с detail.fieldId , detail.type (текущий тип поля) и detail.row :
document.addEventListener('formkit:field-edit-open', function (event) {
var fieldId = event.detail.fieldId;
var type = event.detail.type;
var row = event.detail.row;
var config = JSON.parse(row.dataset.config || '{}');
var myValue = config.my_plugin_key ?? '';
// выставить значение в свою секцию, повесить onchange с сохранением
})
Сохранение своего ключа не через общий экшен обновления поля (он не пропускает произвольные ключи), а прямым обновлением конфига поля из своего экшена:
<?php
$model = new formkitFormFieldModel();
$field = $model->getById($fieldId); // config тут ещё JSON-строка
$config = json_decode($field['config'], true) ?: [];
$config['my_plugin_key'] = waRequest::post('value', '', 'string');
$model->updateById($fieldId, ['config' => json_encode($config, JSON_UNESCAPED_UNICODE)]); formkit_field_render
Срабатывает на публичной форме отдельно для каждого поля, перед тем как оно рендерится. Позволяет добавить свои data-* атрибуты в корневой элемент поля, например, сериализованные условия показа, которые потом читает JS плагина через formkit:render .
| Свойство | Тип данных | Описание |
|---|---|---|
| field | array | Поле формы (id, type, name, config — уже с применёнными дефолтами) |
| attrs | array | Заполняет обработчик — [имя_атрибута => значение], экранируются ядром автоматически при выводе |
attrs — единственный безопасный канал вывода на публичную страницу. Не пытайтесь передать туда готовый HTML, он будет показан как текст.
<?php
public function onFieldRender(&$params)
{
$conditions = $params['field']['config']['conditions'] ?? null;
if ($conditions) {
$params['attrs']['data-my-conditions'] = json_encode($conditions, JSON_UNESCAPED_UNICODE);
}
} Публичная точка входа
formkit_public_callback
Нужен, если плагину требуется публичный URL, доступный без сессии Webasyst. Типичный случай: OAuth-колбэк (внешний сервис возвращает браузер администратора с ?code=...&state=...) или вебхук от стороннего API. Собственный routing.php плагина для этого не годится, formkit даёт один универсальный публичный роут ( plugin-callback/<plugin_id>/<callback_id>/ ), на любой запрос по которому генерируется это событие.
| Свойство | Тип данных | Описание |
|---|---|---|
| plugin_id | string | Вход — сегмент <plugin_id> из URL |
| callback_id | string | Вход — сегмент <callback_id> из URL, удобно для нескольких разных колбэков |
| handled | bool | Заполняет обработчик — установите true, если колбэк ваш и вы его обработали. Если после события handled остался false, formkit отдаёт 404 |
<?php
class myAmoCrmPlugin extends waPlugin
{
public function handlePublicCallback(&$params)
{
if ($params['plugin_id'] !== 'myamocrm' || $params['callback_id'] !== 'redirect') {
return; // не наш колбэк — молчим
}
$params['handled'] = true;
$code = waRequest::get('code', '', 'string');
// обмен кода на токены, сохранение в saveSettings()
echo '<p>Готово, можно закрыть вкладку.</p>';
}
} Обработчик сам решает, что выводить — обычно echo HTML или header('Location: ...') с exit, formkit ничего не подмешивает после события.