oscript-ui
oscript-ui

Поле формы

Поле формы принимает от человека значение: строку, число, пароль, выбор из списка, отметку флажком, несколько значений списком или цвет. Внешне это залитое текстовое поле Material 3 с подписью внутри и линией снизу.

Когда использовать#

  • Человек вводит значение, которое уйдёт на сервер с формой.
  • Нужно выбрать один вариант из списка, где вариантов больше двух-трёх.
  • Нужно отметить согласие или признак, который можно включить, — флажком.
  • Значений несколько и они короткие (маски, коды, метки) — списком плашек.
  • Нужен цвет: акцент, метка, подсветка — полем цвета с образцами.

Не берите поле для «включено — выключено» в настройках: для этого есть тумблер. Для отбора списка — форма отбора. Значение, заданное конфигурацией и не правимое в интерфейсе, показывает поле из конфига.

В дереве холста поле собирается словами: имя и метка позицией, тип — словом .ТипЗначения(…) значением системы типов или выводится из .Значение(…) (см. Язык узлов).

Узлом холста — словами

HTML = Кит.Холст( Кит.Поле("имя", "Имя проекта").Значение("main").Подсказка("латиница и дефис"), Кит.Поле("лимит", "Лимит, МБ").ТипЗначения(Тип("Число")), Кит.Поле("скрыт", "Скрыть из списка").Значение(Истина)).Рендер();

Как оно выглядит#

Поле — контейнер surface-container-highest высотой 44 пикселя, скруглённый на 8 пикселей по всем углам, в рамке 1 пиксель цвета outline — роли Material для рамки поля: она отличается от заливки поля и от карточки не меньше чем в 3 раза по контрасту в обеих темах при любом акценте, и поле видно на любой поверхности. Подпись (Метка) лежит внутри контейнера. В фокусе рамка становится 2 пикселя цветом primary, а подпись окрашивается им же; у поля с отказом рамка цвета ошибки.

Подпись плавает. У пустого поля без фокуса она стоит на месте значения во весь кегль, у заполненного или в фокусе — уменьшается и поднимается к верхнему краю. Пустоту отмечает скрипт кита атрибутом data-empty: он следит за вводом, сбросом формы и автозаполнением. Без скрипта атрибута нет, и подпись всегда стоит наверху — законченный вид, а не сломанный.

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

Подсказка и Ошибка — вспомогательный текст под контейнером, с отступом 16 пикселей.

Пояснение длиннее строки — полем Справка (у узла — словом .Справка(Текст)): значок «?» в строке подписи открывает поповер с текстом, а поле ссылается на него из aria-describedby. Подробно — Подсказка.

Текст с подсказкой

HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Значение, Подсказка", "имя", "Имя проекта", "main", "латиница и дефис"));

Пустое поле с примером значения — пример виден в фокусе

HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Плейсхолдер", "почта", "Почта для уведомлений", "имя@пример.рф"));

Источник значения#

Откуда взялось значение — умолчание, ключ конфигурации, переменная окружения — говорит слово .Источник(Текст) (поле Источник модели, то же слово у поля объявленной формы). Источник печатается мелкой приглушённой надписью справа в строке подсказки (field__origin), а на телефоне переносится под подсказку. Без подсказки строка под полем печатается с одним источником. Поле без слова — прежнее, байт в байт.

Подсказка слева, источник справа

HTML = Кит.Поле("host", "Почтовый сервер").Значение("smtp.example.org") .Подсказка("Адрес SMTP для исходящих писем") .Источник("по умолчанию · mail.host").Рендер();

Источник без подсказки

HTML = Кит.Поле("port", "Порт").Значение(587).Источник("из окружения · MAIL_PORT").Рендер();

Типы#

Тип выбирает управление: «текст» (по умолчанию), «пароль», «число», «многострочное», «выбор», «флажок», «файл», «список», «цвет». Любой другой допустимый type HTML уходит как есть: email, url, date. Тип подбирает клавиатуру телефона и проверку браузера, поэтому выбирайте его по смыслу значения. В дереве холста тип задаёт слово .ТипЗначения(…): Тип("Число"), Тип("Булево"), Тип("Дата") или прежняя строка типа.

Пароль — с подсказкой менеджеру паролей

HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Тип, Автозаполнение", "пароль", "Пароль", "пароль", "new-password"));

Автозаполнение печатается атрибутом autocomplete. Без него менеджер паролей подставит в форму нового пароля старую пару.

Число

HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Тип, Значение", "лимит", "Лимит, МБ", "число", "0"));

Дата — тип HTML как есть

HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Тип", "срок", "Срок", "date"));

Многострочное#

Многострочное поле — <textarea> высотой от двух строк, которое человек растягивает вниз. Берите его для описаний и комментариев.

Многострочное

HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Тип, Значение", "описание", "Описание", "многострочное", "текст"));

Выбор#

Выбор — выпадающий список со своим шевроном справа. Варианты — массив структур Значение, Подпись; выбран тот, чьё значение совпало со Значением поля, или тот, у кого стоит Выбрано.

Выбор

Варианты = Новый Массив(); Варианты.Добавить(Новый Структура("Значение, Подпись", "локальный", "Локальный")); Варианты.Добавить(Новый Структура("Значение, Подпись", "внешний", "Внешний")); HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Тип, Значение, Варианты", "тип", "Тип проекта", "выбор", "внешний", Варианты));

Вариант с пустым значением допустим: он означает «не выбрано» или «все». value у варианта печатается всегда, поэтому пустой вариант приезжает на сервер пустой строкой, а не своей подписью.

Выбор с пустым вариантом

Варианты = Новый Массив(); Варианты.Добавить(Новый Структура("Значение, Подпись", "", "Все события")); Варианты.Добавить(Новый Структура("Значение, Подпись", "доступ.выдан", "Доступ: выдан")); Варианты.Добавить(Новый Структура("Значение, Подпись", "доступ.отозван", "Доступ: отозван")); HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Тип, Варианты", "событие", "Событие", "выбор", Варианты));

Флажок#

Флажок — коробка 18 пикселей слева и подпись справа обычным текстом: плавающей подписи у него нет. Отмеченный заливается цветом primary. Подсказка встаёт под подписью, а не сбоку.

Флажок

HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Тип, Отмечено", "скрыт", "Скрыть из списка", "флажок", Истина));

Флажок с подсказкой

HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Тип, Подсказка", "рассылка", "Присылать сводку по почте", "флажок", "раз в неделю, по понедельникам"));

Отмеченный флажок отправляет Значение, а если оно пусто — «1». Снятый не отправляет ничего; если серверу нужен явный «0», берите тумблер.

Список#

Список — несколько коротких значений в одном поле: маски файлов, коды стран, ключевые слова. Значения стоят плашками с крестиком, а за ними — строка ввода, всё в одной рамке поля. Enter или запятая превращает набранное в плашку, крестик её снимает, Backspace в пустой строке снимает последнюю. Ушёл из строки с набранным — оно тоже становится плашкой, поэтому последнее значение не теряется при отправке.

Серверу уходит одна строка через запятую под именем поля — скрытым полем. Без скрипта это обычное текстовое поле с той же строкой: человек правит её руками, и форма уходит так же. Значение задаётся строкой через запятую или массивом строк; пустые части и повторы отбрасываются и на экране, и при разборе.

Список — слово Список()

Enter или запятая добавляет маску
HTML = Кит.Поле("маски", "Маски файлов").Список() .Значение("*.os, *.bsl, *.json") .Подсказка("Enter или запятая добавляет маску").Рендер();

Массив значений сам делает поле списком — слово Список() тогда не нужно:

Список из массива

Страны = Новый Массив(); Страны.Добавить("RU"); Страны.Добавить("KZ"); Страны.Добавить("BY"); HTML = Кит.Поле("страны", "Коды стран").Значение(Страны).Рендер();

В объявленной форме слово .Список() у поля даёт при разборе Массив строк без пустых и повторов, а действующее значение принимается строкой или массивом.

Цвет#

Поле цвета — ряд образцов кружками и «свой» цвет системной палитрой браузера; под рядом — имя и код выбранного. Образцы задаёт слово .Образец(Цвет, Имя) — код вида #rrggbb и имя для человека; первый образец сам делает поле цветом, .Цвет() — без образцов. Пустое значение значит «по умолчанию»: у необязательного поля для него есть свой кружок, перечёркнутый наискось.

