Интеграция с внешними элементами

Gridstack.js предоставляет механизм интеграции элементов, которые изначально не принадлежат сетке. Такие элементы могут находиться в боковой панели, списке компонентов интерфейса или в другой области страницы и добавляться в сетку посредством перетаскивания. Подобная архитектура используется в конструкторах дашбордов, системах визуального проектирования интерфейсов и редакторах макетов.

Интеграция реализуется через стандартный механизм drag-and-drop, встроенный в Gridstack. Внешние элементы становятся источником перетаскивания, а сама сетка — зоной назначения.

Основные сценарии интеграции:

  • добавление новых виджетов в сетку из панели компонентов;
  • перемещение элементов между несколькими сетками;
  • перенос элементов из произвольных DOM-контейнеров;
  • динамическое создание сеточных элементов при drop-событии.

Подготовка внешних элементов

Для того чтобы внешний элемент мог быть перетащен в Gridstack, ему необходимо назначить соответствующий CSS-класс и атрибуты конфигурации.

Простейший пример панели элементов:

<div class="sidebar">
  <div class="grid-stack-item">
    <div class="grid-stack-item-content">
      Новый виджет
    </div>
  </div>
</div>

<div class="grid-stack"></div>

В этом случае элементы панели уже используют структуру grid-stack-item, что позволяет Gridstack автоматически распознавать их параметры.

Однако чаще используется специальный класс:

<div class="sidebar">
  <div class="widget-template">
    <div class="widget-content">График</div>
  </div>

  <div class="widget-template">
    <div class="widget-content">Таблица</div>
  </div>
</div>

Каждый элемент панели является шаблоном будущего виджета.


Инициализация сетки с поддержкой внешнего drag-and-drop

Для интеграции внешних элементов необходимо активировать режим acceptWidgets.

const grid = GridStack.init({
  acceptWidgets: true
});

Параметр acceptWidgets сообщает библиотеке, что сетка готова принимать внешние элементы.

Поддерживаются несколько вариантов значения:

Значение Описание
true принимать любые элементы
CSS-селектор принимать только указанные элементы
функция кастомная логика проверки

Пример ограничения по селектору:

GridStack.init({
  acceptWidgets: '.widget-template'
});

В этом случае сетка будет принимать только элементы с классом widget-template.


Активация drag-режима для внешних элементов

Gridstack предоставляет утилиту GridStack.setupDragIn, которая делает внешние элементы перетаскиваемыми.

GridStack.setupDragIn('.widget-template', {
  helper: 'clone'
});

Параметры метода:

Параметр Назначение
selector CSS-селектор внешних элементов
options настройки drag-поведения

Опция helper: 'clone' означает, что в сетку будет добавляться копия элемента, а оригинал останется в панели.

Это стандартная схема для конструкторов интерфейсов.


Минимальный пример интеграции

HTML:

<div class="sidebar">
  <div class="widget-template">
    Виджет
  </div>
</div>

<div class="grid-stack"></div>

Jav * aScript:

const grid = GridStack.init({
  acceptWidgets: '.widget-template'
});

GridStack.setupDragIn('.widget-template', {
  helper: 'clone'
});

После этого элемент из панели можно перетащить в сетку, где он автоматически станет grid-stack-item.


Использование атрибутов конфигурации

Размер и позиция создаваемого элемента могут задаваться через специальные data-атрибуты.

<div class="widget-template"
     gs-w="3"
     gs-h="2">
  График
</div>

Атрибуты:

Атрибут Назначение
gs-w ширина
gs-h высота
gs-x позиция по X
gs-y позиция по Y

Если координаты не указаны, Gridstack автоматически разместит элемент в первой доступной позиции.


Создание виджета через событие drop

При необходимости можно полностью контролировать процесс добавления элемента.

Gridstack генерирует событие dropped.

grid.on('dropped', function(event, previousWidget, newWidget) {
  console.log(newWidget);
});

Аргументы:

Параметр Описание
previousWidget исходный DOM-элемент
newWidget добавленный элемент сетки

Этот механизм используется для:

  • генерации сложной структуры DOM
  • загрузки данных
  • инициализации виджета
  • подключения сторонних библиотек

Пример динамической инициализации:

grid.on('dropped', function(event, prev, widget) {
  widget.querySelector('.grid-stack-item-content').innerHTML =
    '<canvas class="chart"></canvas>';

  initChart(widget);
});

Динамическая генерация элементов

Иногда внешний элемент используется только как триггер, а настоящий виджет создаётся программно.

grid.on('dropped', function(event, prev) {

  const node = {
    w: 4,
    h: 3,
    content: '<div class="chart-widget"></div>'
  };

  grid.addWidget(node);
});

