@cocreate/validation 1.19.0 → 2.0.0

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/CONTRIBUTING.md CHANGED
@@ -1,19 +1,19 @@
1
1
  # Contributing to CoCreate-validation
2
2
 
3
- This project is work of [many contributors](https://github.com/CoCreate-app/CoCreate-validation/graphs/contributors).
4
- You're encouraged to submit [pull requests](https://github.com/CoCreate-app/CoCreate-validation/pulls),
5
- [propose features and discuss issues](https://github.com/CoCreate-app/CoCreate-validation/issues).
3
+ This project is work of [many contributors](https://github.com/CoCreateJS/validation/graphs/contributors).
4
+ You're encouraged to submit [pull requests](https://github.com/CoCreateJS/validation/pulls),
5
+ [propose features and discuss issues](https://github.com/CoCreateJS/validation/issues).
6
6
 
7
7
  In the examples below, substitute your Github username for `contributor` in URLs.
8
8
 
9
9
  ## Fork the Project
10
10
 
11
- Fork the [project on Github](https://github.com/CoCreate-app/CoCreate-validation) and check out your copy.
11
+ Fork the [project on Github](https://github.com/CoCreateJS/validation) and check out your copy.
12
12
 
13
13
  ```
14
14
  git clone https://github.com/contributor/CoCreate-validation.git
15
15
  cd CoCreate-validation
16
- git remote add upstream https://github.com/CoCreate-app/CoCreate-validation.git
16
+ git remote add upstream https://github.com/CoCreateJS/validation.git
17
17
  ```
18
18
 
19
19
  ## Create a Topic Branch
@@ -75,7 +75,7 @@ git push origin my-feature-branch
75
75
 
76
76
  ## Make a Pull Request
77
77
 
78
- Go to [https://github.com/CoCreate-app/CoCreate-validation](https://github.com/CoCreate-app/CoCreate-validation) and select your feature branch.
78
+ Go to [https://github.com/CoCreateJS/validation](https://github.com/CoCreateJS/validation) and select your feature branch.
79
79
  Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days.
80
80
 
81
81
  ## Rebase
package/README.md CHANGED
@@ -1,91 +1,142 @@
1
- # CoCreate-validation
2
-
3
- A simple validation component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API. Take it for a spin in our [playground!](https://cocreate.app/docs/validation)
4
-
5
- ![min file size in bytes](https://img.badgesize.io/https://cdn.cocreate.app/validation/latest/CoCreate-validation.min.js?style=flat-square&label=minified&color=orange)
6
- ![gzip file size in bytes](https://img.badgesize.io/https://cdn.cocreate.app/validation/latest/CoCreate-validation.min.js?compression=gzip&style=flat-square&label=gzip&color=yellow)
7
- ![brotlifile size in bytes](https://img.badgesize.io/https://cdn.cocreate.app/validation/latest/CoCreate-validation.min.js?compression=brotli&style=flat-square&label=brotli)
8
- ![GitHub latest release](https://img.shields.io/github/v/release/CoCreate-app/CoCreate-validation?style=flat-square)
9
- ![GitHub](https://img.shields.io/github/license/CoCreate-app/CoCreate-validation?style=flat-square)
10
- ![GitHub](https://img.shields.io/static/v1?style=flat-square&label=&message=Hiring&color=blueviolet)
11
-
12
- ![CoCreate-validation](https://cdn.cocreate.app/docs/CoCreate-validation.gif)
13
-
14
- ## [Docs & Demo](https://cocreate.app/docs/validation)
15
-
16
- For a complete guide and working demo refer to the [doumentation](https://cocreate.app/docs/validation)
17
-
18
- ## CDN
19
-
20
- ```html
21
- <script src="https://cdn.cocreate.app/validation/latest/CoCreate-validation.min.js"></script>
22
- ```
23
-
24
- ```html
25
- <script src="https://cdn.cocreate.app/validation/latest/CoCreate-validation.min.css"></script>
26
- ```
27
-
28
- ## NPM
29
-
30
- ```shell
31
- $ npm i @cocreate/validation
32
- ```
33
-
34
- ## yarn
35
-
36
- ```shell
37
- $ yarn install @cocreate/validation
38
- ```
39
-
40
- # Table of Contents
41
-
42
- - [Table of Contents](#table-of-contents)
43
- - [Announcements](#announcements)
44
- - [Roadmap](#roadmap)
45
- - [How to Contribute](#how-to-contribute)
46
- - [About](#about)
47
- - [License](#license)
48
-
49
- <a name="announcements"></a>
50
-
51
- # Announcements
52
-
53
- All updates to this library are documented in our [CHANGELOG](https://github.com/CoCreate-app/CoCreate-validation/blob/master/CHANGELOG.md) and [releases](https://github.com/CoCreate-app/CoCreate-validation/releases). You may also subscribe to email for releases and breaking changes.
54
-
55
- <a name="roadmap"></a>
56
-
57
- # Roadmap
58
-
59
- If you are interested in the future direction of this project, please take a look at our open [issues](https://github.com/CoCreate-app/CoCreate-validation/issues) and [pull requests](https://github.com/CoCreate-app/CoCreate-validation/pulls). We would love to hear your feedback.
60
-
61
- <a name="about"></a>
62
-
63
- # About
64
-
65
- CoCreate-validation is guided and supported by the CoCreate Developer Experience Team.
66
-
67
- Please Email the Developer Experience Team [here](mailto:develop@cocreate.app) in case of any queries.
68
-
69
- CoCreate-validation is maintained and funded by CoCreate. The names and logos for CoCreate are trademarks of CoCreate, LLC.
70
-
71
- <a name="contribute"></a>
72
-
73
- # How to Contribute
74
-
75
- We encourage contribution to our libraries (you might even score some nifty swag), please see our [CONTRIBUTING](https://github.com/CoCreate-app/CoCreate-validation/blob/master/CONTRIBUTING.md) guide for details.
76
-
77
- We want this library to be community-driven, and CoCreate led. We need your help to realize this goal. To help make sure we are building the right things in the right order, we ask that you create [issues](https://github.com/CoCreate-app/CoCreate-validation/issues) and [pull requests](https://github.com/CoCreate-app/CoCreate-validation/pulls) or merely upvote or comment on existing issues or pull requests.
78
-
79
- We appreciate your continued support, thank you!
80
-
81
- <a name="license"></a>
82
-
83
- # License
84
-
85
- This software is dual-licensed under the GNU Affero General Public License version 3 (AGPLv3) and a commercial license.
86
-
87
- - **Open Source Use**: For open-source projects and non-commercial use, this software is available under the AGPLv3. The AGPLv3 allows you to freely use, modify, and distribute this software, provided that all modifications and derivative works are also licensed under the AGPLv3. For the full license text, see the [LICENSE file](https://github.com/CoCreate-app/CoCreate-validation/blob/master/LICENSE).
88
-
89
- - **Commercial Use**: For-profit companies and individuals intending to use this software for commercial purposes must obtain a commercial license. The commercial license is available when you sign up for an API key on our [website](https://cocreate.app). This license permits proprietary use and modification of the software without the copyleft requirements of the AGPLv3. It is ideal for integrating this software into proprietary commercial products and applications.
90
-
91
- If you have not purchased a commercial license and intend to use this software for commercial purposes, you are required to sign up for an API key on our website.
1
+ # CoCreate-validation
2
+
3
+ A simple validation component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API. Take it for a spin in our [playground!](https://CoCreateJS.com/docs/validation)
4
+
5
+ ![min file size in bytes](https://img.badgesize.io/https://cdn.CoCreateJS.com/validation/latest/CoCreate-validation.min.js?style=flat-square&label=minified&color=orange)
6
+ ![gzip file size in bytes](https://img.badgesize.io/https://cdn.CoCreateJS.com/validation/latest/CoCreate-validation.min.js?compression=gzip&style=flat-square&label=gzip&color=yellow)
7
+ ![brotlifile size in bytes](https://img.badgesize.io/https://cdn.CoCreateJS.com/validation/latest/CoCreate-validation.min.js?compression=brotli&style=flat-square&label=brotli)
8
+ ![GitHub latest release](https://img.shields.io/github/v/release/CoCreateJS/validation?style=flat-square)
9
+ ![GitHub](https://img.shields.io/github/license/CoCreateJS/validation?style=flat-square)
10
+ ![GitHub](https://img.shields.io/static/v1?style=flat-square&label=&message=Hiring&color=blueviolet)
11
+
12
+ ![CoCreate-validation](https://cdn.CoCreateJS.com/docs/CoCreate-validation.gif)
13
+
14
+ ## [Docs & Demo](https://CoCreateJS.com/docs/validation)
15
+
16
+ For a complete guide and working demo refer to the [doumentation](https://CoCreateJS.com/docs/validation)
17
+
18
+ ## CDN
19
+
20
+ ```html
21
+ <script src="https://cdn.CoCreateJS.com/validation/latest/CoCreate-validation.min.js"></script>
22
+ ```
23
+
24
+ ```html
25
+ <script src="https://cdn.CoCreateJS.com/validation/latest/CoCreate-validation.min.css"></script>
26
+ ```
27
+
28
+ ## NPM
29
+
30
+ ```shell
31
+ $ npm i @cocreate/validation
32
+ ```
33
+
34
+ ## yarn
35
+
36
+ ```shell
37
+ $ yarn install @cocreate/validation
38
+ ```
39
+
40
+ # Table of Contents
41
+
42
+ - [Table of Contents](#table-of-contents)
43
+ - [Announcements](#announcements)
44
+ - [Roadmap](#roadmap)
45
+ - [How to Contribute](#how-to-contribute)
46
+ - [About](#about)
47
+ - [License](#license)
48
+
49
+ <a name="announcements"></a>
50
+
51
+ # Announcements
52
+
53
+ All updates to this library are documented in our [CHANGELOG](https://github.com/CoCreateJS/validation/blob/master/CHANGELOG.md) and [releases](https://github.com/CoCreateJS/validation/releases). You may also subscribe to email for releases and breaking changes.
54
+
55
+ <a name="roadmap"></a>
56
+
57
+ # Roadmap
58
+
59
+ If you are interested in the future direction of this project, please take a look at our open [issues](https://github.com/CoCreateJS/validation/issues) and [pull requests](https://github.com/CoCreateJS/validation/pulls). We would love to hear your feedback.
60
+
61
+ <a name="about"></a>
62
+
63
+ # About
64
+
65
+ CoCreate-validation is guided and supported by the CoCreate Developer Experience Team.
66
+
67
+ Please Email the Developer Experience Team [here](mailto:develop@CoCreateJS.com) in case of any queries.
68
+
69
+ CoCreate-validation is maintained and funded by CoCreate. The names and logos for CoCreate are trademarks of CoCreate, LLC.
70
+
71
+ <a name="contribute"></a>
72
+
73
+ # How to Contribute
74
+
75
+ We encourage contribution to our libraries (you might even score some nifty swag), please see our [CONTRIBUTING](https://github.com/CoCreateJS/validation/blob/master/CONTRIBUTING.md) guide for details.
76
+
77
+ We want this library to be community-driven, and CoCreate led. We need your help to realize this goal. To help make sure we are building the right things in the right order, we ask that you create [issues](https://github.com/CoCreateJS/validation/issues) and [pull requests](https://github.com/CoCreateJS/validation/pulls) or merely upvote or comment on existing issues or pull requests.
78
+
79
+ We appreciate your continued support, thank you!
80
+
81
+ <a name="license"></a>
82
+
83
+ # License
84
+
85
+ This software is dual-licensed under the GNU Affero General Public License version 3 (AGPLv3) and a commercial license.
86
+
87
+ - **Open Source Use**: For open-source projects and non-commercial use, this software is available under the AGPLv3. The AGPLv3 allows you to freely use, modify, and distribute this software, provided that all modifications and derivative works are also licensed under the AGPLv3. For the full license text, see the [LICENSE file](https://github.com/CoCreateJS/validation/blob/master/LICENSE).
88
+
89
+ - **Commercial Use**: For-profit companies and individuals intending to use this software for commercial purposes must obtain a commercial license. The commercial license is available when you sign up for an API key on our [website](https://CoCreateJS.com). This license permits proprietary use and modification of the software without the copyleft requirements of the AGPLv3. It is ideal for integrating this software into proprietary commercial products and applications.
90
+
91
+ If you have not purchased a commercial license and intend to use this software for commercial purposes, you are required to sign up for an API key on our website.
92
+
93
+
94
+ ### Action lifecycle and native constraints
95
+
96
+ Use `actions="disabled, validate, save, disabled"` to disable the button while
97
+ validating and saving, then explicitly enable it on success. Validation failure
98
+ or an exception calls `action.abort()`, which releases a button disabled by that
99
+ chain. Validation success calls `action.end()` and continues the chain.
100
+
101
+ Native controls use the browser constraint validation API for `required`, input
102
+ types, `pattern`, ranges, and other supported constraints. Custom messages set
103
+ with `element.setCustomValidity(message)` are preserved; clear them with
104
+ `element.setCustomValidity("")` when resolved. Fields with `aria-errormessage` display errors in their referenced elements.
105
+ Without a valid target, errors render into `template="notification"` and the first
106
+ invalid native field reports its browser message.
107
+ Disabled controls and controls barred from native validation are skipped.
108
+ `novalidate` on the form or `formnovalidate` on the action element skips the native
109
+ checks; explicitly configured CoCreate rules still run.
110
+
111
+ Custom `matches` validators are awaited. A `valid="false"` value marks the
112
+ element invalid; `valid="true"` passes this rule. Validation writes its
113
+ combined result to `validation` and `aria-invalid`. Use native `required`,
114
+ `type="email"`, `pattern`, and `minlength`/`maxlength` attributes for browser
115
+ constraints; the custom `email`, `subdomain`, and `length` attributes have been
116
+ removed. Non-native elements need their own custom validation.
117
+ Each validator registered in `validations` receives its matching elements and
118
+ returns an array of failed elements (or nothing on success). Results are combined
119
+ so one passing rule cannot erase another rule's failure. `validation` and
120
+ `aria-invalid` reflect the combined result. Non-native elements can still use
121
+ CoCreate attributes and `getValue()`. `validate(selector)` scopes validation to
122
+ the matching elements and their descendants.
123
+
124
+ ### Inline field errors
125
+
126
+ ```html
127
+ <label for="email">Email</label>
128
+ <input id="email" type="email" required aria-errormessage="email-error" />
129
+ <span id="email-error" hidden></span>
130
+ ```
131
+
132
+ Native and CoCreate validation messages use this same explicit relationship.
133
+ Validation reveals the target and updates `aria-invalid`; successful revalidation
134
+ clears and hides the message. `aria-describedby` help text is left intact.
135
+ Messages are inserted as text, not HTML. Linked errors do not also generate a
136
+ notification. Missing targets fall back to notifications.
137
+
138
+ Custom validators may accept a second `report` callback and call
139
+ `report({ data: [{ type: "rule", status: "error", success: false,
140
+ message: "Explain the error", elements: failedElements }] })` before returning
141
+ `failedElements`. The action collects these reports and presents the first
142
+ reported error per field after all rules finish.
package/demo/index.html CHANGED
@@ -14,7 +14,7 @@
14
14
  </head>
15
15
 
16
16
  <body>
17
- <!--<script src="https://cdn.cocreate.app/validation/latest/CoCreate-validation.min.js"></script>-->
18
- <script src="https://CoCreate.app/dist/CoCreate.js"></script>
17
+ <!--<script src="https://cdn.CoCreateJS.com/validation/latest/CoCreate-validation.min.js"></script>-->
18
+ <script src="https://CoCreateJS.com/dist/CoCreate.js"></script>
19
19
  </body>
20
20
  </html>
package/docs/index.html CHANGED
@@ -9,7 +9,7 @@
9
9
  rel="icon"
10
10
  type="image/png"
11
11
  sizes="32x32"
12
- href="https://cocreate.app/images/favicon.ico" />
12
+ href="https://CoCreateJS.com/images/favicon.ico" />
13
13
  <meta
14
14
  name="description"
15
15
  content="A simple HTML5 and pure javascript component. Easy configuration using HTML5 attributes or Javscript api and highly styleable." />
@@ -68,7 +68,7 @@
68
68
  share-width="500"
69
69
  share-media="https://via.placeholder.com/300/09f/fff.png">
70
70
  <a
71
- href="https://github.com/CoCreate-app/CoCreate-validation"
71
+ href="https://github.com/CoCreateJS/CoCreate-validation"
72
72
  target="_blank"
73
73
  class="margin-right:15px"
74
74
  ><i src="/assets/svg/github.svg"></i
@@ -112,7 +112,7 @@
112
112
  <pre
113
113
  class="margin-top:15px"><code class="language-javascript">npm install cocreate-validation</code></pre>
114
114
  <p class="padding:10px_0px">Or you can use cdn link:</p>
115
- <pre><code class="language-javascript">https://cdn.cocreate.app/js/CoCreate-validation.min.js</code></pre>
115
+ <pre><code class="language-javascript">https://cdn.CoCreateJS.com/js/CoCreate-validation.min.js</code></pre>
116
116
 
117
117
  <h2
118
118
  class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
@@ -258,6 +258,6 @@
258
258
  </div>
259
259
  </div>
260
260
  </main>
261
- <script src="https://CoCreate.app/dist/CoCreate.js"></script>
261
+ <script src="https://CoCreateJS.com/dist/CoCreate.js"></script>
262
262
  </body>
263
263
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/validation",
3
- "version": "1.19.0",
3
+ "version": "2.0.0",
4
4
  "description": "A simple validation component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "validation",
@@ -22,25 +22,26 @@
22
22
  },
23
23
  "repository": {
24
24
  "type": "git",
25
- "url": "git+https://github.com/CoCreate-app/CoCreate-validation.git"
25
+ "url": "git+https://github.com/CoCreateJS/validation.git"
26
26
  },
27
27
  "author": "CoCreate LLC",
28
28
  "license": "AGPL-3.0",
29
29
  "bugs": {
30
- "url": "https://github.com/CoCreate-app/CoCreate-validation/issues"
30
+ "url": "https://github.com/CoCreateJS/validation/issues"
31
31
  },
32
- "homepage": "https://cocreate.app/docs/validation",
32
+ "homepage": "https://CoCreateJS.com/docs/validation",
33
33
  "funding": {
34
34
  "type": "GitHub Sponsors ❤",
35
- "url": "https://github.com/sponsors/CoCreate-app"
35
+ "url": "https://github.com/sponsors/CoCreateJS"
36
36
  },
37
37
  "main": "./src/index.js",
38
38
  "dependencies": {
39
- "@cocreate/actions": "^1.23.0",
40
- "@cocreate/render": "^1.49.2"
39
+ "@cocreate/actions": "^1.24.0",
40
+ "@cocreate/element-prototype": "^1.35.0",
41
+ "@cocreate/render": "^1.51.0"
41
42
  },
42
43
  "devDependencies": {
43
- "@cocreate/webpack": "^1.7.0"
44
+ "@cocreate/webpack": "^1.9.0"
44
45
  },
45
46
  "allowScripts": {
46
47
  "@cocreate/actions@1.21.4": true,
package/src/index.js CHANGED
@@ -5,83 +5,198 @@
5
5
  * SPDX-License-Identifier: MIT
6
6
  ********************************************************************************/
7
7
 
8
- /*globals CustomEvent*/
9
- import actions from "@cocreate/actions";
10
- // import render from '@cocreate/render';
11
- import { matches } from "./validations/matches";
12
- import { required } from "./validations/required";
13
- import { unique } from "./validations/unique";
14
- import { subdomain } from "./validations/subdomain";
15
- import { length } from "./validations/length";
16
- import { email } from "./validations/email";
8
+ import actions from "@cocreate/actions";
9
+ import "@cocreate/element-prototype";
10
+ import { render } from "@cocreate/render";
11
+ import { clearError, errorTargets, renderErrors } from "./messages.js";
12
+ import { matches } from "./validations/matches.js";
13
+ import { value } from "./validations/value.js";
14
+
15
+ /**
16
+ *
17
+ * @public
18
+ * @environment client
19
+ */
20
+ const validations = new Map();
21
+ validations.set("matches", matches);
22
+ validations.set("valid", validState);
23
+ validations.set("validate", value);
17
24
 
18
- const validations = new Map();
19
- validations.set("matches", matches);
20
- validations.set("required", required);
21
- validations.set("subdomain", subdomain);
22
- validations.set("unique", unique);
23
- validations.set("length", length);
24
- validations.set("email", email);
25
+ function validState(elements, report = renderErrors) {
26
+ const failedElements = elements.filter(element => element.getAttribute("valid") === "false");
25
27
 
26
- const selectors =
27
- "[matches], [required], [unique], [subdomain], [length], [email]";
28
+ if (failedElements.length) {
29
+ report({
30
+ data: failedElements.map(element => ({
31
+ type: "valid",
32
+ status: "error",
33
+ success: false,
34
+ message: element.validationMessage || "This value is not valid.",
35
+ elements: [element]
36
+ }))
37
+ });
38
+ return failedElements;
39
+ }
40
+ }
28
41
 
29
42
  async function validate(action) {
30
- let btn = action.element;
31
- let params = action.params;
32
- let validateElements;
33
- let validateSelectors = [];
34
- let failedElements = [];
43
+ try {
44
+ const selectors = [...validations.keys()].map(name => `[${name}]`).concat("[component][required]").join(", ");
45
+ const candidates = new Set();
46
+ const form = action.element.form || action.form || action.element.closest("form");
47
+ const roots = action.params ? document.querySelectorAll(action.params) : [form];
48
+ if (!roots.length || !roots[0]) throw new Error("No validation target found");
35
49
 
36
- if (params) {
37
- let selector = params;
38
- for (let [validation] of validations) {
39
- let vSelctor = `${selector}[${validation}]`;
40
- validateSelectors.push(vSelctor);
41
- }
42
- let validSelectors = validateSelectors.join(", ");
43
- validateElements = document.querySelectorAll(validSelectors);
44
- if (!validateElements.length) {
45
- let element = document.querySelector(selector);
46
- if (element) validateElements = element.querySelectorAll(selectors);
47
- }
48
- } else {
49
- let element = btn.closest("form");
50
- validateElements = element.querySelectorAll(selectors);
51
- }
50
+ for (const root of roots) {
51
+ if (root.matches(selectors) || root.willValidate) candidates.add(root);
52
+ for (const element of root.querySelectorAll(selectors)) candidates.add(element);
53
+ for (const element of root.elements || root.querySelectorAll("input, select, textarea, button")) {
54
+ candidates.add(element);
55
+ }
56
+ }
57
+ const elements = [...candidates].filter(element =>
58
+ !element.closest("[template]") &&
59
+ !element.matches(":disabled") && element.willValidate !== false
60
+ );
61
+ const failed = new Set();
62
+ const nativeEnabled = !form?.noValidate && !action.element.formNoValidate;
63
+ if (nativeEnabled) {
64
+ for (const element of elements) {
65
+ if (element.willValidate && !element.checkValidity()) failed.add(element);
66
+ if (element.hasAttribute("required")) {
67
+ const value = await element.getValue();
68
+ if (value == null || value === "" || Array.isArray(value) && !value.length)
69
+ failed.add(element);
70
+ }
71
+ }
72
+ if (failed.size) {
73
+ for (const element of elements) markValidity(element, !failed.has(element));
74
+ action.abort();
75
+ const first = failed.values().next().value;
76
+ renderErrors({
77
+ data: [...failed].map(element => ({
78
+ type: "validate", status: "error", success: false,
79
+ message: element.validationMessage || "A value is required.", elements: [element]
80
+ }))
81
+ });
82
+ if (errorTargets(first).length) first.focus();
83
+ else first.reportValidity?.();
84
+ return;
85
+ }
86
+ }
52
87
 
53
- for (let [validation, func] of validations) {
54
- let elements = [];
55
- for (let element of validateElements) {
56
- // let validationSelectors = element.getAttribute('validate').replace(/ /g, '').split(',');
57
- if (element.hasAttribute(validation)) {
58
- elements.push(element);
59
- }
60
- }
61
- if (elements.length) {
62
- let failedEls = await func(elements);
63
- if (failedEls) failedElements.push(failedEls);
64
- }
65
- }
66
- for (let element of validateElements) {
67
- let isValid = element.getAttribute("validation");
68
- if (isValid == "false") failedElements.push(element);
69
- }
88
+ const errors = [];
89
+ for (const [name, validator] of validations) {
90
+ const targets = elements.filter(element => element.hasAttribute(name));
91
+ if (!targets.length) continue;
92
+ const failures = await validator(targets, ({ data }) => errors.push(...data));
93
+ if (failures) for (const element of failures) failed.add(element);
94
+ }
95
+ for (const element of elements) markValidity(element, !failed.has(element));
96
+ if (failed.size) {
97
+ action.abort();
98
+ renderErrors({ data: errors });
99
+ failed.values().next().value.focus?.();
100
+ } else {
101
+ action.end();
102
+ }
103
+ } catch (error) {
104
+ action.abort();
105
+ render({
106
+ selector: '[template~="notification"]',
107
+ data: [{ type: "validate", status: "error", success: false,
108
+ message: error.message || "Unable to validate the form. Please try again." }]
109
+ });
110
+ }
111
+ }
70
112
 
71
- if (failedElements.length == 0) {
72
- btn.dispatchEvent(
73
- new CustomEvent("validate", {
74
- detail: {}
75
- })
76
- );
77
- }
113
+ function markValidity(element, valid) {
114
+ const state = String(valid);
115
+ element.setAttribute("validation", state);
116
+ element.setAttribute("aria-invalid", String(!valid));
117
+ if (valid) clearError(element);
78
118
  }
79
119
 
80
- actions.init({
81
- name: "validate",
82
- callback: (action) => {
83
- validate(action);
84
- }
85
- });
120
+ actions.init({ name: "validate", callback: validate });
86
121
 
87
122
  export default { validations };
123
+
124
+ /**
125
+ *
126
+ * @name aria-errormessage
127
+ * @kind member
128
+ * @attribute
129
+ * @environment client
130
+ */
131
+
132
+ /**
133
+ *
134
+ * @name aria-invalid
135
+ * @kind member
136
+ * @attribute
137
+ * @environment client
138
+ */
139
+
140
+ /**
141
+ *
142
+ * @name match
143
+ * @kind member
144
+ * @attribute
145
+ * @environment client
146
+ */
147
+
148
+ /**
149
+ *
150
+ * @name match-query
151
+ * @kind member
152
+ * @attribute
153
+ * @environment client
154
+ */
155
+
156
+ /**
157
+ *
158
+ * @name required
159
+ * @kind member
160
+ * @attribute
161
+ * @environment client
162
+ */
163
+
164
+ /**
165
+ *
166
+ * @name valid
167
+ * @kind member
168
+ * @attribute
169
+ * @environment client
170
+ */
171
+
172
+ /**
173
+ *
174
+ * @name validation
175
+ * @kind member
176
+ * @attribute
177
+ * @environment client
178
+ */
179
+
180
+ /**
181
+ * A simple validation component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.
182
+ *
183
+ * @module validation
184
+ * @environment client
185
+ */
186
+
187
+ /**
188
+ * Declarative selectors recognized by this module.
189
+ *
190
+ * @name declarative-selectors
191
+ * @kind member
192
+ * @selectors
193
+ * @environment client
194
+ * @example
195
+ * ```json
196
+ * [
197
+ * "[template~=\"notification\"]",
198
+ * "[match-query][match=\"false\"]",
199
+ * "[valid=\"false\"]"
200
+ * ]
201
+ * ```
202
+ */