Значение несёт одно поле — код текстом. Его формат проверяет pattern: браузер не отправит код не того вида, а объявленная форма отобьёт его и сервером. Кружки — радиокнопки, а палитра — <input type="color">, но в отправку они не входят: атрибут form="" отвязывает их от формы, и второго значения под именем поля не бывает. Без скрипта ряд спрятан, и остаётся поле кода — его набирают руками.

Цвет — образцы, свой и по умолчанию

Цвет акцента
Синий
HTML = Кит.Поле("акцент", "Цвет акцента") .Образец("#6750a4", "Фиолетовый") .Образец("#1a73e8", "Синий") .Образец("#188038", "Зелёный") .Образец("#e8710a", "Оранжевый") .Образец("#d93025", "Красный") .Значение("#1a73e8").Рендер();

Свой цвет — не из образцов

Цвет метки
Свой
HTML = Кит.Поле("метка", "Цвет метки") .Образец("#1a73e8", "Синий") .Образец("#188038", "Зелёный") .Значение("#8e24aa").Рендер();

Акцент чаще всего выбирают из палитры кита — слово .ОбразцыТемы(): шесть кружков (лаванда, синий, зелёный, янтарный, красный, серый), на которых цветовая схема держит контраст ролей в обеих темах. Палитра одна на все экраны выбора акцента — у посетителя и у администратора цвета не расходятся. Имена цветов кит берёт из словаря (field.color.swatch.lavender, …blue, …green, …amber, …red, …grey): своих строк у кита нет. Свои образцы словом .Образец встают после палитры.

Акцент из палитры кита

Акцент
Зелёный
Пусто — акцент по умолчанию.
HTML = Кит.Поле("accent", "Акцент").ОбразцыТемы() .Подсказка("Пусто — акцент по умолчанию.").Значение("#2bb673").Рендер();

В объявленной форме слова те же — .Цвет() и .Образец(Цвет, Имя); разбор отдаёт код строчными, пустое — Неопределено («по умолчанию»), а код не того вида отбивает текстом словаря form.error.color.

Значок#

Поле выбора значка — сетка значков кита на выбор: глифы набора (имена, как у иконки) и логотипы брендов (бренд:telegram, бренд:github …). Слово .ВыборЗначка() (или узел Кит.ВыборЗначка(Имя, Метка)) делает поле сеткой радиокнопок: значение поля — имя выбранного значка, оно и уходит с формой. Выбранная ячейка — заливкой и кольцом, её видно и без скрипта. Без скрипта сетка печатается целиком, разделами «Глифы» и «Бренды»; со скриптом над ней строка поиска по имени — она отбирает ячейки на месте, а скринридер слышит, сколько найдено. Enter в строке поиска выбирает первый найденный значок.

Необязательные слова: .Разделы("глифы", "бренды", "служебные") — какие каталоги показать и в каком порядке (без слова — глифы и бренды), .Значение(Имя) — текущий значок, .Пусто(Подпись, Иконка) — вариант «без значка» первой ячейкой (без подписи — текст словаря iconpicker.none; со своим значком — приглушённый значок вместо перечёркнутого круга и видимая подпись рядом: пусто у провайдера входа значит «по издателю», а не «ничего»), .Исключить(Имя, …) — значки, которых в сетке быть не должно (имена или массив имён; повторный вызов дописывает). Тексты строки поиска, разделов и счёта найденного — словарь iconpicker.search, iconpicker.glyphs, iconpicker.brands, iconpicker.service, iconpicker.found.

Служебные глифы — стрелки, меню, крестик, солнце и луна (Иконка.СлужебныеГлифы()) — кит рисует в своих узлах, и в выборе значка тега или канала они лишние: в разделе «Глифы» их нет (дев-сборка 10). Нужны — назовите раздел служебные. Сохранённое значение остаётся своей ячейкой, даже если оно служебное или исключено: иначе выбор, которого нет в сетке, пропал бы при следующем сохранении.

Значок — глифы и бренды с поиском

Значок

Значок стоит перед именем в плашке.
HTML = Кит.Поле("значок", "Значок").ВыборЗначка().Пусто() .Значение("тег").Подсказка("Значок стоит перед именем в плашке.").Рендер();

Только бренды — значок провайдера входа

Значок провайдера

