Skip to content

Commit 2a864ad

Browse files
Merge pull request #8 from practical-computer/thomas/pract-138-prefix-all-data-attributes-to-data-pf-errors
Prefix all `data` attributes with `data-pf-` to unify + avoid collisions
2 parents 7477efd + dd85f53 commit 2a864ad

22 files changed

+341
-341
lines changed

README.md

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,18 @@ applyErrorMappingButton.addEventListener(`click`, (event) => {
7979
<custom-error-handling>
8080
<form id="test-form" aria-describedby='test-form-error-container'>
8181
<input type="email" id="email-field" aria-describedby="email-field-errors" minlength="4">
82-
<section id="email-field-errors" data-error-container>
82+
<section id="email-field-errors" data-pf-error-container>
8383
<ul>
84-
<li data-visible data-error-type="error_1">ad-hoc error message 1 <small>(rendered on initial load)</small></li>
85-
<li data-preserve data-error-type="tooShort">Custom Preserved Error: Must be at least 4 characters<small>(rendered on initial load)</small></li>
84+
<li data-pf-error-visible data-pf-error-type="error_1">ad-hoc error message 1 <small>(rendered on initial load)</small></li>
85+
<li data-pf-error-preserve data-pf-error-type="tooShort">Custom Preserved Error: Must be at least 4 characters<small>(rendered on initial load)</small></li>
8686
</ul>
8787
</section>
8888

89-
<section id="test-form-error-container" data-error-container>
89+
<section id="test-form-error-container" data-pf-error-container>
9090
<h2>Form Errors</h2>
9191
<ul>
92-
<li data-visible data-error-type="error_2">ad-hoc error message 2 <small>(rendered on initial load)</small></li>
93-
<li data-visible data-preserve data-error-type="error_3">Preserved Error <small>(rendered on initial load)</small></li>
92+
<li data-pf-error-visible data-pf-error-type="error_2">ad-hoc error message 2 <small>(rendered on initial load)</small></li>
93+
<li data-pf-error-visible data-pf-error-preserve data-pf-error-type="error_3">Preserved Error <small>(rendered on initial load)</small></li>
9494
</ul>
9595
</section>
9696

@@ -105,7 +105,7 @@ applyErrorMappingButton.addEventListener(`click`, (event) => {
105105
<textarea id="easy-console" readonly rows=20></textarea>
106106

107107
<template id="pf-error-list-item-template">
108-
<li><span>‼️</span> <span data-error-message></span></li>
108+
<li><span>‼️</span> <span data-pf-error-message></span></li>
109109
</template>
110110
</body>
111111
```
@@ -143,18 +143,18 @@ The following terms are used for this package:
143143
The following data attributes are used by this package:
144144

145145
- Inputs
146-
- Validation Event Handling flags. This package does not provide the validations, but does provide helper functions for checks if an event handler should proceed by checking the value of `data-validation`:
147-
- `data-validation="input"`: This input should use `input` validation
148-
- `data-validation="change"`: This input should use `change` validation
149-
- `data-validation="focusout"`: This input should use `focusout` validation
150-
- `data-validation="skip"`: This input should skip any validations
151-
- `data-initial-load-errors`: If present, this input has initial load errors, which should not be cleared out when reflecting the constraint validation for the initial load.
152-
- `data-error-container`: Marks an element as an error container
146+
- Validation Event Handling flags. This package does not provide the validations, but does provide helper functions for checks if an event handler should proceed by checking the value of `data-pf-validation`:
147+
- `data-pf-validation="input"`: This input should use `input` validation
148+
- `data-pf-validation="change"`: This input should use `change` validation
149+
- `data-pf-validation="focusout"`: This input should use `focusout` validation
150+
- `data-pf-validation="skip"`: This input should skip any validations
151+
- `data-pf-initial-load-errors`: If present, this input has initial load errors, which should not be cleared out when reflecting the constraint validation for the initial load.
152+
- `data-pf-error-container`: Marks an element as an error container
153153
- Error list items
154-
- `data-visible`: Marks that the error list item should be visible
155-
- `data-error-type`: The error type for this list item (eg: `tooShort`, or `some_custom_error_type`)
156-
- `data-preserve`: This error list item should not be removed when clearing the error list; useful for rendering custom error messages for default error types. *Just because an error is preserved does not mean it is visible*
157-
- `data-error-message` Used in the error list item `template` element to indicate where an error message should be rendered in the markup as the `textContent`
154+
- `data-pf-error-visible`: Marks that the error list item should be visible
155+
- `data-pf-error-type`: The error type for this list item (eg: `tooShort`, or `some_custom_error_type`)
156+
- `data-pf-error-preserve`: This error list item should not be removed when clearing the error list; useful for rendering custom error messages for default error types. *Just because an error is preserved does not mean it is visible*
157+
- `data-pf-error-message` Used in the error list item `template` element to indicate where an error message should be rendered in the markup as the `textContent`
158158

159159
### Marking an input as invalid
160160

@@ -164,20 +164,20 @@ We use `aria-invalid="true"` to indicate that an input is invalid. This makes yo
164164

165165
To link an `input` or `form` to an error container, you:
166166

167-
- Add the error container's markup to the page, with a unique `id` and the `data-error-container` attribute
167+
- Add the error container's markup to the page, with a unique `id` and the `data-pf-error-container` attribute
168168
- Include that `id` in the `input`/`form`'s `aria-describedby`
169169

170-
We use the `aria-describedby` so that your markup is **accessible by default**. Since there can be [multiple elements that describe an element](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-describedby#id_reference_list), You specify which one is the error container using `data-error-container`.
170+
We use the `aria-describedby` so that your markup is **accessible by default**. Since there can be [multiple elements that describe an element](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-describedby#id_reference_list), You specify which one is the error container using `data-pf-error-container`.
171171

172172
#### Example
173173
```html
174174
<form id="test-form" aria-describedby='test-form-error-container'>
175175
<input type="email" id="email-field" aria-describedby="email-field-errors" minlength="4">
176-
<section id="email-field-errors" data-error-container>
176+
<section id="email-field-errors" data-pf-error-container>
177177
<ul></ul>
178178
</section>
179179

180-
<section id="test-form-error-container" data-error-container>
180+
<section id="test-form-error-container" data-pf-error-container>
181181
<h2>Form Errors</h2>
182182
<ul></ul>
183183
</section>
@@ -215,14 +215,14 @@ if (!window.customElements.get('app-error-handling')) {
215215

216216
### Handling the initial page load
217217

218-
- Render any error list items that should be visible on the initial page load with the `data-visible` attribute
218+
- Render any error list items that should be visible on the initial page load with the `data-pf-error-visible` attribute
219219
- Mark the invalid inputs with:
220220
- `aria-invalid=true`
221-
- `data-initial-load-errors`
221+
- `data-pf-initial-load-errors`
222222

223223
To reflect any other errors that might be present from the Constraint Validation API, you can use the `reflectConstraintValidationForInitialLoad` method in `@practical-computer/error-handling/element-utilities`.
224224

225-
This method will skip any `form.elements` with blank values, or the `data-initial-load-errors` attribute.
225+
This method will skip any `form.elements` with blank values, or the `data-pf-initial-load-errors` attribute.
226226

227227

228228
### Server-side errors
@@ -294,7 +294,7 @@ One of the best ways to understand this package is to glance at the source. It's
294294
- Any preserved errors for a list (or for a specific `type` of error)
295295
- Rendering helper functions, including:
296296
- Reflecting the current [`ValidityState`](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState) of an element
297-
- Applyig the `data-` and ARIA attributes to mark an element as invalid, without going through the Constraint Validation API
297+
- Applyig the `data-pf` and ARIA attributes to mark an element as invalid, without going through the Constraint Validation API
298298
- Marking an error `type` as visible for an element
299299
- Creating a new error list item element
300300
- Clearing the error list for an element, or for an entire form.
@@ -323,7 +323,7 @@ Validation is almost always application/framework dependent; and best served by
323323

324324
#### Markup for rendering errors
325325

326-
You provide the markup, using ARIA attributes, a small set of `data-` attributes, and a `template` element. Fitting error messages into a design is *tough* and extremely context specific. We trust your judgement, and render the text and set the `data-visible` attributes in the places you put us to.
326+
You provide the markup, using ARIA attributes, a small set of `data-` attributes (prefixed with `data-pf`), and a `template` element. Fitting error messages into a design is *tough* and extremely context specific. We trust your judgement, and render the text and set the `data-pf-error-visible` attributes in the places you put us to.
327327

328328
#### Automatic integrations/hooks/event handlers
329329

css/util.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
[data-error-container]:not(:has([data-visible])) {
1+
[data-pf-error-container]:not(:has([data-pf-error-visible])) {
22
display: none;
33
}
44

5-
[data-error-container] > ul > li:not([data-visible]) {
5+
[data-pf-error-container] > ul > li:not([data-pf-error-visible]) {
66
display: none;
77
}

demo/index.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
padding: 1em;
7878
}
7979

80-
[data-error-container] {
80+
[data-pf-error-container] {
8181
border: 1px solid red;
8282
}
8383
</style>
@@ -90,18 +90,18 @@ <h1>Practical Error Handling Demo</h1>
9090
<custom-error-handling>
9191
<form id="test-form" aria-describedby='test-form-error-container'>
9292
<input type="email" id="email-field" aria-describedby="email-field-errors" minlength="4">
93-
<section id="email-field-errors" data-error-container>
93+
<section id="email-field-errors" data-pf-error-container>
9494
<ul>
95-
<li data-visible data-error-type="error_1">ad-hoc error message 1 <small>(rendered on initial load)</small></li>
96-
<li data-preserve data-error-type="tooShort">Custom Preserved Error: Must be at least 4 characters<small>(rendered on initial load)</small></li>
95+
<li data-pf-error-visible data-pf-error-type="error_1">ad-hoc error message 1 <small>(rendered on initial load)</small></li>
96+
<li data-pf-error-preserve data-pf-error-type="tooShort">Custom Preserved Error: Must be at least 4 characters<small>(rendered on initial load)</small></li>
9797
</ul>
9898
</section>
9999

100-
<section id="test-form-error-container" data-error-container>
100+
<section id="test-form-error-container" data-pf-error-container>
101101
<h2>Form Errors</h2>
102102
<ul>
103-
<li data-visible data-error-type="error_2">ad-hoc error message 2 <small>(rendered on initial load)</small></li>
104-
<li data-visible data-preserve data-error-type="error_3">Preserved Error <small>(rendered on initial load)</small></li>
103+
<li data-pf-error-visible data-pf-error-type="error_2">ad-hoc error message 2 <small>(rendered on initial load)</small></li>
104+
<li data-pf-error-visible data-pf-error-preserve data-pf-error-type="error_3">Preserved Error <small>(rendered on initial load)</small></li>
105105
</ul>
106106
</section>
107107

@@ -116,7 +116,7 @@ <h2>Form Errors</h2>
116116
<textarea id="easy-console" readonly rows=20></textarea>
117117

118118
<template id="pf-error-list-item-template">
119-
<li><span>‼️</span> <span data-error-message></span></li>
119+
<li><span>‼️</span> <span data-pf-error-message></span></li>
120120
</template>
121121
</body>
122122
</html>

src/element-utilities.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,39 @@ export function generateValidationMessage(element) {
1111
}
1212

1313
/**
14-
* Checks if the given `element` has `data-validation == "input"`
14+
* Checks if the given `element` has `data-pf-validation == "input"`
1515
* @param {Element} element
16-
* @return {boolean} Returns true if the element does not have `data-validation == "input"`
16+
* @return {boolean} Returns true if the element does not have `data-pf-validation == "input"`
1717
*/
1818
export function skipInputValidation(element) {
19-
return !(element.getAttribute(`data-validation`) === "input")
19+
return !(element.getAttribute(`data-pf-validation`) === "input")
2020
}
2121

2222
/**
23-
* Checks if the given `element` has `data-validation == "change"`
23+
* Checks if the given `element` has `data-pf-validation == "change"`
2424
* @param {Element} element
25-
* @return {boolean} Returns true if the element does not have `data-validation == "change"`
25+
* @return {boolean} Returns true if the element does not have `data-pf-validation == "change"`
2626
*/
2727
export function skipChangeValidation(element) {
28-
return !(element.getAttribute(`data-validation`) === "change")
28+
return !(element.getAttribute(`data-pf-validation`) === "change")
2929
}
3030

3131
/**
32-
* Checks if the given `element` has `data-validation == "focusout"`
32+
* Checks if the given `element` has `data-pf-validation == "focusout"`
3333
* @param {Element} element
34-
* @return {boolean} Returns true if the element does not have `data-validation == "focusout"`
34+
* @return {boolean} Returns true if the element does not have `data-pf-validation == "focusout"`
3535
*/
3636
export function skipFocusoutValidation(element) {
37-
return !(element.getAttribute(`data-validation`) === "focusout")
37+
return !(element.getAttribute(`data-pf-validation`) === "focusout")
3838
}
3939

4040
/**
41-
* Checks if the given `element` given `element` has `data-validation == "skip"`
41+
* Checks if the given `element` given `element` has `data-pf-validation == "skip"`
4242
* @param {Element} element
43-
* @return {boolean} Returns true if the element has `data-validation == "change"`
43+
* @return {boolean} Returns true if the element has `data-pf-validation == "change"`
4444
*/
4545
export function skipValidation(element) {
46-
return (element.getAttribute(`data-validation`) === "skip")
46+
return (element.getAttribute(`data-pf-validation`) === "skip")
4747
}
4848

4949
/**
@@ -74,12 +74,12 @@ export function setValidityStateAttributes(element, isValid) {
7474

7575
/**
7676
* Used for the initial loading of the given `form`, calls {@link reflectConstraintValidationForElement} for each
77-
* non-blank item in `form.element` that does not have a `data-initial-load-errors`
77+
* non-blank item in `form.element` that does not have a `data-pf-initial-load-errors`
7878
* @params {FormElement} form the form to reflect the initial Constraint Validation state for
7979
*/
8080
export function reflectConstraintValidationForInitialLoad(form) {
8181
for(const element of form.elements) {
82-
if(element.hasAttribute(`data-initial-load-errors`)) {
82+
if(element.hasAttribute(`data-pf-initial-load-errors`)) {
8383
continue; // do not change any elements that have server-side errors
8484
}
8585
if(element.value !=="" ){

src/error-containers.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ import { generateValidationMessage } from './element-utilities.js'
33

44
/**
55
* Returns the ID for the given `element`'s `aria-describedby` attribute of the element that has a
6-
* `data-error-container` attribute`
6+
* `data-pf-error-container` attribute`
77
* @param {Element} element
8-
* @returns {string|undefined} the `aria-describedby` attribute if present and the element has the `data-error-container` attribute`
8+
* @returns {string|undefined} the `aria-describedby` attribute if present and the element has the `data-pf-error-container` attribute`
99
*/
1010
export function getErrorContainerID(element) {
1111
const errorContainerID = element.getAttribute(`aria-describedby`)
1212
if(!errorContainerID || errorContainerID == ''){ return }
1313

1414
return errorContainerID.split(" ").find((x) => {
15-
return document.getElementById(x)?.hasAttribute(`data-error-container`)
15+
return document.getElementById(x)?.hasAttribute(`data-pf-error-container`)
1616
})
1717
}
1818

@@ -53,16 +53,16 @@ export function getErrorListFromContainer(container) {
5353
}
5454

5555
/**
56-
* Returns the `NodeList` of elements inside the given `errorListElement` with `data-preserve`
56+
* Returns the `NodeList` of elements inside the given `errorListElement` with `data-pf-error-preserve`
5757
* @param {Element} element
58-
* @returns {NodeList} All elements with the `data-preserve` attribute
58+
* @returns {NodeList} All elements with the `data-pf-error-preserve` attribute
5959
*/
6060
export function getPreservedErrors(errorListElement) {
61-
return errorListElement.querySelectorAll(`:scope > [data-preserve]`)
61+
return errorListElement.querySelectorAll(`:scope > [data-pf-error-preserve]`)
6262
}
6363

6464
/**
65-
* Checks the given `errorListElement` for any preserved errors ({@link getPreservedErrors}) where the `data-error-type`
65+
* Checks the given `errorListElement` for any preserved errors ({@link getPreservedErrors}) where the `data-pf-error-type`
6666
* matches` `type`
6767
* @params {Element} {@link getErrorList}
6868
* @params {string} type the error type
@@ -73,35 +73,35 @@ export function hasPreservedErrorForType(errorListElement, type) {
7373
}
7474

7575
/**
76-
* Checks the given `errorListElement` for any preserved errors ({@link getPreservedErrors}) where the `data-error-type`
76+
* Checks the given `errorListElement` for any preserved errors ({@link getPreservedErrors}) where the `data-pf-error-type`
7777
* matches` `type` and returns the first match if present
7878
* @params {Element} {@link getErrorList}
7979
* @params {string} type the error type
8080
* @returns {Element|null}
8181
*/
8282
export function getPreservedErrorForType(errorListElement, type) {
8383
return [...getPreservedErrors(errorListElement)].find((x) => {
84-
return x.getAttribute(`data-error-type`)?.toString() == type.toString()
84+
return x.getAttribute(`data-pf-error-type`)?.toString() == type.toString()
8585
})
8686
}
8787

8888
/**
89-
* Marks the given element as a preserved error message, with the `data-preserve` attribute
89+
* Marks the given element as a preserved error message, with the `data-pf-error-preserve` attribute
9090
* @params {Element} element the error element to mark as preserved
9191
*/
9292
export function markAsPreservedError(element) {
93-
element.setAttribute(`data-preserve`, true)
93+
element.setAttribute(`data-pf-error-preserve`, true)
9494
}
9595

9696
/**
97-
* Returns the `element` that has the given `data-error-type` if it's present.
97+
* Returns the `element` that has the given `data-pf-error-type` if it's present.
9898
* @params {Element} {@link getErrorList}
9999
* @params {string} type the error type
100100
* @returns {Element|null}
101101
*/
102102
export function getErrorForType(errorListElement, type) {
103-
return [...errorListElement.querySelectorAll(`[data-error-type]`)].find((x) => {
104-
return x.getAttribute(`data-error-type`)?.toString() == type.toString()
103+
return [...errorListElement.querySelectorAll(`[data-pf-error-type]`)].find((x) => {
104+
return x.getAttribute(`data-pf-error-type`)?.toString() == type.toString()
105105
})
106106
}
107107

src/error-mapping.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import {
3030
* @param {string} errors[].container_id - The ID of the container this error message should be rendered in
3131
* @param {string} errors[].element_id - The ID of the element to call {@link setValidityStateAttributes} with `false` for
3232
* @param {string} errors[].message - the error message
33-
* @param {string} errors[].type - the value for `data-error-type` that represents the type of error this is
33+
* @param {string} errors[].type - the value for `data-pf-error-type` that represents the type of error this is
3434
*
3535
* @example
3636
* // For example, a JSON response from a fetch request

src/event-handlers.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function validateFormSubmitEventHandler(event) {
3535

3636
/**
3737
* Calls {@link reflectConstraintValidationForElement} if the `event.target` has
38-
* `data-validation="input"` and does not have `data-skip-validation`
38+
* `data-pf-validation="input"`
3939
*
4040
* @param {Event} event
4141
*/
@@ -48,7 +48,7 @@ export function inputValidationEventHandler(event) {
4848

4949
/**
5050
* Calls {@link reflectConstraintValidationForElement} if the `event.target` has
51-
* `data-validation="focusout"` and does not have `data-skip-validation`
51+
* `data-pf-validation="focusout"`
5252
* @param {Event} event
5353
*/
5454
export function focusoutValidationEventHandler(event) {

0 commit comments

Comments
 (0)