Skip to Content

JavaScript

Flute CMS использует JavaScript для интерактивности. Основные библиотеки: HTMX, jQuery, Notyf.

Подключение скриптов

В теме

Создайте assets/scripts/app.js — он автоматически подключится в макете:

// assets/scripts/app.js document.addEventListener('DOMContentLoaded', () => { console.log('Theme loaded'); initMyFeatures(); }); function initMyFeatures() { // ваш код }

На конкретной странице

@push('scripts') <script> document.addEventListener('DOMContentLoaded', () => { // код для этой страницы }); </script> @endpush

Внешний файл модуля

@push('scripts') @at('Modules/Shop/Resources/assets/js/cart.js') @endpush

Уведомления (Notyf)

Глобальный объект notyf доступен на всех страницах.

Базовые уведомления

// Успех notyf.success('Сохранено!'); // Ошибка notyf.error('Произошла ошибка');

Расширенные опции

notyf.open({ type: 'success', // success, error, warning, info message: 'Сообщение', duration: 5000, // мс, 0 = не закрывать dismissible: true, // можно закрыть position: { x: 'right', // left, center, right y: 'top' // top, bottom } });

Примеры

// После сохранения формы $('form').on('submit', async function(e) { e.preventDefault(); try { await saveData(); notyf.success('Данные сохранены'); } catch (error) { notyf.error('Ошибка: ' + error.message); } });

Модальные окна

Открытие/закрытие

// Открыть openModal('modal-id'); // Закрыть closeModal('modal-id');

Через data-атрибуты

{{-- Открытие --}} <x-button data-modal-open="my-modal">Открыть</x-button> {{-- Закрытие изнутри модалки --}} <x-button data-modal-close="my-modal">Закрыть</x-button>

Программно с содержимым

// Открыть модалку и загрузить контент $('#my-modal .modal-body').load('/api/content', function() { openModal('my-modal'); });

События

// Модалка открыта window.addEventListener('open-modal', (e) => { console.log('Opened:', e.detail.modalId); }); // Модалка закрыта window.addEventListener('close-modal', (e) => { console.log('Closed:', e.detail.modalId); });

Tooltips

<!-- Базовый tooltip --> <button data-tooltip="Подсказка">Наведи</button> <!-- С позицией --> <button data-tooltip="Сверху" data-tooltip-placement="top">Наведи</button> <button data-tooltip="Снизу" data-tooltip-placement="bottom">Наведи</button> <button data-tooltip="Слева" data-tooltip-placement="left">Наведи</button> <button data-tooltip="Справа" data-tooltip-placement="right">Наведи</button> <!-- HTML контент через селектор --> <button data-tooltip="#tooltip-html">Сложный</button> <div id="tooltip-html" style="display:none"> <strong>Заголовок</strong> <p>Описание</p> </div>

Базовый

{{-- Кнопка --}} <button data-dropdown-open="user-menu"> Меню <x-icon path="ph.regular.caret-down" /> </button> {{-- Содержимое --}} <div data-dropdown="user-menu" class="dropdown"> <a href="/profile" class="dropdown__item"> <x-icon path="ph.regular.user" /> Профиль </a> <a href="/settings" class="dropdown__item"> <x-icon path="ph.regular.gear" /> Настройки </a> <hr class="dropdown__divider"> <a href="/logout" class="dropdown__item dropdown__item--danger"> <x-icon path="ph.regular.sign-out" /> Выйти </a> </div>

Hover dropdown

<button data-dropdown-open="menu" data-dropdown-hover="true"> Наведи </button>

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

HTMX подтверждение

<x-button hx-delete="/api/item/123" hx-flute-confirm="Удалить этот элемент?" hx-flute-confirm-type="error" hx-trigger="confirmed"> Удалить </x-button>

Типы

ТипЦветИспользование
errorКрасныйУдаление
warningЖелтыйПредупреждение
successЗеленыйПодтверждение
infoСинийИнформация
accentAccentОсновной

URL хелпер

// Полный URL u('/profile') // → https://site.com/profile u('api/users') // → https://site.com/api/users u() // → https://site.com/ // Пример использования fetch(u('api/users')) .then(r => r.json()) .then(data => console.log(data));

// Установить cookie setCookie('theme', 'dark', 365); // на 365 дней // Получить cookie const theme = getCookie('theme'); // Удалить cookie eraseCookie('theme');

Переключение темы

// Получить текущую тему const theme = document.documentElement.getAttribute('data-theme'); // 'light' или 'dark' // Переключить const newTheme = theme === 'light' ? 'dark' : 'light'; document.documentElement.setAttribute('data-theme', newTheme); setCookie('theme', newTheme, 365); // Или через событие window.dispatchEvent(new CustomEvent('switch-theme', { detail: { theme: 'dark' } }));

HTMX

Flute использует HTMX для динамических обновлений без перезагрузки страницы.

Базовые примеры

{{-- GET запрос --}} <button hx-get="/api/data" hx-target="#result"> Загрузить </button> <div id="result"></div> {{-- POST запрос --}} <form hx-post="/api/save" hx-target="#result"> <input name="title"> <button type="submit">Сохранить</button> </form> {{-- DELETE с подтверждением --}} <button hx-delete="/api/item/1" hx-target="closest .item" hx-swap="outerHTML" hx-flute-confirm="Удалить?"> Удалить </button>

Навигация без перезагрузки

<a href="/page" hx-boost="true" hx-target="#main" hx-swap="outerHTML transition:true"> Ссылка </a>

Атрибуты

АтрибутОписание
hx-getGET запрос
hx-postPOST запрос
hx-putPUT запрос
hx-deleteDELETE запрос
hx-targetКуда вставить результат
hx-swapКак вставить (innerHTML, outerHTML, beforeend…)
hx-triggerКогда выполнить (click, change, load…)
hx-boostSPA-like навигация

Реинициализация после HTMX

При динамической подгрузке контента нужно переинициализировать JS:

// После вставки нового контента htmx.on('htmx:afterSwap', (event) => { initMyComponents(); initTooltips(); initDropdowns(); }); // После любого запроса htmx.on('htmx:afterRequest', (event) => { // обновить счетчики, бейджи и т.д. });

Создание своего модуля

// assets/scripts/my-module.js class MyModule { constructor() { this.init(); } init() { this.bindEvents(); } bindEvents() { // Делегирование для динамического контента $(document).on('click', '.my-button', (e) => { this.handleClick(e); }); // Реинициализация после HTMX htmx.on('htmx:afterSwap', () => { this.refresh(); }); } handleClick(event) { event.preventDefault(); const $btn = $(event.currentTarget); // ... } refresh() { // переинициализация } } // Инициализация $(document).ready(() => { window.myModule = new MyModule(); });

Глобальные объекты

После загрузки страницы доступны:

app // FluteApp instance notyf // Notyf (уведомления) htmx // HTMX $ // jQuery

Полезные функции

// Дождаться загрузки DOM $(document).ready(() => { }); document.addEventListener('DOMContentLoaded', () => { }); // Делегирование событий (работает с динамическим контентом) $(document).on('click', '.selector', handler); // Debounce для поиска let timeout; $('#search').on('input', function() { clearTimeout(timeout); timeout = setTimeout(() => { // выполнить поиск }, 300); });