Обработка форм и валидация

Svelte предоставляет простой и интуитивно понятный способ работы с формами и их элементами. Обработка форм в Svelte включает в себя несколько ключевых шагов: привязка данных, обработка событий, валидация и отправка данных.

Привязка данных к элементам формы

Основной механизм для работы с формами в Svelte — это привязка данных с использованием двусторонней привязки. Это позволяет синхронизировать значения элементов формы с состоянием компонента. Для привязки используется атрибут bind:.

Пример привязки данных к полям формы:

<script>
  let name = '';
  let email = '';
</script>

<form>
  <label for="name">Имя:</label>
  <input type="text" id="name" bind:value={name} />

  <label for="email">Email:</label>
  <input type="email" id="email" bind:value={email} />

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

<p>Имя: {name}</p>
<p>Email: {email}</p>

В этом примере значения полей name и email синхронизируются с переменными компонента через bind:value. Изменение значений полей автоматически обновляет состояние компонента и наоборот.

Обработка событий формы

Форма в Svelte может реагировать на различные события, такие как отправка формы или изменения в полях. Для обработки событий используется синтаксис on:event, где event — это тип события, например, submit, input или change.

Пример обработки события отправки формы:

<script>
  let name = '';
  let email = '';

  function handleSubmit(event) {
    event.preventDefault();
    console.log('Форма отправлена:', { name, email });
  }
</script>

<form on:submit={handleSubmit}>
  <label for="name">Имя:</label>
  <input type="text" id="name" bind:value={name} />

  <label for="email">Email:</label>
  <input type="email" id="email" bind:value={email} />

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

Метод handleSubmit срабатывает при отправке формы. Важно использовать event.preventDefault(), чтобы предотвратить стандартное поведение формы (перезагрузку страницы).

Валидация форм

Валидация данных формы — один из важнейших аспектов работы с формами. В Svelte валидацию можно реализовать как на уровне полей ввода, так и при отправке формы. Для этого можно использовать как встроенные HTML-атрибуты для валидации, так и написать собственные проверки.

Валидация с использованием HTML-атрибутов

HTML предоставляет ряд атрибутов для валидации данных, таких как required, minlength, pattern и другие. Эти атрибуты можно использовать непосредственно в элементе формы.

Пример с использованием атрибутов валидации:

<script>
  let name = '';
  let email = '';
</script>

<form on:submit|preventDefault>
  <label for="name">Имя:</label>
  <input type="text" id="name" bind:value={name} required minlength="2" />

  <label for="email">Email:</label>
  <input type="email" id="email" bind:value={email} required />

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

Здесь используется атрибут required, который заставляет пользователя заполнить поле перед отправкой формы, и minlength для проверки минимальной длины строки.

Кастомная валидация

Для более сложной валидации, например, проверки формата email или выполнения бизнес-логики, необходимо писать собственные функции. Эти функции можно вызывать перед отправкой формы, проверяя состояние данных.

Пример кастомной валидации:

<script>
  let name = '';
  let email = '';
  let error = '';

  function validateForm() {
    if (!name || !email) {
      error = 'Все поля обязательны для заполнения';
      return false;
    }
    if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) {
      error = 'Неверный формат email';
      return false;
    }
    error = '';
    return true;
  }

  function handleSubmit(event) {
    event.preventDefault();
    if (validateForm()) {
      console.log('Форма отправлена:', { name, email });
    }
  }
</script>

<form on:submit={handleSubmit}>
  <label for="name">Имя:</label>
  <input type="text" id="name" bind:value={name} />

  <label for="email">Email:</label>
  <input type="email" id="email" bind:value={email} />

  {#if error}
    <p class="error">{error}</p>
  {/if}

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

В этом примере функция validateForm проверяет, что оба поля заполнены, а также что email соответствует стандартному формату. Если валидация не проходит, выводится сообщение об ошибке.

Управление состоянием формы

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

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

Пример управления состоянием формы:

<script>
  let name = '';
  let email = '';
  let submitted = false;

  function handleSubmit(event) {
    event.preventDefault();
    submitted = true;
    console.log('Форма отправлена:', { name, email });
  }
</script>

<form on:submit={handleSubmit}>
  <label for="name">Имя:</label>
  <input type="text" id="name" bind:value={name} />

  <label for="email">Email:</label>
  <input type="email" id="email" bind:value={email} />

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

{#if submitted}
  <p>Форма успешно отправлена!</p>
{/if}

В этом примере флаг submitted переключается в true после отправки формы, и отображается сообщение об успешной отправке.

Обработка ошибок и сообщений об ошибках

Чтобы улучшить пользовательский опыт, важно отображать сообщения об ошибках непосредственно на форме. Это можно сделать с помощью условных блоков Svelte ({#if ...}) или с использованием стилизации, чтобы выделить элементы с ошибками.

Пример отображения ошибок:

<script>
  let name = '';
  let email = '';
  let nameError = '';
  let emailError = '';

  function handleSubmit(event) {
    event.preventDefault();
    nameError = '';
    emailError = '';

    if (!name) {
      nameError = 'Имя обязательно для заполнения';
    }
    if (!email) {
      emailError = 'Email обязателен';
    } else if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(email)) {
      emailError = 'Неверный формат email';
    }

    if (!nameError && !emailError) {
      console.log('Форма отправлена:', { name, email });
    }
  }
</script>

<form on:submit={handleSubmit}>
  <label for="name">Имя:</label>
  <input type="text" id="name" bind:value={name} />
  {#if nameError}
    <p class="error">{nameError}</p>
  {/if}

  <label for="email">Email:</label>
  <input type="email" id="email" bind:value={email} />
  {#if emailError}
    <p class="error">{emailError}</p>
  {/if}

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

В этом примере ошибки отображаются непосредственно под полями ввода с помощью условных блоков. Сообщения об ошибках отображаются, только если соответствующие поля не проходят валидацию.

Стилизация и улучшение UX

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

Пример стилизации ошибок:

<style>
  .error {
    color: red;
    font-size: 0.9em;
  }

  input:invalid {
    border: 2px solid red;
  }

  input:valid {
    border: 2px solid green;
  }
</style>

Стилизация позволяет выделять поля с ошибками, изменяя их обводку или добавляя дополнительные элементы, такие как значки или цвета.