Skip to content

Latest commit

 

History

History
275 lines (155 loc) · 17.7 KB

BLOCKS.md

File metadata and controls

275 lines (155 loc) · 17.7 KB

form blocks draft

Форма — абстракция над набором полей, контролов, валидацией. В браузере привязывается к dom-элементу form и управляет её поведением.

Поле — абстрактное понятие, описывающее основной элемент формы. В обычном виде возвращает строку, но может так же не возвращать значение, или возвращать объект или массив. При отстутсвии имени (getName) считается, что поле виртуальное и не должно участвовать в выходных данных формы. Обычно расширяется модификатором type.

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

Метка — используется только в браузере, привязывается к полям формы.

Сообщение (об ошибке) - Специальный блок, описывающий скрытый элемент, который включается в верстку только с модификатором form_validity. Имеет простой интерфейс для размещения в нем текстовой ошибки ввода, скрывается при сбросе. Управляется исключительно извне (из формы).

Common API

Блок form

extends BEM mixes form__core

Базовый функционал формы — получить объект со значениями, заполнить другими значениями.

form.browser.js

Методы экземпляра
  • {BEMDOM} _onSubmit({Function} fn) - добавляет обработчик на событие отправки формы, chainable
События
  • submit({target : Form}) - зовется при отправке формы;
  • focus({target : FormControl}) - событие прихода фокуса в контрол;
  • blur({target : FormControl}) - событие ухода;
  • change({target : FormControl}) - событие смены значения в контроле.
Параметры
  • {String} action - устанавливает целевой url формы;
  • {String} method - устанавливает используемый при отправке метод;
  • {String} contentType - по-умолчанию, urlencoded, может быть одним из urlencoded, form-data, plain. При выставлении — форсирует выставление атрибута method в значение POST.

form.node.js

Методы экземпляра
  • ? {BEM} setVal({Object} val) - заполняет поля формы новыми значениями, chainable. Например, form.setVal(req.body).checkValidation()

Микс form__core

mix, extends BEM

Описывает общие методы form для browser.js и node.js. Вынесен отдельно и миксуется, ибо нет множественного наследования (и не надо).

Методы экземпляра
  • {Object} form.getVal() - возвращает данные полей (или контролов) в нормализованном виде;
  • {Array.<FormTuple>} getFields() - возвращает массив полей;
  • {?FormTuple} getField({String} name) - возвращает поле по имени или null.

Модификатор form_ajax

Отменяет отправку формы обычным способом и вместо этого начинает отправку асинхронно с помощью XMLHttpRequest, ?FileReader API, ?FormData API или ?iframe (для отправки файлов в старых браузерах).

? Стоит ли вынести в абстрактный блок/модуль работу с fileReader/formData?

Элемент form__tuple

extends BEM

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

Методы экземпляра
  • {String} getName() - возвращает имя поля. Если имя приходит пустое — в результат getVal формы оно не попадает.
  • {*} getVal() - возвращает значение, может быть чем угодно (см. [form__field])
  • {BEM} setVal({*} val) - устанавливает значение поля, chainable

Блок label

Блок метки, привязывается к [form__control], [form__field] или [input], [attach], [textarea], etc.

Элемент label__hint

Вспомогательный элемент метки, описывающий подсказку.

Параметры
  • {String} for - имя контрола, к которому привязывается label.

Элемент form__control

extends form__tuple

Заготовка для контрола (?), содержит в себе ровно один элемент ввода (типа [input], [attach], [textarea], etc.)

? Основная его цель — подключать стандартные элементы ввода к форме, чтобы мочь собирать значения, валидировать, ...

Не может использоваться без модификатора type

Модификатор _type_X

Контрол типа X, где X, по умолчанию, это один из базовых [input], [attach], [textarea], etc.

Validation API

Блок validators

Блок для хранения валидаторов, расширяется модификаторами через базовое API.

Статические методы
  • {Validation} register({String} name, {function(this: Validation, {*} val, {?Object} params)} fn) - регистрируем валидатор
  • {?Boolean} run({String} name, {*} val, {?Object} params) - проверяем значение val с помощью валидатора name. Возвращаемое значение может быть true (проверка успешно пройдена), false (не пройдена) и null (в случаях, если валидатор не найден или в нем произошла ошибка).

Модификатор _required

Регистрирует валидатор required, который проверяет на наличие любого ненулевого значения

Модификатор _email

Регистрирует валидатор email, который проверяет на значение на соотв. регулярному выражению /^.+@.+$/

Модификатор _numbers

Регистрирует валидатор numbers, который проверяет значение, чтобы оно состояло из цифр и знака разделителя десятичной части

Есть возможно передать точность числа, кол-во десятичных цифр, и т.д. в поле js.

Параметры
  • {Number} min - ограничение снизу числового значения
  • {Number} max - ограничение сверху числового значения
  • {String} decimalSeparator - разделитель десятичной части
  • {Number} precision - ограничение кол-ва цифр в десятичной части

Модификатор _money

Используя функционал _numbers, дополнительно проверяет, что поле конкретно бабло (?)

Модификатор _pattern

Проверяет, что значение соответствует некоторому выражению.

Требует передачи этого выражения в поле js.

Параметры
  • {String} pattern - регулярное выражение, которому должно соответствовать значение

Модификатор _card