HTML = Кит.ВыборЗначка("значок-провайдера", "Значок провайдера").Разделы("бренды") .Пусто("По издателю", "ключ").Рендер();

Без значков, которых домен не принимает

Значок канала

HTML = Кит.ВыборЗначка("значок-канала", "Значок канала").Исключить("тег", "закладка", "бренд:google") .Значение("конверт").Рендер();

Зеркало поля выбора значка показывает в образце сам значок: у зеркала признаком на плашке или кнопке — вместо её значка, у зеркала текстом — вместо текста. Образец — на странице иконки.

Состояния#

Ошибка#

Ошибка красит линию, подпись и курсор цветом ошибки и печатает сообщение под полем. Пишите, что исправить, а не только что не так.

С ошибкой

HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Ошибка", "имя", "Имя проекта", "Имя занято"));

С Ид поле получает id, подпись — for, а сообщение об ошибке — свой идентификатор, на который поле ссылается из aria-describedby. Тогда скринридер на фокусе прочтёт и подпись, и причину отказа.

Ошибка, связанная с полем через Ид

HTML = Набор.Поле().Отрисовать(Новый Структура("Ид, Имя, Метка, Значение, Ошибка", "проект-имя", "имя", "Имя проекта", "main", "Имя занято — выберите другое"));

Обязательное и только для чтения#

Обязательное ставит атрибут required: браузер не отправит форму с пустым полем. ТолькоЧтение оставляет поле в форме и в отправке, но править не даёт.

Обязательное

HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Обязательное", "имя", "Имя проекта", Истина));

Только для чтения — значение уходит с формой

HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Значение, ТолькоЧтение", "ключ", "Ключ проекта", "PRJ-12", Истина));

Заблокированное#

Заблокированное поле — витрина значения: оно не правится и не отправляется, поэтому Имя ему не нужно. Контейнер и текст приглушены.

Заблокированное — витрина значения

HTML = Набор.Поле().Отрисовать(Новый Структура("Метка, Значение, Заблокировано", "Каталог данных", "/var/lib/приложение", Истина));

Проверка#

Поле проверяется трижды одними и теми же правилами: браузер — атрибутами (required, pattern, minlength, maxlength, min, max, type=url и email), скрипт кита — текстом под полем ещё до отправки, сервер — при разборе объявленной формы. Источник правил один — слова поля; второй копии в скрипте или в обработчике нет.

Когда использовать#

  • Правило известно заранее: формат адреса и почты, длина имени, пределы числа, шаблон ключа. Скажите его словом поля — человек узнает об ошибке, уходя из поля, а не после перезагрузки.
  • Ответ знает только сервер: имя занято, ключ уже выдан. Слово ПроверкаНаСервере(Адрес) спросит его, пока человек ещё в форме.

Не проверяйте до отправки то, что зависит от других полей или прав: это работа обработчика формы, и его отказ ляжет под поле тем же путём.

Слова и тексты#

Слово Что печатает поле Текст отказа — ключ словаря
Обязательное() required form.error.required
ТипЗначения("url"), ТипЗначения("email") type=url, type=email form.error.url, form.error.email
ТипЗначения(Тип("Число")) type=number form.error.number
Пределы(Мин, Макс) min, max form.error.min, form.error.max (%1 — предел)
Длина(Мин, Макс) minlength, maxlength form.error.minlength, form.error.maxlength (%1 — длина)
Шаблон(Образец) pattern form.error.pattern
ПроверкаНаСервере(Адрес) data-check текст ответа сервера

Слова Длина, Шаблон и ПроверкаНаСервере включают проверку до отправки сами. Прежним ограничениям — обязательности, типу почты и адреса, пределам — её включает слово ПроверкаДоОтправки(): без него такое поле печатается как раньше, байт в байт, и отказ показывает браузер своим пузырём.

Поле с проверкой несёт тексты отказов разметкой: признак data-error-<вид> на каждое своё ограничение — required, type, number, pattern, minlength, maxlength, min, max. Текстов в скрипте нет: словарь один у сервера и у браузера, поэтому отказ до отправки звучит теми же словами, что и отказ сервера после неё. Ключ, которого словарь не знает, печатается маркером [?ключ].

Проверка до отправки — словами поля

