Gridstack.js предоставляет мощный инструмент для создания динамических, перетаскиваемых сеток в веб-приложениях. Одной из ключевых возможностей является синхронизация состояния сетки с серверным хранилищем, что позволяет сохранять пользовательские настройки, восстанавливать расположение виджетов и поддерживать актуальность данных между сессиями.
Gridstack.js использует JSON-структуры для представления состояния сетки. Каждая карточка (widget) описывается объектом со следующими свойствами:
x — горизонтальная позиция (колонка) в сеткеy — вертикальная позиция (ряд)width (w) — ширина виджета в ячейкахheight (h) — высота виджета в ячейкахid — уникальный идентификатор виджетаcontent или type, для хранения специфической
информацииПример структуры JSON для трех виджетов:
[
{ "id": "widget1", "x": 0, "y": 0, "w": 2, "h": 2, "content": "График продаж" },
{ "id": "widget2", "x": 2, "y": 0, "w": 2, "h": 3, "content": "Таблица заказов" },
{ "id": "widget3", "x": 0, "y": 2, "w": 4, "h": 2, "content": "Календарь событий" }
]
Для отслеживания изменений в сетке Gridstack.js предоставляет набор событий:
change — вызывается при любом изменении положения или
размера виджетаadded — при добавлении нового виджетаremoved — при удалении виджетаЭти события можно использовать для отправки обновленных данных на сервер.
const grid = GridStack.init({/* настройки сетки */});
grid.on('change', function(event, items) {
const layout = grid.save(); // получает текущий JSON-состояние
fetch('/api/saveLayout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(layout)
});
});
В примере выше grid.save() возвращает массив всех
виджетов с их координатами и размерами, который затем отправляется на
сервер методом POST.
Для восстановления состояния сетки при загрузке страницы используется
метод load():
fetch('/api/getLayout')
.then(response => response.json())
.then(data => {
grid.load(data); // восстанавливает расположение виджетов
});
Важно обеспечить уникальные идентификаторы виджетов
(id), чтобы Gridstack мог корректно соотнести серверные
данные с конкретными элементами DOM.
При динамическом добавлении виджетов через интерфейс необходимо:
id для нового виджета.grid.addWidget():const node = { id: 'widget4', x: 0, y: 0, w: 2, h: 2, content: 'Новый график' };
grid.addWidget(`<div id="${node.id}">${node.content}</div>`, node);
grid.on('added', function(event, items) {
const layout = grid.save();
fetch('/api/saveLayout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(layout)
});
});
Удаление виджетов аналогично: используется событие
removed и метод
grid.removeWidget(element).
version к JSON позволяет управлять конфликтами при
одновременном редактировании сетки несколькими пользователями.let saveTimeout;
grid.on('change', function() {
clearTimeout(saveTimeout);
saveTimeout = setTimeout(() => {
fetch('/api/saveLayout', { method: 'POST', body: JSON.stringify(grid.save()) });
}, 300);
});
Gridstack.js универсален и может интегрироваться с любыми бекенд-сервисами, поддерживающими HTTP-запросы и JSON:
Пример обработки на Node.js + Express:
app.post('/api/saveLayout', (req, res) => {
const layout = req.body;
database.saveLayout(layout) // функция сохранения в БД
.then(() => res.send({ status: 'ok' }))
.catch(err => res.status(500).send({ error: err.message }));
});
Помимо координат и размеров, в серверное хранилище можно передавать:
Для этого достаточно расширять JSON-объект виджета дополнительными ключами:
{ "id": "widget1", "x": 0, "y": 0, "w": 2, "h": 2, "content": "График продаж", "color": "#3498db", "filters": { "region": "EU" } }
id для виджетов.change, added, removed).grid.load().Эти подходы позволяют строить динамические, персонифицированные интерфейсы, полностью синхронизированные с серверным хранилищем и готовые к работе в много-пользовательских сценариях.