Skip to content

📚 pbMessage — универсальный вывод сообщений

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

✅ Зачем нужен

  • Позволяет автоматически показывать сообщения из JSON-ответов { success: true|false, message: "..." }.
  • Работает по умолчанию вместе с pbFetch — без ручного вывода.
  • Контролируется через кастомные события pb:success и pb:error — ты можешь отменить автоматический показ.
  • Даёт одну точку, где меняется вид сообщений на всём сайте: подставил свой обработчик — и вместо текста в блоке появились тосты или модалки.
  • Можно легко настроить CSS классы, куда вставлять сообщение и как его очищать.

⚙️ Как работает

🚦 Основная логика

js
pbMessage.success(ctx, message)
pbMessage.error(ctx, message)
pbMessage.clear(ctx)
  • ctx — это DOM-элемент, внутри которого ищется блок для вывода. Обычно это форма или элемент из pb-target.
  • pbMessage.success() ищет [pb-success-message], а если не нашёл — [pb-message].
  • pbMessage.error() ищет [pb-error-message], а если не нашёл — тот же [pb-message].
  • Если блок не найден — ничего не происходит.

ctx обязателен, и молча

Все три метода при пустом ctx просто выходят: ни сообщения, ни ошибки в консоли. Именно так выглядит самый частый «pbMessage не работает» — сообщение искать негде. pbFetch берёт контекстом форму элемента, а если формы нет — элемент из pb-target; когда нет ни того, ни другого, ctx равен null.

🏷️ Как разметить HTML

1️⃣ Один универсальный блок

html
<div pb-message class="d-none"></div>

2️⃣ Раздельные блоки для успеха и ошибки

html
<div pb-success-message class="d-none"></div>
<div pb-error-message class="d-none"></div>

✔️ Рекомендуется располагать эти блоки внутри формы или внутри таргета, чтобы pbMessage точно нашёл их по контексту.

📌 Пример разметки формы

html
<form id="my-form">
	<input type="text" name="name">
	<button
		type="submit"
		pb-post="/api/submit"
		pb-expect="json"
		pb-include="#my-form input"
	>
		Отправить
	</button>

	<!-- Лучше внутри формы -->
	<p pb-success-message class="text-success d-none"></p>
	<p pb-error-message class="text-danger d-none"></p>
</form>

Текст вставляется через innerHTML — простую разметку (<b>, <a>) сервер может прислать прямо в message. Значит и экранировать пользовательский ввод должен сервер.

🧩 Автоматическая интеграция с pbFetch

Сообщение показывается, когда сошлись три условия:

  1. запрос сделан с pb-expect="json" (для html сообщений нет вообще);
  2. в ответе есть непустое data.message;
  3. соответствующее событие не отменено.
js
// при response.ok
pbMessage.success(ctx, data.message)

// при HTTP-ошибке
pbMessage.error(ctx, data.message)

Ты можешь отменить автопоказ, добавив в обработчике:

js
document.addEventListener('pb:success', (e) => {
    e.preventDefault(); // сообщение не покажется автоматически
    // твоя логика
});

preventDefault() на pb:success отключает не только сообщение

На успешном ответе это событие сторожит весь разбор JSON: сообщение, редирект по data.redirect и подмену разметки из data.html. Отменяя показ сообщения, ты берёшь на себя и остальное. На pb:error отменяется только сообщение.

❓ Подтверждение действия

Атрибут pb-confirm у pbFetch вызывает pbMessage.confirmHandler(el, message) и отправляет запрос, только если тот вернул истину:

html
<button pb-delete="/cargo/12" pb-expect="json" pb-confirm="Удалить заказ?">
  Удалить
</button>

Штатный обработчик — это браузерный confirm(). Заменяется на свой так:

js
pbMessage.setConfirmHandler(async (el, message) => {
    const result = await Swal.fire({
        title: message,
        icon: 'question',
        showCancelButton: true,
        confirmButtonText: 'Да, удалить'
    });
    return result.isConfirmed;
});

Обработчик может быть async — его дождутся. Он должен вернуть true, чтобы запрос ушёл; исключение внутри обработчика отменяет запрос и пишется в консоль.

🎨 Настройка классов через конфиг и системные настройки

По умолчанию классы для сообщений подставляются из системных настроек:

  • pageblocks_msg_success — классы для успешного сообщения
  • pageblocks_msg_error — классы для ошибок
  • pageblocks_hidden_class — класс, который скрывает блок сообщений (например, d-none)

Пример значений из настроек:

plaintext
pageblocks_msg_success = "text-success"
pageblocks_msg_error = "text-danger,text-error"
pageblocks_hidden_class = "d-none"

Подставляет их не сам файл pb.message.v300.js, а компонент: событие OnWebPageInit при включённой настройке pageblocks_load_scripts дописывает на страницу вызов setConfig() с этими значениями. В самом классе прошиты только запасные значения:

js
pbMessage.config = {
  successClasses: ['text-success'],
  errorClasses: ['text-error', 'text-danger'],
  hiddenClass: 'd-none'
};

Классы — Bootstrap-овские; своих стилей PageBlocks для них не поставляет. На теме без Bootstrap задайте в настройках собственные.

Можно вручную переопределить через setConfig():

js
pbMessage.setConfig({
  successClasses: ['alert', 'alert-success'],
  errorClasses: ['alert', 'alert-danger'],
  hiddenClass: 'hidden' // например, TailwindCSS класс
});

Показывая сообщение, pbMessage снимает класс скрытия и классы противоположного типа, а затем вешает нужные. Поэтому один блок [pb-message] спокойно переключается с ошибки на успех и обратно.

🧹 Очистка сообщений

Если нужно убрать сообщение и сбросить классы:

js
pbMessage.clear(form);
// или pbMessage.clear(targetElement);

Метод проходит по всем трём атрибутам — [pb-success-message], [pb-error-message], [pb-message], — очищает текст, возвращает класс скрытия и снимает классы успеха и ошибки.

🔥 Полный API

МетодОписание
pbMessage.success(ctx, message)Показать успешное сообщение
pbMessage.error(ctx, message)Показать ошибку
pbMessage.clear(ctx)Очистить все сообщения и сбросить добавленные классы
pbMessage.setSuccessHandler(fn)Переопределить обработчик для успеха
pbMessage.setErrorHandler(fn)Переопределить обработчик для ошибок
pbMessage.setConfirmHandler(fn)Переопределить диалог подтверждения (pb-confirm)
pbMessage.setConfig({...})Задать CSS классы для успеха/ошибки (массивы классов)

Все три set*Handler() бросают TypeError, если передать не функцию.

✔️ Пример с использованием SweetAlert2

js
pbMessage.setSuccessHandler((ctx, message) => {
    Swal.fire({
        icon: 'success',
        title: 'Успех!',
        text: message
    });
});

pbMessage.setErrorHandler((ctx, message) => {
    Swal.fire({
        icon: 'error',
        title: 'Ошибка!',
        text: message
    });
});

Свой обработчик волен не смотреть на ctx вовсе — тосты и модалки живут поверх страницы, и тогда исчезает проблема «блока для сообщения нет в контексте».

© PageBlocks 2019-present