Регистрирует валидатор card, который проверяет значение на длину (16 или 18), на отстутствие нециферных знаков, на прохождение алгоритма luhn и на принадлежность номера карты одному из провайдеров (visa, mc, etc.) - ? описать все, которые нам нужны

Параметры
  • {String|Array.<String>} cardTypes - дополнительно проверяет, чтобы карта была выпущена указанным (?)центром

Блок validate

extends BEMDOM

Вешается на поле или контрол и служит для автоматической проверки значения элемента ввода, расчитан на использование вместе с [input], [attach], [textarea], etc. Может быть полезен в создании пользовательских форм.

? Т.е. крепится к чему угодно, где есть пользовательский ввод — пока не до конца понятно про все инпуты/селекты/аттачи, какой интерфейс должен быть реализован в элементах ввода, и где мы его описываем.

Methods
  • {?Boolean} run() (или checkValidation()?) - запускает проверку и выставляет модификатор на target блок с результатами проверки
Параметры
  • {String} target - строковое название блока, на который крепится элемент. Блок должен реализовывать некоторый интерфейс, чтобы все работало (?) - нужно его описать

Кроме вышеописанных параметров здесь же можно передать параметры для используемых валидаторов:

{
  js: {target: 'input', numbers: {precision: 3, decimalDelimiter: ','}}
}

Модификатор form_validity extends Form

Расширение основного функционала блока формы прохождением валидации при изменении полей и отправке формы.

Зависит от блока [validation].

Методы экземпляра
  • {BEM} onSubmit() - перегрузка сабмита, приостанавливается до положительного разрешения промиса из checkValidity()
  • {Promise} checkValidity() - Таки промис или не промис? Ведь капчу тоже хочется проверять, как же без капчи?
Модификатор _state или _vaildation?
  • form_state_unchecked - выставляется при инициализации form_validity
  • form_state_processing (validating?) — состояние, описывающее процесс затяжной валидации, выставляется после вызова checkValidity и стоит до разрешения промиса;
  • form_state_valid — состояние, когда каждое из полей прошло проверку, либо ни одно из них её не требует;
  • form_state_invalid — состояние формы, когда есть поля, которые требует проверки, и любое из них её не прошло;

Блок message extends BEMDOM

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

Пивязывается к [form], [form__field], [form__control], в него можно складывать ошибку валидации, прячется если пользователь начал ввод, и вновь отображается при ошибках проверки.

Методы экземпляра
  • {BEMDOM} setMessage({String} val) - выставляет переданную ошибку и отображает блок;
  • ? {BEMDOM} reset() - удаляет ошибку и прячет блок;
  • ? {String} getMessage() - возвращает текущую ошибку;
  • ? {String} dropMessage() - удаляет ошибку, прячет блок и возвращает удаленную ошибку.

Модификатор _visible

Выставляется при наличии ошибки и намекает браузеру, что пора отобразить блок, и удаляется при её сбросе.

Fields (draft)

Блок form_fields

  • Натравливает форму на использование form__field (browser.js);
  • Дополнительно привязывает метки;
  • ? Если одному из полей нужна валидация — форма должна выставить себе модификатор _validity;
Methods
  • {Array.<FormField>} getFields()
  • {FormField} getField()
  • {Object} getVal()
  • ? {BEMDOM} addField({{name: String, type: String, val: *, after: String|FormTuple, }}) - добавляем поле в форму, тип должен быть заранее подгружен в зависимостях (для browser.js нужны шаблоны на клиенте)
  • ? {BEMDOM} removeField({FormField|FormControl}) - удаляем поле из формы

Элемент form__field

Базовый функционал элемента формы. Добавляет метку, если она указана.

Может включать в себя {0..n} контролов, комбинировать их вывод, инициализировать ввод, делать пре/пост процессинг данных из контролов, аггрегировать данные из других полей формы, и т.д. Все решается в контретных реализациях.

Модификации form__field_type_X

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

Согласно типу, поле:

  • генерирует внутри себя нужные контролы;
  • навешивает на себя валидации всех внутренних контролов и выводить только одну ошибку для поля целиком (вместо нескольких ошибок, по одной для каждого контрола);
  • перенаправляет события из формы в контролы по своему усмотрению, и аналогично назад;
  • дописывает в нужное место блок message для вывода ошибки;

Т.е. позволяет описать внутреннюю логику поля формы, включая валидацию, возвращаемое значение, и т.д.

Получается, что для контрола form__field должен выглядеть как форма, и для формы — как контрол.

Примеры
_type_price

Cостоит из формы ввода для суммы и селектора валют, в особо тяжелых случаях может еще отображать введенную сумму в рублях при пересчете по курсу ЦБ. Пример значения: {currency: 'euro', amount: '152.12'}.

_type_coord

Состоит из 2х скрытых форм ввода (input type=hidden) и гео-карты, с помощью которой позволяет выбирать произвольную гео-точку. Пример значения: {lat : 55.4507, long : 37.3656}.

_type_nested-leafs

Позволяет выбирать любое кол-во конечных элементов (листьев) в произвольной заранее известной древовидной структуре. Имеет логику отрисовки подветок на клиенте, и т.д. Пример значения: [4, 2, 42]

_type_tags

Позволяет выбирать теги из облака. Пример значения: ['bem', 'rocks']