HTML, пустой ответ и ошибка
Каждый запрос выполняется при новом открытии. Перед выбором следующего режима закройте тост. Обработка пустого ответа и ошибки показана в JavaScript.
Запрос ещё не отправлен.
Ожидание загрузки
HTML
<div id="toast-ajax-controls" class="d-flex flex-wrap gap-2">
<button type="button" class="btn btn-primary btn-sm" data-mode="success">Загрузить HTML</button>
<button type="button" class="btn btn-surface btn-sm" data-mode="empty">Пустой ответ</button>
<button type="button" class="btn btn-surface btn-sm" data-mode="error">Ошибка 503</button>
</div>
<p id="toast-ajax-status" role="status" class="mt-3">Запрос ещё не отправлен.</p>
<div id="toast-ajax" class="vg-toast bottom center" role="status" aria-live="polite" >
<div class="vg-toast-wrapper">
<div class="vg-toast-content"><div class="vg-toast-body"><span id="toast-ajax-body">Ожидание загрузки</span></div></div>
<div class="vg-toast-button"><button type="button" class="vg-btn-close" data-vg-dismiss="toast" aria-label="Закрыть уведомление"></button></div>
</div>
</div>
JavaScript
/**
* Описание: AJAX с явным target и состояниями ответа.
* Возможности: рабочий пример публичного API VGToast.
*/
import { VGToast } from 'vgapp';
function initToastDemo() {
const element = document.querySelector('#toast-ajax');
if (!element) return;
const status = document.querySelector('#toast-ajax-status');
const target = document.querySelector('#toast-ajax-body');
const instance = VGToast.getOrCreateInstance(element, {
enableClickToast: false, animation: {enable: false, delay: 0},
ajax: {route: '/api/toast/demo', target: '#toast-ajax-body', loader: true, once: false},
});
element.addEventListener('vg.toast.loaded', event => {
const failed = event.detail.stats === 'error';
if (failed) target.textContent = 'Не удалось загрузить уведомление. Повторите запрос.';
else if (!target.textContent.trim()) target.textContent = 'Новых уведомлений нет.';
status.textContent = failed ? 'Ошибка 503: можно повторить.' : 'Ответ получен: ' + event.detail.stats;
});
const controls = document.querySelector('#toast-ajax-controls');
controls.addEventListener('click', event => {
const button = event.target.closest('[data-mode]');
if (!button) return;
if (element.classList.contains('show')) {
status.textContent = 'Сначала закройте открытое уведомление.';
return;
}
button.setAttribute('data-ajax-route', '/api/toast/demo?mode=' + button.dataset.mode);
status.textContent = 'Загрузка…';
instance.show(button);
});
}
initToastDemo();
CSS
/* Композиция демо и публичные переменные VGToast. Тему переключает OKAUX. */
.page-module-toast .vg-toast {
--vg-toast-width: min(28rem, 100%);
--vg-toast-border-radius: var(--vg-radius-lg);
--vg-toast-background-color: var(--vg-bg-secondary);
--vg-toast-color: var(--vg-text-primary);
--vg-toast-border-color: var(--vg-border-default);
}
.page-module-toast .vg-toast-content { min-width: 0; overflow-wrap: anywhere; }
.module-toast-content { min-width: 0; }
.toast-demo-log { white-space: pre-wrap; overflow-wrap: anywhere; padding: 1rem; background: var(--vg-bg-secondary); border: 1px solid var(--vg-border-default); border-radius: var(--vg-radius-lg); }
.toast-demo-reference { overflow-wrap: anywhere; }
.toast-demo-reference dt { margin-top: 1rem; font-family: monospace; }
.toast-demo-reference dd { margin: .25rem 0 0; }