Кастомные валидаторы

Polymer предоставляет гибкий механизм работы с формами и валидацией данных, позволяющий создавать собственные правила проверки значений, выходящих за рамки стандартных HTML-атрибутов (required, pattern, minlength и т. д.). Основой для кастомной валидации является свойство validator у элементов формы и использование поведения Polymer.IronValidatableBehavior.


Подключение поведения IronValidatableBehavior

Для создания собственного валидатора необходимо подключить поведение IronValidatableBehavior, которое добавляет к элементу возможность проверки и управления состоянием валидности:

import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
import '@polymer/iron-validatable-behavior/iron-validatable-behavior.js';

class CustomInput extends Polymer.mixinBehaviors([Polymer.IronValidatableBehavior], PolymerElement) {
  static get template() {
    return html`
      <input value="{{value::input}}">
      <div hidden$="[[!invalid]]">Значение недопустимо</div>
    `;
  }

  static get properties() {
    return {
      value: {
        type: String,
        notify: true
      }
    };
  }

  validate(value) {
    // Здесь реализуется собственная логика проверки
    const isValid = /^[a-z]+$/i.test(value); // Только латинские буквы
    this.invalid = !isValid;
    return isValid;
  }
}

customElements.define('custom-input', CustomInput);

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

  • Свойство invalid управляет визуальной подсветкой ошибки.
  • Метод validate(value) возвращает true, если значение корректно, и false в противном случае.
  • Использование регулярных выражений позволяет гибко задавать правила проверки.

Регистрация валидатора для iron-form

Polymer предоставляет элемент iron-form, который позволяет собрать данные формы и выполнить массовую проверку валидаторов. Для интеграции кастомного валидатора с iron-form необходимо:

import '@polymer/iron-form/iron-form.js';

class FormExample extends PolymerElement {
  static get template() {
    return html`
      <iron-form id="form">
        <form>
          <custom-input name="username" value="{{username}}"></custom-input>
          <button type="submit">Отправить</button>
        </form>
      </iron-form>
    `;
  }

  ready() {
    super.ready();
    this.$.form.addEventListener('iron-form-submit', (e) => {
      console.log('Данные формы:', this.$.form.serializeForm());
    });
  }
}

customElements.define('form-example', FormExample);

В этом примере кастомный элемент с валидатором автоматически участвует в валидации при вызове this.$.form.validate().


Параметризация валидатора

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

static get properties() {
  return {
    minLength: {
      type: Number,
      value: 3
    },
    value: {
      type: String,
      notify: true
    }
  };
}

validate(value) {
  const isValid = value.length >= this.minLength;
  this.invalid = !isValid;
  return isValid;
}

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


Асинхронные валидаторы

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

validate(value) {
  return new Promise((resolve) => {
    setTimeout(() => {
      const isValid = value !== 'admin'; // Например, проверка уникальности имени
      this.invalid = !isValid;
      resolve(isValid);
    }, 500);
  });
}

iron-form поддерживает асинхронные валидаторы через метод validate(), если он возвращает Promise. При этом форма будет ожидать завершения всех проверок перед отправкой данных.


Советы по проектированию кастомных валидаторов

  • Разделение логики и отображения: валидация должна быть независима от визуальной части элемента. invalid управляет только состоянием ошибки.
  • Повторное использование: создавая параметризованные валидаторы, можно использовать один компонент для нескольких полей формы.
  • Поддержка асинхронности: для серверных проверок интеграция с Promise позволяет гибко управлять процессом валидации.
  • Комбинирование валидаторов: для сложных форм можно создавать цепочки валидаторов, вызывая несколько методов validate последовательно.

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

Состояние валидности удобно использовать для стилизации:

:host([invalid]) input {
  border: 2px solid red;
}

Эта простая техника позволяет визуально выделять некорректные поля без использования сторонних библиотек.


Кастомные валидаторы в Polymer обеспечивают гибкий и расширяемый механизм проверки данных, позволяя создавать сложные правила и поддерживать высокую повторяемость компонентов без нарушения принципов веб-компонентов.