HTML = Кит.Форма("/образец-проверки", Кит.Поле("name", "Имя проекта").Ид("proverka-name").Обязательное().Длина(2, 30) .Шаблон("[a-z0-9\-]+").ПроверкаНаСервере("/образец-проверки/имя") .Подсказка("латиница, цифры и дефис; alpha и beta заняты"), Кит.Поле("site", "Сайт проекта").Ид("proverka-site").ТипЗначения("url").ПроверкаДоОтправки(), Кит.Поле("limit", "Участников, не больше").Ид("proverka-limit").ТипЗначения(Тип("Число")) .Пределы(1, 50).ПроверкаДоОтправки(), Кит.Кнопка("Создать проект").Основная()).Вид("столбик").Токен("образец").Рендер();

Наберите в образце «пример.рф» в адресе и нажмите «Создать проект»: форма не уйдёт, а под полем встанет «Нужен адрес страницы целиком». Наберите «alpha» в имени — через полсекунды сервер этого сайта ответит, что имя занято. Тот же образец с тихой отправкой и тостом ответа — на странице с сервером.

Шаблон браузер читает по правилам атрибута pattern — с флагом v: значение совпадает с выражением целиком, а дефис внутри класса экранируется ([a-z0-9\-]+). Негодное выражение останавливает сборку там, где его объявили.

У списка ограничения несёт строка ввода, а разбор судит строку через запятую — ту, что без скрипта и уходит с формой. У цвета pattern и maxlength кода свои, а отказ шаблона звучит словами form.error.color, как у разбора. Справка у обоих та же, что у прочих полей: значок рядом с подписью, ссылка из aria-describedby у ввода.

Список и цвет со справкой и проверкой

Маски через запятую или Enter; строка целиком — не длиннее 30 символов.
Цвет акцента
По умолчанию
Цвет кнопок и ссылок проекта.
HTML = Кит.Поле("маски", "Маски файлов").Ид("proverka-masks").Список().Значение("*.os, *.bsl") .Справка("Маски через запятую или Enter; строка целиком — не длиннее 30 символов.").Длина(1, 30).Рендер() + Кит.Поле("акцент", "Цвет акцента").Ид("proverka-accent").Образец("#1a73e8", "Синий") .Образец("#188038", "Зелёный").Справка("Цвет кнопок и ссылок проекта.").Обязательное() .ПроверкаДоОтправки().Рендер();

Что делает скрипт#

  • Попытка отправить форму с негодным полем: вместо пузыря браузера текст отказа ложится в field__error этого поля — туда же, куда сервер печатает свой, — поле получает aria-invalid="true" и ссылку на текст из aria-describedby, фокус встаёт на первое негодное поле.
  • Уход из поля, в котором что-то набрали: та же проверка, без отправки. Нетронутое поле на уходе молчит.
  • Исправленное поле снимает отказ сразу, на вводе.
  • ПроверкаНаСервере: когда человек перестал набирать (полсекунды тишины) или ушёл из поля, скрипт спрашивает GET Адрес?имя=значение. Ответ 200 — свободно, 409 — занято, и текст ответа становится отказом: он держит форму, пока значение не сменят. Сеть и другие ответы молчат — занятость проверит обработчик при отправке.

Без скрипта форма работает целиком: негодное не пускает браузер, а то, что знает только сервер, отбивает обработчик формы — методом Отбить объявленной формы или словом Ошибка поля. Отказ сервера после тихой отправки морфится в те же места: тот же field__error, тот же aria-invalid.

// обработчик POST: те же ограничения разбирает объявление, занятость — домен
Итог = Объявление.Разобрать(Присланное);
Если Итог.Принято И Проекты.Занято(Итог.Значения.Получить("name")) Тогда
	Объявление.Отбить("name", СтрШаблон("Имя «%1» уже занято", Итог.Значения.Получить("name")));
КонецЕсли;

// адрес проверки: 200 — свободно, 409 с текстом — занято
Ответ.УстановитьТипКонтента("txt");
Ответ.УстановитьСостояние(?(Занято, 409, 200));
Ответ.ТелоТекст = ?(Занято, "Имя уже занято — выберите другое", "");
ДелайтеПравило — словом поля: браузер, скрипт и сервер судят одинаково
Код
HTML = Кит.Поле("name", "Имя проекта").Длина(2, 30).Шаблон("[a-z0-9\-]+")
	.Подсказка("латиница, цифры и дефис").Рендер();
