Динамические формы

Slim.js — это легковесная библиотека для построения компонентов в JavaScript с реактивным обновлением DOM. Одной из ключевых возможностей является создание динамических форм, где структура формы и данные могут изменяться на лету без полной перерисовки страницы.

В Slim.js формы строятся с помощью компонентов, каждый из которых может содержать внутреннее состояние и реактивные свойства.

class DynamicForm extends Slim {
    constructor() {
        super();
        this.fields = [
            { name: 'username', type: 'text', label: 'Имя пользователя' },
            { name: 'email', type: 'email', label: 'Email' }
        ];
        this.values = {};
    }
    
    submit() {
        console.log(this.values);
    }
}

Slim.tag('dynamic-form', DynamicForm);

В этом примере fields определяет набор полей формы, а values — объект для хранения введённых данных.


Реактивность и биндинг данных

Slim.js поддерживает двусторонний биндинг с помощью директивы bind. Это позволяет автоматически синхронизировать значение поля с состоянием компонента.

<input type="text" bind="values.username">
<input type="email" bind="values.email">

Изменение данных в объекте values мгновенно отражается в форме, и наоборот. Это особенно полезно для динамических форм, где поля могут добавляться или удаляться на основе условий.


Динамическое добавление и удаление полей

Форма может модифицировать свои поля во время работы, используя реактивные массивы. В Slim.js при изменении массива fields DOM обновляется автоматически.

addField() {
    this.fields.push({ name: 'phone', type: 'tel', label: 'Телефон' });
}

removeField(index) {
    this.fields.splice(index, 1);
}

Шаблон для динамических полей:

<div repeat="fields">
    <label>{{ label }}</label>
    <input type="{{ type }}" bind="values[name]">
    <button click="removeField($index)">Удалить</button>
</div>
<button click="addField">Добавить поле</button>
  • repeat — директива для рендеринга массива объектов.
  • $index — текущий индекс элемента массива, используется для удаления.

Валидация форм в Slim.js

Slim.js позволяет добавлять клиентскую валидацию через события change и submit. Для динамических форм это особенно важно, так как набор полей может меняться.

validateField(name) {
    if (!this.values[name] || this.values[name].trim() === '') {
        this.errors = { ...this.errors, [name]: 'Поле обязательно' };
    } else {
        const { [name]: removed, ...rest } = this.errors;
        this.errors = rest;
    }
}

В шаблоне ошибки можно отображать рядом с полем:

<div repeat="fields">
    <label>{{ label }}</label>
    <input type="{{ type }}" bind="values[name]" change="validateField(name)">
    <span if="errors[name]">{{ errors[name] }}</span>
</div>
  • if — условный рендеринг элемента.
  • errors — объект с ошибками, где ключи соответствуют именам полей.

Условное отображение полей

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

this.showExtra = false;

toggleExtra() {
    this.showExtra = !this.showExtra;
}
<div if="showExtra">
    <label>Дополнительная информация</label>
    <input type="text" bind="values.extra">
</div>
<button click="toggleExtra">Показать/Скрыть поле</button>

Изменение showExtra автоматически добавляет или убирает поле из DOM.


Работа с вложенными структурами

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

class AddressForm extends Slim {
    constructor() {
        super();
        this.address = { street: '', city: '' };
    }
}

Slim.tag('address-form', AddressForm);
<address-form bind="values.address"></address-form>
  • bind позволяет связать внутренние значения вложенного компонента с внешним состоянием формы.
  • Вложенные компоненты могут иметь собственные валидации и динамику полей.

Сбор и отправка данных

Динамическая форма собирает все значения автоматически в объект values. Отправка данных может происходить через метод submit:

submit() {
    fetch('/api/submit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(this.values)
    }).then(res => res.json())
      .then(data => console.log(data));
}

Вызов метода submit может быть привязан к кнопке формы:

<button click="submit">Отправить</button>

Ключевые моменты при работе с динамическими формами в Slim.js

  • Реактивность позволяет мгновенно отражать изменения состояния в DOM.
  • repeat и bind упрощают работу с массивами и вложенными объектами.
  • Динамическое добавление/удаление полей не требует ручного обновления DOM.
  • Условный рендеринг (if) и события позволяют управлять видимостью и валидацией полей.
  • Вложенные компоненты обеспечивают модульность и повторное использование формы.

Использование этих возможностей позволяет создавать сложные, интерактивные формы с минимальным количеством кода и высокой производительностью.