Валидация полей

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

В FAST Element каждое свойство, влияющее на визуальное состояние или логику компонента, объявляется с помощью @attr или @observable. Для валидации это особенно важно, так как изменение свойства может автоматически триггерить проверку и обновление интерфейса.

import { FASTElement, html, css, observable } from "@microsoft/fast-element";

export class ValidatedInput extends FASTElement {
  @observable value = "";
  @observable error = "";

  validate() {
    if (this.value.trim() === "") {
      this.error = "Поле обязательно для заполнения";
      return false;
    }
    if (!/^\w+@\w+\.\w+$/.test(this.value)) {
      this.error = "Неверный формат email";
      return false;
    }
    this.error = "";
    return true;
  }
}

Привязка к шаблону и реактивность

FAST Element использует двустороннюю привязку для свойств и шаблона через синтаксис ${} и директивы :value. Это позволяет автоматически отображать ошибки и состояние валидации:

const template = html<ValidatedInput>`
  <label>
    Email
    <input type="text" :value=${x => x.value} @input=${x => x.value = x.event.target.value}>
  </label>
  <span class="error" ?hidden=${x => !x.error}>${x => x.error}</span>
  <button @click=${x => x.validate()}>Проверить</button>
`;

const styles = css`
  .error {
    color: red;
    font-size: 0.9em;
  }
`;

Особенности привязки:

  • :value — реактивная привязка значения input к свойству компонента.
  • @input — событие, обновляющее свойство при вводе.
  • ?hidden — условное отображение ошибки.

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

Реактивные правила и кастомные валидаторы

FAST Element позволяет создавать пользовательские валидаторы, которые могут проверять поля по сложным правилам, включая асинхронные проверки, например, запрос к серверу для проверки уникальности логина:

async validateUniqueUsername(username) {
  const response = await fetch(`/api/check-username?username=${username}`);
  const result = await response.json();
  return result.available;
}

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

async validate() {
  if (this.value.trim() === "") {
    this.error = "Поле обязательно";
    return false;
  }

  const isUnique = await this.validateUniqueUsername(this.value);
  if (!isUnique) {
    this.error = "Имя пользователя уже занято";
    return false;
  }

  this.error = "";
  return true;
}

Композиция и повторное использование

В FAST Element удобно создавать обобщённые компоненты для валидации, которые можно использовать в разных формах:

import { FASTElement, html, observable } from "@microsoft/fast-element";

export class FormField extends FASTElement {
  @observable value = "";
  @observable error = "";

  validate(rules) {
    for (const rule of rules) {
      const error = rule(this.value);
      if (error) {
        this.error = error;
        return false;
      }
    }
    this.error = "";
    return true;
  }
}

const emailRules = [
  value => (!value ? "Обязательное поле" : ""),
  value => (!/^\w+@\w+\.\w+$/.test(value) ? "Неверный email" : "")
];

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

Взаимодействие с формами

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

const fields = [usernameField, emailField, passwordField];
const isFormValid = fields.every(field => field.validate());

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

Стилизация ошибок и визуальные индикаторы

FAST Element поддерживает условные классы и стили, которые позволяют выделять поля с ошибками:

const inputStyles = css`
  input {
    border: 1px solid #ccc;
    padding: 6px;
  }
  input.error {
    border-color: red;
  }
`;

Привязка классов через синтаксис ?className=${} делает визуальное состояние реактивным:

<input type="text" :value=${x => x.value} ?class.error=${x => x.error}>

Асинхронная валидация и UX

Асинхронные проверки лучше запускать с задержкой или после “blur”, чтобы не перегружать интерфейс и сервер:

<input type="text" :value=${x => x.value} @blur=${async x => await x.validate()}>

Это предотвращает постоянные запросы при каждом вводе и делает интерфейс отзывчивым.


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