Не делайтеПравило только в подсказке: человек узнает о нём после перезагрузки
Код
HTML = Кит.Поле("name", "Имя проекта")
	.Подсказка("от 2 до 30 символов: латиница, цифры и дефис").Рендер();

Доступность проверки#

  • Текст отказа — role="alert": скринридер читает его сразу, как только он появился.
  • Поле с отказом — aria-invalid="true"; с Ид оно ссылается на текст отказа из aria-describedby, не теряя других ссылок.
  • После неудачной попытки отправить фокус встаёт на первое негодное поле.
  • Отказ не держится на цвете: красная линия дублируется текстом под полем.

Гайдлайны#

ДелайтеМетка называет поле, плейсхолдер — только пример
Код
HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Плейсхолдер",
	"почта", "Почта", "имя@пример.рф"));
Не делайтеПлейсхолдер вместо метки: при вводе он исчезнет вместе с подсказкой
Код
HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Плейсхолдер",
	"почта", "Почта"));
ДелайтеОшибка говорит, что исправить
Код
HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Значение, Ошибка",
	"имя", "Имя проекта", "Мой проект", "Только латиница и дефис, например my-project"));
Не делайтеОшибка без причины и выхода
Код
HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Значение, Ошибка",
	"имя", "Имя проекта", "Мой проект", "Неверное значение"));
ДелайтеФлажок — утверждение, которое включают
Код
HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Тип",
	"скрыт", "Скрыть из списка", "флажок"));
Не делайтеФлажок с отрицанием: «снять „не“» читается вдвое дольше
Код
HTML = Набор.Поле().Отрисовать(Новый Структура("Имя, Метка, Тип",
	"показ", "Не показывать в списке", "флажок"));
ДелайтеСписок — для коротких однородных значений
Код
HTML = Кит.Поле("метки", "Метки").Список().Значение("срочно, отчёт, квартал").Рендер();
Не делайтеСписок для фраз с запятыми: запятая разрежет фразу на плашки
Код
HTML = Кит.Поле("адрес", "Адрес").Список().Значение("Москва, ул. Тверская, 1").Рендер();
Цвет акцента
По умолчанию
ДелайтеОбразец с именем: имя читает скринридер и показывает подсказка
Код
HTML = Кит.Поле("акцент", "Цвет акцента").Образец("#1a73e8", "Синий")
	.Образец("#188038", "Зелёный").Рендер();
Цвет акцента
По умолчанию
Не делайтеОбразец без имени: у кружка остаётся только код
Код
HTML = Кит.Поле("акцент", "Цвет акцента").Образец("#1a73e8")
	.Образец("#188038").Рендер();

Доступность#

  • Подпись связана с полем всегда: вложением в <label>, а с Ид — ещё и атрибутом for.
  • Поле с ошибкой несёт aria-invalid="true"; сообщение печатается с role="alert" и читается сразу. С Ид поле ссылается на сообщение из aria-describedby.
  • Флажок — настоящий <input type="checkbox">: пробел, фокус и состояние даёт браузер.
  • Без Метки поле немо для скринридера: плейсхолдер подписью не считается. Метку задавайте всегда.
  • Незаблокированное поле без Имени кит не соберёт: браузер не отправил бы его значение.
  • Список: строка ввода связана с подписью вложением, плашки — список (role="list") с именем поля, крестик каждой — кнопка «Убрать «значение»» (ключ словаря field.list.remove). Снял плашку — фокус возвращается в строку ввода. Без скрипта плашек нет вовсе: обычное поле со строкой.
  • Цвет: группа <fieldset> с <legend>; образцы — радиокнопки одной группы, поэтому Tab заходит в ряд одной остановкой, а стрелки выбирают образец. Имя образца — его подпись для скринридера, «по умолчанию» и «свой» берутся из словаря (field.color.default, field.color.own), поле кода называет себя field.color.code. Отмеченный кружок обведён двойным кольцом, а не только цветом.

Узлом холста#

На холсте поле кладут в форму; как собрать форму целиком — на странице Формы деревом.

Поле узлом дерева

HTML = Кит.Поле("имя", "Имя проекта").Значение("main").Рендер();

Модель#

