Валидация пользовательского ввода

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

Атрибуты и свойства для валидации

Каждый элемент сетки (виджет) в Gridstack представлен HTML-элементом с набором атрибутов:

  • gs-x, gs-y — координаты элемента в сетке по оси X и Y.
  • gs-w, gs-h — ширина и высота виджета в единицах сетки.
  • gs-min-w, gs-max-w, gs-min-h, gs-max-h — ограничения по размеру.

Эти атрибуты позволяют ограничивать размеры и позиции виджетов на уровне разметки. Значения должны быть целыми числами, соответствующими единицам сетки. Попытка задать недопустимые значения приведёт к автоматической корректировке Gridstack.

Методы для проверки корректности

Gridstack.js предоставляет несколько методов, которые помогают реализовать валидацию динамически:

  • isAreaEmpty(x, y, width, height) — проверяет, свободна ли область сетки для размещения нового виджета. Возвращает true, если место доступно.
  • canMove(node, x, y) — проверяет, можно ли переместить виджет node в координаты (x, y) без наложения на другие элементы.
  • willItFit(node, x, y, width, height) — предсказывает возможность размещения виджета с заданными размерами и координатами.

Использование этих методов позволяет предотвратить ошибки при добавлении, перетаскивании и изменении размеров виджетов.

События для валидации в реальном времени

Gridstack генерирует ряд событий, которые можно использовать для проверки пользовательского ввода до его окончательного применения:

  • dragstart, drag, dragstop — события перетаскивания. На этапе drag можно проверять новые координаты и предотвращать некорректные перемещения.
  • resizestart, resize, resizestop — события изменения размеров. Позволяют проверять, не превышает ли новый размер ограничений min/max.
  • added, change — события добавления новых элементов и изменения существующих, где можно реализовать финальную проверку данных перед сохранением состояния сетки.

Пример использования события drag для ограничения движения виджета только по оси X:

grid.on('drag', function(event, el, source) {
    const node = el.gridstackNode;
    if(node.x < 0) {
        node.x = 0;
    }
});

Пользовательские правила валидации

Для более сложных сценариев возможно создание собственных правил валидации. Например, ограничения по минимальному расстоянию между виджетами, запрет на перекрытие определённых зон или проверка соответствия размеров конкретным шаблонам. Это реализуется через комбинацию методов isAreaEmpty, willItFit и перехват событий drag/resize с последующим откатом изменений при нарушении правил.

Ограничения сетки и snap-to-grid

Gridstack поддерживает механизм привязки виджетов к сетке (cellHeight, verticalMargin, column). Настройка этих параметров облегчает валидацию, поскольку пользователь не может задать произвольные координаты и размеры:

const grid = GridStack.init({
    column: 12,
    cellHeight: 100,
    verticalMargin: 10,
    disableOneColumnMode: true
});

При этом любое перемещение или изменение размера виджета автоматически подстраивается под ячейки сетки, что снижает вероятность ошибок.

Проверка данных перед сериализацией

Перед сохранением состояния сетки (grid.save()) рекомендуется выполнять дополнительную валидацию всех виджетов:

grid.engine.nodes.forEach(node => {
    if(node.w < node.minW) node.w = node.minW;
    if(node.h < node.minH) node.h = node.minH;
});

Это гарантирует, что сохранённые данные будут корректными и пригодными для восстановления состояния сетки.

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

Валидация Gridstack может сочетаться с проверкой значений форм внутри виджетов. Например, можно запретить сохранение виджета, если текстовое поле пустое, или число превышает лимит. Для этого используется событие change или resizestop с проверкой содержимого:

grid.on('change', function(event, items) {
    items.forEach(item => {
        const input = item.el.querySelector('input');
        if(input && input.value.trim() === '') {
            alert('Заполните поле перед сохранением');
            grid.update(item.el, {x: item.x, y: item.y}); // откат позиции
        }
    });
});

Итоговый подход к валидации

  • Использование встроенных атрибутов gs-min-* и gs-max-* для базовой проверки размеров.
  • Методы isAreaEmpty, canMove, willItFit для контроля размещения.
  • Перехват событий drag, resize, change для динамической проверки изменений.
  • Комбинирование с пользовательскими правилами для сложных сценариев.
  • Проверка состояния перед сериализацией или сохранением, интеграция с формами и данными виджетов.

Такой подход позволяет создавать надёжные интерфейсы, предотвращающие ошибки пользователя и обеспечивающие предсказуемое поведение сетки при любых действиях с виджетами.