form-father 0.7.1 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,230 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ ## [0.8.3](https://github.com/Poliklot/form-father/compare/form-father-v0.8.2...form-father-v0.8.3) (2026-06-22)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * avoid unsafe error id regex trimming ([0c9dca8](https://github.com/Poliklot/form-father/commit/0c9dca873c5c7677baffc7381912fcef0fdd9f71))
11
+
12
+ ## [0.8.2](https://github.com/Poliklot/form-father/compare/form-father-v0.8.1...form-father-v0.8.2) (2026-06-18)
13
+
14
+
15
+ ### Security
16
+
17
+ * Override `js-yaml` to `4.2.0` to close the remaining Dependabot security alert.
18
+ * Update vulnerable build dependencies, including `serialize-javascript`, `vite`, and `esbuild`.
19
+
20
+
21
+ ### Build
22
+
23
+ * Update Rollup, Babel, PostCSS, and TypeScript build tooling.
24
+ * Set explicit TypeScript `rootDir` and DOM/ES2019 library targets for stable declaration builds.
25
+
26
+
27
+ ### Tests
28
+
29
+ * Configure Jest TypeScript globals for the TypeScript 6 test run.
30
+
31
+ ## [0.8.1](https://github.com/Poliklot/form-father/compare/form-father-v0.8.0...form-father-v0.8.1) (2026-06-18)
32
+
33
+
34
+ ### Bug Fixes
35
+
36
+ * accept Release Please changelog format ([d1bfe42](https://github.com/Poliklot/form-father/commit/d1bfe426d25d93bedb6ccf23406fd546a929a7bd))
37
+
38
+ ## [0.8.0](https://github.com/Poliklot/form-father/compare/form-father-v0.7.1...form-father-v0.8.0) (2026-06-18)
39
+
40
+
41
+ ### Features
42
+
43
+ * Добавлен экспорт всех функций их валидаторов. ([a98d9cf](https://github.com/Poliklot/form-father/commit/a98d9cfc5500d5ffc6b4259cd195fd0bec2e76e0))
44
+ * Добавлены 2 колбэка до валидации и после. ([27830c7](https://github.com/Poliklot/form-father/commit/27830c72f0335071a3693d165ed2b8d267504472))
45
+ * добавлены checkbox в clearInputs ([b4109a9](https://github.com/Poliklot/form-father/commit/b4109a94de4007a51ef497b37493aef6d4389084))
46
+ * Добавлены конфиги для редактора. ([e47f6b9](https://github.com/Poliklot/form-father/commit/e47f6b9c090bf7cdc76ceebd1ff65f88a7852730))
47
+ * добавлены свойства reload-delay и redirect-url-delay в ответе для задержки reload или redirect после ответа с сервера ([1575892](https://github.com/Poliklot/form-father/commit/157589223247fa26a588ddb8c8430810097ee3e1))
48
+ * добавлены свойства reload-delay и redirect-url-delay в ответе для задержки reload или redirect после ответа с сервера ([52d38b5](https://github.com/Poliklot/form-father/commit/52d38b52cd2b2ce2b6a3257945eab41e66182186))
49
+ * доработан README про redirect-url-delay & reload-delay & и перенесён RESPONSE_API из отдельного гиста https://gist.github.com/Poliklot/4916c87acf77c0a57c46c08ae2672299 ([2fe0339](https://github.com/Poliklot/form-father/commit/2fe0339b60319fad3e486de5fbf8cd3837add54c))
50
+ * доработана валидация URL ([398591c](https://github.com/Poliklot/form-father/commit/398591c4154df9b07a060b8e96b2c2cbc0c2e6f1))
51
+ * Доработана реализация валидатора required и тесты к нему. ([ed68350](https://github.com/Poliklot/form-father/commit/ed683502858f9579cccfc5113e98773eee8b86e9))
52
+ * Доработки по toast. ([c9c3e02](https://github.com/Poliklot/form-father/commit/c9c3e022ebf034eae8210db6f882ad2497aa84ba))
53
+ * Исправлен хардкод вызывающий toast. ([d0920de](https://github.com/Poliklot/form-father/commit/d0920decfe8c7efbd73ddc3772fc790376db116f))
54
+ * отменено всплытие дефолтного submit к document ([4d3e962](https://github.com/Poliklot/form-father/commit/4d3e9629c5cce822065437db66bc0fada44be82a))
55
+ * отменено всплытие дефолтного submit к document ([4df6d64](https://github.com/Poliklot/form-father/commit/4df6d6469dc2f899ece209170de93f66a7fd2240))
56
+ * отменено поведение при клике ([ddde968](https://github.com/Poliklot/form-father/commit/ddde9680b7cede4a0eb0ce1cb6aeb20cfe5193d0))
57
+ * отменено поведение при клике ([d7ed0a5](https://github.com/Poliklot/form-father/commit/d7ed0a5877da68232cfe308f625f02b869a40b18))
58
+ * проработан случай нескольких submit-кнопок ([a598b36](https://github.com/Poliklot/form-father/commit/a598b36cb8b5eafe7ead324f2df9b3ada670f742))
59
+ * Раширен API валидаторов. ([3050de9](https://github.com/Poliklot/form-father/commit/3050de95f75bf066a92d4673d1bd9ceb19a60b9c))
60
+ * Реализован публичный метод destroy. ([b8dee71](https://github.com/Poliklot/form-father/commit/b8dee71e8cc711d1b3361b92a5be11bfef78c566))
61
+ * Реализована анимация появления ошибки у формы. ([cb26d9e](https://github.com/Poliklot/form-father/commit/cb26d9e8313ec01c8b64afda3479df65a5ba833b))
62
+ * Реализована возможность валидации отдельных частей формы. ([bd2d5b7](https://github.com/Poliklot/form-father/commit/bd2d5b7b3b367e8d808f90e911fc3aeed10c61b6))
63
+ * Реализовано 2 дата-атрибута для отключения валидации и скролла до элемента. ([ce95a6b](https://github.com/Poliklot/form-father/commit/ce95a6be6b66c00ea7eb0af6ea3b91d0129515b2))
64
+ * Реализованы валидаторы. ([1018d4c](https://github.com/Poliklot/form-father/commit/1018d4c775107ac7568a59df962f22e0244aa450))
65
+ * Реализованы тесты ([cf4fd76](https://github.com/Poliklot/form-father/commit/cf4fd76a36846e006421db87df18c01ee47d53c0))
66
+
67
+
68
+ ### Bug Fixes
69
+
70
+ * publish package entrypoints ([bc379bf](https://github.com/Poliklot/form-father/commit/bc379bff2d0f57eb836c245cf5a038530df5d5d8))
71
+ * Исправлена проблема потери дефолтных параметров в разных скриптах. ([cdecba6](https://github.com/Poliklot/form-father/commit/cdecba6be3fce67d7d8264ce3e57d8a7d0fc89d8))
72
+ * Исправлены жесткие селекторы. ([d906319](https://github.com/Poliklot/form-father/commit/d906319c14de868b6ea12012134b1e4fe517a580))
73
+
74
+ ## 0.7.1 - 2026-05-19
75
+
76
+ ### Fixed
77
+
78
+ - Added explicit npm package entrypoints (`main`, `module`, `types`, `exports.default`, CDN fields) for compatibility with webpack and TypeScript consumers using classic Node module resolution.
79
+ - Synchronized the flattened publish manifest in `package/package.json` with the root package metadata.
80
+
81
+ ## 0.7.0 - 2026-04-27
82
+
83
+ ### Added
84
+
85
+ - Added `docs/api/README.md` with a compact public API, options, methods, validators, adapters, and helpers reference.
86
+ - Added `docs/demo/README.md` with manual demo scenarios and demo coverage notes.
87
+ - Added a Public API demo panel covering `setValues()`, `validateField()`, `setErrors()`, `getValues()`, and
88
+ `clearErrors()`.
89
+ - Added `npm run docs:check` to verify documentation files, version references, package README sync, and demo coverage.
90
+
91
+ ### Changed
92
+
93
+ - `npm run release:check` now includes documentation checks before build and package smoke checks.
94
+ - Package smoke checks now verify the broader public export surface and package documentation files.
95
+
96
+ ### Tests
97
+
98
+ - Release gate remains at 122 tests plus docs/package smoke checks.
99
+
100
+ ## 0.6.0 - 2026-04-27
101
+
102
+ ### Added
103
+
104
+ - Added accessible field error wiring via `aria-describedby` with safe preservation of existing descriptions.
105
+ - Added `errorSummary` option with default rendering, custom selector support, focus control, and custom renderers.
106
+ - Added `ariaDescribeErrors` and `errorIdPrefix` options for UI/a11y integration control.
107
+
108
+ ### Changed
109
+
110
+ - Field, form-level, backend, and manual errors can now share one visible summary while keeping the existing inline error
111
+ rendering path.
112
+ - Demo forms now include accessible error summaries.
113
+
114
+ ### Tests
115
+
116
+ - Test suite expanded to 122 tests.
117
+ - Coverage baseline: 98.30% statements, 86.88% branches, 97.25% functions, 100% lines.
118
+
119
+ ## 0.5.0 - 2026-04-27
120
+
121
+ ### Added
122
+
123
+ - Added field validator DX helpers: `registerFieldValidator()`, `createPatternValidator()`, and
124
+ `createLengthValidator()`.
125
+ - Added form validator DX helpers: `createFormValidator()`, `sameAsField()`, `requiredIf()`, and `dateOrder()`.
126
+ - Added helper types for reusable form validator predicates and issue factories.
127
+
128
+ ### Changed
129
+
130
+ - Demo and documentation now use higher-level helper APIs for common password-confirm and validation rule recipes.
131
+
132
+ ### Tests
133
+
134
+ - Test suite expanded to 115 tests.
135
+ - Coverage baseline: 98.19% statements, 86.91% branches, 97.04% functions, 100% lines.
136
+
137
+ ## 0.4.0 - 2026-04-27
138
+
139
+ ### Added
140
+
141
+ - Added form-level and cross-field validation via `formValidators`.
142
+ - Added `setErrors()` for backend maps, `ErrorResponse[]`, global form errors, and custom validation issue objects.
143
+ - Added `FORM_ERROR_FIELD` constant for form-level errors in `getErrors()`.
144
+ - Added public TypeScript types for form validation contexts and issues.
145
+
146
+ ### Changed
147
+
148
+ - `validate()` now runs field-level rules first, then form-level validators over `getValues()`.
149
+ - Cross-field and backend errors share the same rendering path as field validation errors.
150
+
151
+ ### Tests
152
+
153
+ - Test suite expanded to 113 tests.
154
+ - Coverage baseline: 98.31% statements, 87.05% branches, 96.34% functions, 100% lines.
155
+
156
+ ## 0.3.0 - 2026-04-25
157
+
158
+ ### Added
159
+
160
+ - Added convenience API: `Form.initAll()`, `updateOptions()`, public `submit()`, `validateField()`, `showFieldError()`,
161
+ `getErrors()`, `getValues()`, `setValues()`, `clearErrors()`, and `reset()`.
162
+ - Added client validation hooks: `onValidationError`, `onBeforeSubmit`, and `onSubmitError`.
163
+ - Added live validation options: `validateOn`, `revalidateOn`, `validationDebounce`, and `focusFirstErroredInput`.
164
+ - Added `data-validate`, `data-error-*`, and `data-error-container` support while keeping `data-custom-validate`.
165
+ - Added optional mutation observing for dynamic fields and submit buttons.
166
+ - Added race-safe async field validation state with `aria-busy` and configurable field state attributes.
167
+ - Added dependency-free schema adapters: `createSchemaValidator()`, `registerSchemaValidator()`, and
168
+ `createFieldValidator()`.
169
+ - Added static demos for login, callback/server errors, GET search, and multipart upload.
170
+ - Added recipes documentation for common API, data-attribute, adapter, and server-error flows.
171
+
172
+ ### Changed
173
+
174
+ - Validation now merges every matching schema rule for a field before applying data-attribute rules.
175
+ - Server-side field errors now populate the public `getErrors()` list.
176
+ - Package contents now include docs, demos, and the changelog.
177
+
178
+ ### Tests
179
+
180
+ - Test suite expanded to 109 tests.
181
+ - Coverage baseline: 98.10% statements, 86.15% branches, 95.69% functions, 100% lines.
182
+
183
+ ## 0.2.11 - 2026-04-25
184
+
185
+ ### Added
186
+
187
+ - Added release checklist, package smoke checks, CI workflow, and release gate scripts.
188
+ - Added npm pack dry-run script with a temporary npm cache for local cache permission issues.
189
+
190
+ ### Changed
191
+
192
+ - Updated package metadata and release workflow after `0.2.10` had already been published.
193
+
194
+ ## 0.2.10 - 2026-04-25
195
+
196
+ ### Added
197
+
198
+ - Exported public helper APIs from the package entrypoint: `serializeToFormData`, validators, URL/email/phone helpers, scroll helpers, and response helpers.
199
+ - Exported TypeScript types for public consumers: `FormOptions`, `ValidationRule`, `ValidationSchema`, `ErrorResponse`, and `ResponseBody`.
200
+ - Added package smoke checks for built files and public exports.
201
+ - Added CI workflow for tests, build, smoke checks, and npm pack dry-run.
202
+ - Added coverage thresholds to keep the stabilization baseline from regressing.
203
+
204
+ ### Changed
205
+
206
+ - `new Form(formEl)` now works without an options object.
207
+ - Submit detection now supports implicit submit buttons (`<button>`) and `input[type="image"]`.
208
+ - `GET` and `HEAD` forms now append form data to the action query string and do not send a request body.
209
+ - `wrapData` now applies consistently across supported encodings: `application/x-www-form-urlencoded`, `multipart/form-data`, `text/plain`, and `application/json`.
210
+ - Non-200 HTTP responses, `success !== true`, and invalid JSON responses now flow through `onResponseUnsuccess`.
211
+ - Server-side field errors can be applied to `input`, `textarea`, and `select`.
212
+ - `serializeToFormData` now skips disabled controls, controls marked with `data-no-serialize`, and button controls.
213
+ - Built-in validators are registered idempotently across repeated module imports.
214
+
215
+ ### Fixed
216
+
217
+ - Loader and `waitResponse` cleanup now runs when `fetch` or response parsing fails.
218
+ - Required radio groups now produce one validation error per group.
219
+ - Field error rendering no longer requires a wrapper-level `showError()` method.
220
+ - Release script now exits with `0` on success and handles missing temporary files during cleanup.
221
+ - Rollup IIFE build no longer warns about mixed default and named exports.
222
+
223
+ ### Tests
224
+
225
+ - Test coverage baseline: 98.32% statements, 86.34% branches, 93.18% functions, 100% lines.
226
+ - Test suite baseline: 93 tests passing.
227
+
228
+ ## 0.2.9
229
+
230
+ - Previous published patch release.
@@ -0,0 +1,233 @@
1
+ ## Краткое введение
2
+
3
+ Эй, ребята! Собрались здесь для того, чтобы понять, как у нас отвечает сервер после того, как отправляем формы через
4
+ AJAX. Это будет не какая-то скучная докуха, а всё по-кубански, с размахом и только по сути!
5
+
6
+ ## Что и как 🛠️
7
+
8
+ ### `success`
9
+
10
+ - **Тип**: boolean.
11
+ - **Описание**: Флаг, показывающий, всё ли круто.
12
+ - **Как Работает**: Если сервер справился, то `true`, а если нет – `false`.
13
+
14
+ ### `redirect-url`
15
+
16
+ - **Тип**: string (опционально).
17
+ - **Описание**: Куда пойти, если всё зашибись.
18
+ - **Когда Появляется**: Только если `success` равно `true`.
19
+
20
+ ### `redirect-url-delay`
21
+
22
+ - **Тип**: number (опционально).
23
+ - **Описание**: Задержка в ms перед редиректом.
24
+
25
+ ### `reload`
26
+
27
+ - **Тип**: boolean (опционально).
28
+ - **Описание**: Как перезагрузить страничку.
29
+ - **Когда Используем**: Когда сервер скажет "обновись".
30
+
31
+ ### `reload-delay`
32
+
33
+ - **Тип**: number (опционально).
34
+ - **Описание**: Задержка в ms перед перезагрузкой страницы.
35
+
36
+ ### `error`
37
+
38
+ - **Тип**: boolean (опционально).
39
+ - **Описание**: Флаг о проблемах.
40
+ - **Как Работает**: Если есть косяк, то `true`.
41
+
42
+ ### `error-msg`
43
+
44
+ - **Тип**: string (опционально).
45
+ - **Описание**: Пояснения от сервера о косяке.
46
+ - **Пример**: "Тут беда, братишка".
47
+
48
+ ### `errors`
49
+
50
+ - **Тип**: array (опционально).
51
+ - **Описание**: Список мелких недоразумений.
52
+ - **Содержание**: Конкретные поля и тексты ошибок.
53
+
54
+ Каждый объект в массиве содержит:
55
+
56
+ - `name` (string): Имя поля, в котором произошла ошибка.
57
+ - `error-msg` (string): Текст ошибки для данного поля.
58
+
59
+ ### `error-toast`
60
+
61
+ - Тип: string (опционально).
62
+ - Описание: Выводится всплывашка(toast) с ошибкой.
63
+ - Пример: "Тут беда, братишка".
64
+
65
+ > [!Caution]
66
+ > `error-toast` DEPRECATED!!!
67
+
68
+ ### `toast`
69
+ - Тип: объект | массив объектов.
70
+ - Описание: Выводит определённый тип тоста и передаёт опции.
71
+ - Пример, один тост:
72
+ ```
73
+ {
74
+ type: 'success',
75
+ title: 'Успешно',
76
+ }
77
+ ```
78
+
79
+ - Пример, несколько тостов за раз:
80
+ ```
81
+ [
82
+ {
83
+ type: 'success',
84
+ title: 'Успешно',
85
+ },
86
+ {
87
+ type: 'error',
88
+ title: 'Ошибка',
89
+ }
90
+ ]
91
+ ```
92
+
93
+
94
+ ## Примеры ответов 📝
95
+
96
+ ### `Когда всё чик-пук, и можно идти дальше.`
97
+
98
+ ```json
99
+ {
100
+ "success": true,
101
+ }
102
+ ```
103
+
104
+ ### `Если нужен редирект.`
105
+
106
+ ```json
107
+ {
108
+ "success": true,
109
+ "redirect-url": "https://example.com/success",
110
+ "redirect-url-delay": 5000, // если нужна задержка перед редиректом
111
+ }
112
+ ```
113
+
114
+ ### `Если нужна перезагрузка страницы.`
115
+
116
+ ```json
117
+ {
118
+ "success": true,
119
+ "reload": true,
120
+ "reload-delay": 5000, // если нужна задержка перед обновлением страницы
121
+ }
122
+ ```
123
+
124
+ ### `Когда надо что-то менять.`
125
+
126
+ ```json
127
+ {
128
+ "success": false,
129
+ "error": true,
130
+ "error-msg": "Тут беда, братишка",
131
+ "errors": [
132
+ {
133
+ "name": "email",
134
+ "error-msg": "Эй, мэйл какой-то кривой"
135
+ }
136
+ ]
137
+ }
138
+ ```
139
+
140
+ Вот и всё, ребятки! Теперь вы знаете, как наш сервер отзывается на ваши AJAX-формы. Дерзайте!
141
+
142
+ # Как работать с e-commerce
143
+
144
+ - В сниппете #src/snippets/\_ym-metrika.html лежит пример кода инициализации Яндекс.Метрики.
145
+ - В скрипте с id='ecommerceScript' есть 2 важных момента: первый - это пример запуска необходимого кода сразу после
146
+ инициализации Яндекс.метрики, а второй - это функция, которая принимает данные и с учётом этого происходят действия
147
+ необходимые для метрик.
148
+ - На данный момент существует только 4 события: `click`, `submit`, `ajax-success` и `ajax-fail`.
149
+ - Атрибут `data-ecom-data` нужно указывать, только для тех событий, которые не ожидают ответа от сервера.
150
+
151
+ ## Примеры использования атрибутов:
152
+
153
+ ### Обычный клик на ссылке
154
+
155
+ ```html
156
+ <a
157
+ href="#"
158
+ data-ecom-action="click"
159
+ data-ecom-data='{
160
+ "click": {
161
+ "ymCounter123123123": "pull-right",
162
+ "dataLayer": []
163
+ }
164
+ }'
165
+ >
166
+ Оформить заказ
167
+ </a>
168
+ ```
169
+
170
+ ### Множественное количество событий на Форме-кнопке
171
+
172
+ ```html
173
+ <button
174
+ data-form-button
175
+ data-form-button-action="/endpoint"
176
+ data-form-button-method="POST"
177
+ data-form-button-data='{"someProperties": "1234"}'
178
+ data-ecom-action="click,ajax-success,submit"
179
+ data-ecom-data='{
180
+ "click": {
181
+ "ymCounter123123123": "pull-right",
182
+ "dataLayer": []
183
+ },
184
+ "submit": {
185
+ "ymCounter123123123": "pull-right",
186
+ "dataLayer": []
187
+ }
188
+ }'
189
+ >
190
+ Оформить заказ
191
+ </button>
192
+ ```
193
+
194
+ ### Cобытие у элемента формы
195
+
196
+ ```html
197
+ <form
198
+ class="ordering-page__body"
199
+ action="/api/order/"
200
+ method="POST"
201
+ name="ORDER_FORM"
202
+ enctype="multipart/form-data"
203
+ novalidate
204
+ data-ecom-action="ajax-success"
205
+ >
206
+ ...
207
+ </form>
208
+ ```
209
+
210
+ # Сериализация форм и полей
211
+
212
+ ## Работа с атрибутом `data-no-serialize-before-changes`
213
+
214
+ ### Общее описание
215
+
216
+ Атрибут `data-no-serialize-before-changes` предназначен для контроля сериализации полей формы в AJAX-запросах. С его
217
+ помощью можно указать, какие поля формы не должны быть сериализованы и отправлены на сервер до того момента, как в них
218
+ произойдут изменения со стороны пользователя.
219
+
220
+ ### Применение
221
+
222
+ Для использования атрибута достаточно добавить его к любому элементу формы, например, `<input>`, `<select>` или
223
+ `<textarea>`. Пока пользователь не изменит значение такого поля, оно не будет включено в сериализованные данные формы
224
+ при AJAX-запросе.
225
+
226
+ ### Пример
227
+
228
+ ```html
229
+ <input type="text" name="user-email" data-no-serialize-before-changes />
230
+ ```
231
+
232
+ В данном случае, поле для ввода email пользователя не будет сериализовано и отправлено на сервер до тех пор, пока
233
+ пользователь явно не изменит его содержимое.
@@ -0,0 +1,198 @@
1
+ <!doctype html>
2
+ <html lang="ru">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Form Father demos</title>
7
+ <link rel="stylesheet" href="./styles.css" />
8
+ </head>
9
+ <body>
10
+ <header class="demo-header">
11
+ <div>
12
+ <p class="eyebrow">Form Father</p>
13
+ <h1>Демо форм, валидации и ответов сервера</h1>
14
+ </div>
15
+ <a class="github-link" href="https://github.com/Poliklot/form-father">GitHub</a>
16
+ </header>
17
+
18
+ <main class="demo-grid">
19
+ <section class="demo-panel">
20
+ <div class="panel-title">
21
+ <p class="eyebrow">Login</p>
22
+ <h2>Live validation</h2>
23
+ </div>
24
+ <form data-form-father action="/demo/login" method="post" enctype="application/json" data-demo="login" novalidate>
25
+ <div data-form-father-summary hidden></div>
26
+
27
+ <label class="field">
28
+ <span>Email</span>
29
+ <input
30
+ class="input"
31
+ name="email"
32
+ type="email"
33
+ autocomplete="email"
34
+ data-validate="required|email|available-email"
35
+ data-error-required="Email обязателен"
36
+ data-error-email="Введите корректный email"
37
+ data-error-available-email="Этот email уже занят"
38
+ data-error-container="#login-email-error"
39
+ />
40
+ <small id="login-email-error" class="field-error" hidden></small>
41
+ </label>
42
+
43
+ <label class="field">
44
+ <span>Password</span>
45
+ <input
46
+ class="input"
47
+ name="password"
48
+ type="password"
49
+ autocomplete="current-password"
50
+ data-validate="required|min-length:6"
51
+ data-error-required="Пароль обязателен"
52
+ data-error-min-length="Минимум 6 символов"
53
+ />
54
+ </label>
55
+
56
+ <label class="field">
57
+ <span>Repeat password</span>
58
+ <input
59
+ class="input"
60
+ name="passwordConfirm"
61
+ type="password"
62
+ autocomplete="current-password"
63
+ data-validate="required"
64
+ data-error-required="Повторите пароль"
65
+ />
66
+ </label>
67
+
68
+ <button type="submit">Войти</button>
69
+ </form>
70
+ </section>
71
+
72
+ <section class="demo-panel">
73
+ <div class="panel-title">
74
+ <p class="eyebrow">Callback</p>
75
+ <h2>Server field errors</h2>
76
+ </div>
77
+ <form data-form-father action="/demo/callback" method="post" data-demo="callback" novalidate>
78
+ <div data-form-father-summary hidden></div>
79
+
80
+ <label class="field">
81
+ <span>Имя</span>
82
+ <input class="input" name="name" data-validate="required" data-error-required="Укажите имя" />
83
+ </label>
84
+
85
+ <label class="field">
86
+ <span>Телефон</span>
87
+ <input
88
+ class="input"
89
+ name="tel"
90
+ type="tel"
91
+ placeholder="+79991234567"
92
+ data-validate="required|tel"
93
+ data-error-tel="Телефон в формате +7XXXXXXXXXX"
94
+ />
95
+ </label>
96
+
97
+ <button type="submit">Заказать звонок</button>
98
+ </form>
99
+ </section>
100
+
101
+ <section class="demo-panel">
102
+ <div class="panel-title">
103
+ <p class="eyebrow">Search</p>
104
+ <h2>GET query</h2>
105
+ </div>
106
+ <form data-form-father action="/demo/search?source=demos" method="get" data-demo="search" novalidate>
107
+ <div data-form-father-summary hidden></div>
108
+
109
+ <label class="field">
110
+ <span>Запрос</span>
111
+ <input class="input" name="q" value="form father" data-validate="required" />
112
+ </label>
113
+
114
+ <label class="field">
115
+ <span>Раздел</span>
116
+ <select class="input" name="section">
117
+ <option value="docs">Docs</option>
118
+ <option value="api">API</option>
119
+ <option value="examples">Examples</option>
120
+ </select>
121
+ </label>
122
+
123
+ <button type="submit">Найти</button>
124
+ </form>
125
+ </section>
126
+
127
+ <section class="demo-panel">
128
+ <div class="panel-title">
129
+ <p class="eyebrow">Multipart</p>
130
+ <h2>FormData upload</h2>
131
+ </div>
132
+ <form data-form-father action="/demo/upload" method="post" enctype="multipart/form-data" data-demo="upload" novalidate>
133
+ <div data-form-father-summary hidden></div>
134
+
135
+ <label class="field">
136
+ <span>Название</span>
137
+ <input class="input" name="title" data-validate="required" />
138
+ </label>
139
+
140
+ <label class="field">
141
+ <span>Файл</span>
142
+ <input class="input" name="attachment" type="file" />
143
+ </label>
144
+
145
+ <button type="submit">Отправить</button>
146
+ </form>
147
+ </section>
148
+
149
+ <section class="demo-panel demo-panel--wide">
150
+ <div class="panel-title">
151
+ <p class="eyebrow">Public API</p>
152
+ <h2>Programmatic control</h2>
153
+ </div>
154
+ <form data-form-father action="/demo/api" method="post" data-demo="api" novalidate>
155
+ <div data-form-father-summary hidden></div>
156
+
157
+ <label class="field">
158
+ <span>Имя</span>
159
+ <input class="input" name="name" data-validate="required" data-error-required="Укажите имя" />
160
+ </label>
161
+
162
+ <label class="field">
163
+ <span>Email</span>
164
+ <input class="input" name="email" type="email" data-validate="required|email" />
165
+ </label>
166
+
167
+ <label class="field">
168
+ <span>Тариф</span>
169
+ <select class="input" name="plan">
170
+ <option value="starter">Starter</option>
171
+ <option value="team">Team</option>
172
+ <option value="enterprise">Enterprise</option>
173
+ </select>
174
+ </label>
175
+
176
+ <div class="demo-actions" aria-label="Public API actions">
177
+ <button type="button" data-api-action="fill">setValues()</button>
178
+ <button type="button" data-api-action="validate-email">validateField()</button>
179
+ <button type="button" data-api-action="server-errors">setErrors()</button>
180
+ <button type="button" data-api-action="values">getValues()</button>
181
+ <button type="button" data-api-action="clear">clearErrors()</button>
182
+ </div>
183
+ </form>
184
+ </section>
185
+ </main>
186
+
187
+ <section class="demo-output">
188
+ <div class="panel-title">
189
+ <p class="eyebrow">Output</p>
190
+ <h2>Последний ответ</h2>
191
+ </div>
192
+ <pre id="demo-output">Заполните любую форму.</pre>
193
+ </section>
194
+
195
+ <script src="../dist/FormFather.min.js"></script>
196
+ <script src="./main.js"></script>
197
+ </body>
198
+ </html>