Класс зовётся ПолеФормы: имя Поле занято библиотекой decorator. В наборе компонентов он доступен как Набор.Поле(). Структура с этими полями — прежний вид модели: в дереве холста те же поля пишут слова Кит.Поле, а поле Тип — слово ТипЗначения.

Кит.Поле()src/Классы/холст/Кит.os

Поле ввода со своей меткой, подсказкой и отказом. Тип ввода — словом ТипЗначения(Тип(…)
| ОписаниеТипов | строка) либо выводится из Значения. Слова: Метка, ТипЗначения,
Значение, Подсказка, Пример (плейсхолдер), Автозаполнение, Ошибка, Обязательное,
ТолькоЧтение, Заблокировано, Отмечено, Вариант(Значение, Подпись), Ид, Многострочное,
Секрет, Файл, Справка(Текст) — длинное пояснение значком «?» с поповером рядом с подписью
(короткое остаётся словом Подсказка строкой под полем); поле-список — Список(), поле цвета —
Цвет() и Образец(Цвет, Имя); проверка до отправки (выпуск 0.12) — Пределы(Мин, Макс),
Длина(Мин, Макс), Шаблон(Образец), ПроверкаНаСервере(Адрес), ПроверкаДоОтправки.

Параметры:
 Имя   - Строка, Структура - имя поля (атрибут name); Структура — прежний вид модели
         компонента «Поле».
 Метка - Строка - (необязательный) подпись поля для человека.

Возвращаемое значение:
 ЭлементЭкрана

ПолеФормы.Отрисовать()src/Классы/компоненты/ПолеФормы.os

Отрисовывает поле формы: подпись, ввод, пояснение и сообщение об ошибке.

Параметры:
 Модель - Структура - Имя (атрибут name; обязательно, кроме заблокированного поля),
          Метка, Значение, Тип ("текст" | "пароль" | "число" | "флажок" | "файл" |
          "многострочное" | "выбор" либо любой валидный type HTML), Подсказка,
          Плейсхолдер, Автозаполнение (атрибут autocomplete), Ошибка, Обязательное,
          Заблокировано, ТолькоЧтение, Отмечено (для флажка), Варианты (для выбора:
          массив структур Значение, Подпись, Выбрано, Данные — Соответствие
          дополнительных data-атрибутов варианта). Вариант с пустым Значением
          допустим и выбирается пустым Значением поля. Ид — идентификатор управления:
          задан, значит печатаются id, <label for> и aria-describedby сообщения
          об ошибке; без него подпись связана с полем вложением. Минимум, Максимум,
          Шаг и ДлинаМакс — атрибуты min, max, step и maxlength (пустые не печатаются;
          их выводит тип значения поля, см. ТипыПоля). Шаблон — атрибут pattern
          (регулярное выражение, которому значение обязано совпасть целиком), Форма —
          атрибут form (якорь формы вне поля); пустые не печатаются.
          Справка — длинное пояснение: значок «?» рядом с подписью открывает поповер
          с ним, а поле ссылается на поповер из aria-describedby; ИдСправки —
          идентификатор поповера (по умолчанию Ид + "-help", без Ид — "help-" + Имя),
          ПодписьСправки — имя значка для скринридера (без неё значок называется «?»).
          Тип «список» — значения плашками: Значение строкой через запятую или массивом
          строк. Тип «цвет» — образцы кружками: Образцы (массив структур Цвет — код
          #rrggbb, Имя; вместо Имени — Ключ словаря с именем, как у палитры кита
          ТокеныТемы.ОбразцыАкцента), Значение — код выбранного; пустое значит «по умолчанию».
          Проверка до отправки (выпуск 0.12): ДлинаМин — атрибут minlength; Проверка
          (Булево) — поле несёт тексты отказов словаря form.error.* признаками
          data-error-* для каждого своего ограничения (скрипт кита пишет их под полем);
          АдресПроверки — признак data-check: адрес, у которого скрипт спрашивает,
          свободно ли значение (200 — свободно, 409 с текстом — занято). Справка
          и проверка до отправки годятся и списку, и цвету: атрибуты ввода у всех видов
          поля одни (у цвета pattern и maxlength кода свои, отказ шаблона — form.error.color).
          Источник — откуда взялось значение («по умолчанию · mail.host»): мелкая
          приглушённая надпись справа в строке подсказки; без подсказки строка
          печатается с одним источником. Пустой — строка подсказки прежняя.
          СсылкаРядом (дев-сборка 9) — Структура Адрес, Подпись: ссылка над полем справа
          («Забыли пароль?»), обёртка <div class="field-aside">.
          СкрытаяМетка — метка видна только скринридеру (visually-hidden вместо
          field__label): поле садится как поле без метки, а доступное имя — от метки.
          Тип «значок» (дев-сборка 9) — выбор значка сеткой: Значение — имя значка
          (глиф набора или «бренд:<ключ>»), Разделы — Массив из «глифы», «бренды» (какие
          каталоги показать, по умолчанию оба), Пусто — подпись варианта «без значка»
          первой ячейкой (пустая строка — подпись словаря iconpicker.none; поля нет —
          варианта нет).

