Обработка отправки формы

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

Связывание формы с данными компонента

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

Пример:

import Slim from 'slim-js';

class ContactForm extends Slim {
  name = '';
  email = '';
  message = '';

  submitForm(event) {
    event.preventDefault();
    console.log('Отправка данных:', {
      name: this.name,
      email: this.email,
      message: this.message
    });
  }

  template() {
    return `
      <form onsub mit="submitForm(event)">
        <label>
          Имя:
          <input type="text" bind="name" />
        </label>
        <label>
          Email:
          <input type="email" bind="email" />
        </label>
        <label>
          Сообщение:
          <textarea bind="message"></textarea>
        </label>
        <button type="submit">Отправить</button>
      </form>
    `;
  }
}

Slim.define('contact-form', ContactForm);

Ключевые моменты:

  • Атрибут bind="property" автоматически связывает значение поля ввода с соответствующим свойством компонента.
  • Метод submitForm вызывается при событии onsubmit. event.preventDefault() предотвращает стандартное поведение браузера (перезагрузку страницы).
  • Данные формы доступны через свойства класса и могут быть отправлены на сервер или использованы внутри компонента.

Использование событий для обработки формы

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

<form onsub mit="handleSubmit(event)">
  <input type="text" bind="name" onin put="validateName()" />
</form>

Метод validateName может проверять ввод пользователя в реальном времени, изменяя состояние компонента:

validateName() {
  if(this.name.length < 3) {
    this.errorMessage = 'Имя должно быть не меньше 3 символов';
  } else {
    this.errorMessage = '';
  }
}

Асинхронная отправка данных

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

async submitForm(event) {
  event.preventDefault();

  const payload = {
    name: this.name,
    email: this.email,
    message: this.message
  };

  try {
    const response = await fetch('/api/contact', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(payload)
    });
    const result = await response.json();
    this.statusMessage = result.message;
  } catch (error) {
    this.statusMessage = 'Ошибка при отправке формы';
    console.error(error);
  }
}

Особенности работы с асинхронностью:

  • Свойство statusMessage можно отобразить в шаблоне для информирования пользователя.
  • Slim автоматически обновляет DOM при изменении свойств компонента, что делает реактивную обработку форм простой и удобной.

Валидация и реактивное обновление интерфейса

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

get isFormValid() {
  return this.name && this.email.includes('@') && this.message.length > 0;
}

Это свойство можно использовать в шаблоне для включения или отключения кнопки отправки:

<button type="submit" disabled="{{!isFormValid}}">Отправить</button>

Slim.js автоматически отслеживает изменения зависимых свойств и обновляет интерфейс без необходимости писать дополнительный код для обновления DOM.

Работа с несколькими формами

В случае, если на странице несколько форм, каждая форма может быть оформлена как отдельный компонент Slim.js. Это обеспечивает изоляцию состояния и уменьшает вероятность ошибок:

class LoginForm extends Slim {
  username = '';
  password = '';

  login(event) {
    event.preventDefault();
    // обработка авторизации
  }

  template() {
    return `
      <form onsub mit="login(event)">
        <input type="text" bind="username" />
        <input type="password" bind="password" />
        <button type="submit">Войти</button>
      </form>
    `;
  }
}

Slim.define('login-form', LoginForm);

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