В этом случае исходный элемент может быть удалён:

prev.remove();

Подобный подход используется в редакторах дашбордов, где панель содержит лишь типы компонентов.


Передача данных из панели элементов

Шаблоны часто содержат информацию о типе создаваемого виджета.

<div class="widget-template"
     data-type="chart">
  График
</div>

<div class="widget-template"
     data-type="table">
  Таблица
</div>

Получение данных:

grid.on('dropped', function(event, prev, widget) {

  const type = prev.dataset.type;

  if (type === 'chart') {
    createChart(widget);
  }

  if (type === 'table') {
    createTable(widget);
  }

});

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


Интеграция нескольких панелей компонентов

Gridstack позволяет использовать несколько источников элементов.

GridStack.setupDragIn('.charts-panel .widget', {
  helper: 'clone'
});

GridStack.setupDragIn('.tables-panel .widget', {
  helper: 'clone'
});

Сетка принимает все элементы, если они удовлетворяют параметру acceptWidgets.


Перетаскивание между несколькими сетками

Gridstack поддерживает перенос элементов между разными сетками.

HTML:

<div class="grid-stack grid-1"></div>
<div class="grid-stack grid-2"></div>

Jav * aScript:

GridStack.init({
  acceptWidgets: true
}, '.grid-1');

GridStack.init({
  acceptWidgets: true
}, '.grid-2');

Теперь элементы можно перемещать между сетками.

Это используется в:

  • редакторах страниц
  • системах компоновки дашбордов
  • визуальных CMS

Ограничение типов принимаемых элементов

Сетка может фильтровать допустимые виджеты.

GridStack.init({
  acceptWidgets: function(el) {
    return el.dataset.type !== 'restricted';
  }
});

Функция возвращает true или false.

Подобная логика применяется, когда:

  • разные сетки принимают разные компоненты;
  • определённые элементы доступны только администраторам;
  • требуется проверка прав доступа.

Настройка внешнего helper-элемента

Во время перетаскивания используется специальный элемент-превью.

GridStack.setupDragIn('.widget-template', {
  helper: function(el) {
    const clone = el.cloneNode(true);
    clone.style.width = '200px';
    return clone;
  }
});

Кастомный helper позволяет:

  • менять внешний вид превью;
  • отображать placeholder;
  • добавлять визуальные подсказки.

Интеграция с пользовательскими интерфейсами

В реальных проектах панель компонентов обычно представляет собой полноценный UI-модуль.

Типичная структура:

sidebar
 ├── charts
 ├── tables
 ├── widgets
 └── media

Каждая группа содержит собственные шаблоны.

Gridstack подключается только к тем элементам, которые должны быть перетаскиваемыми.

GridStack.setupDragIn('.sidebar .widget');

Управление placeholder-элементом

Во время drag-операции Gridstack показывает временный placeholder.

Его внешний вид можно изменить через CSS.

.grid-stack-placeholder {
  background: rgba(0,0,0,0.1);
  border: 2px dashed #666;
}

Placeholder помогает пользователю визуально понимать, где будет размещён элемент.


Интеграция с асинхронной загрузкой данных

После добавления виджета может выполняться запрос к серверу.

grid.on('dropped', async function(event, prev, widget) {

  const data = await fetch('/widget-data').then(r => r.json());

  renderWidget(widget, data);

});

Это позволяет:

  • загружать реальные данные для дашборда;
  • получать конфигурацию виджета;
  • синхронизировать интерфейс с сервером.

Использование шаблонов HTML

Часто структура виджета хранится в <template>.

<template id="chart-template">
  <div class="grid-stack-item-content">
    <canvas class="chart"></canvas>
  </div>
</template>

При drop-событии:

grid.on('dropped', function(event, prev, widget) {

  const template = document.getElementById('chart-template');

  widget.innerHTML = template.innerHTML;

});

Этот подход упрощает поддержку сложных интерфейсов.


Типичная архитектура конструктора дашбордов

Интеграция внешних элементов обычно строится по следующей схеме:

  1. Панель компонентов содержит шаблоны виджетов
  2. Gridstack управляет сеткой размещения
  3. Drag-операция переносит элемент из панели
  4. Событие dropped создаёт полноценный виджет
  5. Виджет инициализирует логику приложения

Такой подход обеспечивает:

  • модульность компонентов
  • динамическое расширение интерфейса
  • поддержку drag-and-drop без дополнительного кода
  • удобную интеграцию с фреймворками и backend-логикой

Gridstack выступает только механизмом компоновки, тогда как логика виджетов полностью контролируется приложением.