Возвращаемое значение:
 Строка - фрагмент <label class="field"> (у списка — <div class="field">, у цвета и значка —
          <fieldset class="field">); со Справкой — он же в <div class="field-help">
          вместе со значком и поповером. Кидается исключением, если у незаблокированного
          поля нет Имени.

Слова проверки до отправки (выпуск 0.12) — у поля холста и у описания поля объявленной формы:

ЭлементЭкрана.ПроверкаНаСервере()src/Классы/холст/ЭлементЭкрана.os

Проверка значения сервером до отправки (признак data-check): скрипт кита, когда человек
перестал набирать или ушёл из поля, спрашивает «Адрес?имя=значение»; 200 — свободно,
409 — занято, текст ответа печатается под полем. Без скрипта занятость проверяет
обработчик формы. Включает проверку до отправки.

Параметры:
 Адрес_ - Строка - адрес проверки.

Возвращаемое значение:
 ЭлементЭкрана - этот же элемент.

ЭлементЭкрана.ПроверкаДоОтправки()src/Классы/холст/ЭлементЭкрана.os

Проверка до отправки: поле несёт тексты отказов словаря form.error.* для каждого своего
ограничения (data-error-*), и скрипт кита пишет отказ под полем, когда браузер не пускает
форму или человек уходит из поля. Слова Длина, Шаблон и ПроверкаНаСервере включают её
сами; прежним ограничениям (Обязательное, Пределы, ТипЗначения("email" | "url")) она
нужна словом — их поле печатается как раньше, пока его об этом не попросили.

Возвращаемое значение:
 ЭлементЭкрана - этот же элемент.

ЭлементЭкрана.СкрытаяМетка()src/Классы/холст/ЭлементЭкрана.os

Метка поля только для скринридера: её не видно, а доступное имя поле получает от неё,
а не от примера (placeholder), который пропадает при вводе. Для поля, чей смысл ясен
из места на экране, — строки поиска над списком, поля в строке таблицы. Поле садится
так же, как поле без метки: значение посередине, пример виден.

Возвращаемое значение:
 ЭлементЭкрана - этот же элемент.

ОписаниеПоля.Длина()src/Классы/каркас/ОписаниеПоля.os

Пределы длины строки: поле печатает атрибуты minlength и maxlength, разбор отбивает
строку короче или длиннее, скрипт кита пишет отказ под полем до отправки. Включает
проверку до отправки (см. ПроверкаДоОтправки).

Параметры:
 Мин  - Число, Неопределено - наименьшая длина; Неопределено или 0 — без нижнего предела.
 Макс - Число, Неопределено - (необязательный) наибольшая длина; Неопределено или 0 — без верхнего.

Возвращаемое значение:
 ОписаниеПоля - это же описание.

ОписаниеПоля.Шаблон()src/Классы/каркас/ОписаниеПоля.os

Шаблон значения — регулярное выражение, которому значение обязано совпасть ЦЕЛИКОМ
(атрибут pattern). Разбор сверяет с ним то, что пришло, — без скрипта браузер не
отправит несовпавшее, а сервер не примет подделанное. Включает проверку до отправки.

Параметры:
 Образец - Строка - регулярное выражение без якорей ^ и $ по правилам атрибута pattern
           (браузер читает его с флагом v: дефис внутри класса экранируется), например
           "[a-z0-9\-]+".

Возвращаемое значение:
 ОписаниеПоля - это же описание.