Skip to content

Commit 3630a86

Browse files
authored
Merge pull request #1250 from Patternslib/validation-maint
Validation maintainence
2 parents 3e2ef51 + 8354615 commit 3630a86

File tree

3 files changed

+1432
-1390
lines changed

3 files changed

+1432
-1390
lines changed

src/pat/validation/documentation.md

+84-42
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
## Description
22

3-
This pattern provides form validation based on the HTML standard and offers extended functionality like custom error messages and extra validation rules.
4-
3+
This pattern provides form validation with standard HTML validation attributes,
4+
extra validation rules, custom error messages and a custom error template. It
5+
is based HTML form validation framework and therefor supports form state
6+
checking via CSS peudo classes like `:valid` and `:invalid`.
57

68
## Documentation
79

@@ -10,13 +12,23 @@ The rest is handled mostly with standard HTML validation attributes.
1012

1113
This patterns offers:
1214

13-
- extra validation rules like checking for equality or checking is one date it after another.
14-
- custom error messages.
15+
- Custom error messages for the standard HTML validation attributes.
16+
- Custom error template to display error messages.
17+
- Extra validation rules where the standard HTML validation attributes are not enough.
18+
19+
These extra validation rules are:
20+
21+
- Equality checking between two fields (e.g. password confirmation).
22+
- Date and datetime validation for before and after a given date or another input field.
1523

16-
Since it is based on the HTML standard you can still use the `:valid`, `:invalid` and `:out-of-range` CSS pseudo classes.
1724

18-
You can use any HTML form validation attributes but here are some examples:
25+
### HTML form validation framework integration.
1926

27+
This pattern uses the [JavaScript Constraint Validation API](https://developer.mozilla.org/en-US/docs/Web/HTML/Guides/Constraint_validation).
28+
Valid formns or inputs can be selected with the `:valid` pseudo class, invalid ones with the `:invalid` pseudo class.
29+
30+
31+
### Validation rules
2032

2133
| Name | Syntax | Description |
2234
| ------------- | -------------------------- | ------------------------------------------------------------ |
@@ -31,64 +43,94 @@ You can use any HTML form validation attributes but here are some examples:
3143
> **_NOTE:_** The form inputs must have a `name` attribute, otherwise the validation would not happen.
3244
3345

34-
### Error messages
46+
### Custom error messages
3547

36-
Error messages are inserted into the DOM as `em` elements with a `message warning` class.
37-
For most input elements error messages are inserted immediately after the input element.
38-
In addition both the input element and its label will get an `warning` class.
48+
Error messages are unique per type of validation (e.g. `required`, `email` or `number`) and can be overridden:
3949

40-
<label class="warning">First name
41-
<input type="text" required="required" />
42-
<em class="message warning">Please fill out this field</em>
43-
</label>
50+
```html
51+
<form method="post" class="pat-validation"
52+
data-pat-validation="
53+
message-date: This value must be a valid date;
54+
message-datetime: This value must be a valid date and time;
55+
message-email: This value must be a valid email address;
56+
message-number: This value must be a number;
57+
message-required: This field is required;">
58+
<!-- Form fields come here -->
59+
</form>
60+
```
4461

45-
Checkboxes and radio buttons are treated differently: if they are contained in a fieldset with class `checklist` error messages are added at the end of the fieldset.
62+
Error messages can also be overridden on a per-field basis, for example:
4663

47-
<fieldset class="checklist radio">
48-
<label><input type="radio" name="radio" /> Strawberry</label>
49-
<label><input type="radio" name="radio" /> Banana</label>
50-
<label><input type="radio" name="radio" /> Raspberry</label>
51-
<em class="message warning">Please make a choice</em>
52-
</fieldset>
64+
```html
65+
<input
66+
type="date"
67+
name="date"
68+
data-pat-validation="
69+
not-after: #planning-end-${number};
70+
message-date: This date must be on or before the end date.
71+
"
72+
/>
73+
```
5374

54-
#### Overriding error messages
75+
For a list of all available error messages see the [Options reference](#options-reference).
5576

56-
Error messages are unique per type of validation (e.g. `required`, `email` or `number`) and can be overridden:
5777

58-
<form method="post" class="pat-validation"
59-
data-pat-validation="
60-
message-date: This value must be a valid date;
61-
message-datetime: This value must be a valid date and time;
62-
message-email: This value must be a valid email address;
63-
message-number: This value must be a number;
64-
message-required: This field is required;">
78+
### Error message rendering
6579

66-
<!-- Form fields come here -->
80+
Error messages are inserted into the DOM as `em` elements with a `message warning` class.
81+
For most input elements error messages are inserted immediately after the input element.
82+
In addition both the input element and its label will get an `warning` class.
6783

68-
</form>
84+
```html
85+
<label class="warning">First name
86+
<input type="text" required="required" />
87+
<em class="message warning">Please fill out this field</em>
88+
</label>
89+
```
6990

70-
Error messages can also be overridden on a per-field basis, for example:
91+
Checkboxes and radio buttons are treated differently: if they are contained in a fieldset with class `checklist` error messages are added at the end of the fieldset.
92+
93+
```html
94+
<fieldset class="checklist radio">
95+
<label><input type="radio" name="radio" /> Strawberry</label>
96+
<label><input type="radio" name="radio" /> Banana</label>
97+
<label><input type="radio" name="radio" /> Raspberry</label>
98+
<em class="message warning">Please make a choice</em>
99+
</fieldset>
100+
```
71101

72-
<input type="date" name="date" data-pat-validation="not-after: #planning-end-${number}; message-date: This date must be on or before the end date."/>
102+
The error message template is be overridden via JavaScript by customizing the error_template method of the Pattern API.
103+
This is an [example taken from Mockup](https://github.com/plone/mockup/blob/6c93b810b2c07b5bd58eec80cd03f700c9447d8c/src/patterns.js#L67):
104+
105+
```javascript
106+
import { Pattern as ValidationPattern } from "@patternslib/patternslib/src/pat/validation/validation";
107+
108+
ValidationPattern.prototype.error_template = (message) =>
109+
`<em class="invalid-feedback">${message}</em>`;
110+
```
73111

74112
### Options reference
75113

76-
> **_NOTE:_** The form inputs must have a `name` attribute, otherwise the validation would not happen.
114+
> **_NOTE:_** The form inputs must have a `name` attribute, otherwise the
115+
> validation would not happen.
77116
78-
> **_NOTE:_** If you need to exclude a submit button from form validation - like a cancel button which actually submits - add the `formnovalidate` attribute to the button.
117+
> **_NOTE:_** If you need to exclude a submit button from form validation -
118+
> like a cancel button which actually submits - add the `formnovalidate`
119+
> attribute to the button.
79120
80121

81122
| Property | Description | Default | Type |
82123
| ---------------- | -------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------- | -------------------------------------- |
83124
| disable-selector | A selector for elements that should be disabled when there are errors in the form. | | CSS Selector |
84-
| equality | Field-specific. The name of another input this input should equal to (useful for password confirmation). | | String |
85125
| message-date | The error message for date fields. | This value must be a valid date | String |
86126
| message-datetime | The error message for datetime fields. | This value must be a valid date and time | String |
87127
| message-email | The error message for email fields. | This value must be a valid email address | String |
88-
| message-equality | The error message for fields required to be equal | is not equal to %{attribute} | String |
89-
| message-max | The error message for max number values. | This value must be less than or equal to %{count} | String |
90-
| message-min | The error message for min number values. | This value must be greater than or equal to %{count} | String |
128+
| message-max | The error message for number values which are higher than max. | This value must be less than or equal to %{count} | String |
129+
| message-min | The error message for number values which are lower than min. | This value must be greater than or equal to %{count} | String |
91130
| message-number | The error message for numbers. | This value must be a number. | String |
92131
| message-required | The error message for required fields. | This field is required. | String |
93-
| not-after | Field-specific. A lower time limit restriction for date and datetime fields. | | CSS Selector or a ISO8601 date string. |
94-
| not-before | Field-specific. An upper time limit restriction for date and datetime fields. | | CSS Selector or a ISO8601 date string. |
132+
| message-equality | The error message for fields required to be equal | is not equal to %{attribute} | String |
133+
| equality | Field-specific extra rule. The name of another input this input should equal to (useful for password confirmation). | | String |
134+
| not-after | Field-specific extra rule. A lower time limit restriction for date and datetime fields. | | CSS Selector or a ISO8601 date string. |
135+
| not-before | Field-specific extra rule. An upper time limit restriction for date and datetime fields. | | CSS Selector or a ISO8601 date string. |
136+
| delay | Time in milliseconds before validation starts to avoid validating while typing. | 100 | Integer |

src/pat/validation/validation.js

+10-24
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,25 @@ import utils from "../../core/utils";
1010
import registry from "../../core/registry";
1111

1212
const logger = logging.getLogger("pat-validation");
13-
//logger.setLevel(logging.Level.DEBUG);
13+
1414

1515
export const parser = new Parser("validation");
1616
parser.addArgument("disable-selector", "[type=submit], button:not([type=button])"); // Elements which must be disabled if there are errors
17-
parser.addArgument("message-date", ""); // "This value must be a valid date");
18-
parser.addArgument("message-datetime", ""); // "This value must be a valid date and time");
19-
parser.addArgument("message-email", ""); // "This value must be a valid email address");
20-
parser.addArgument("message-max", ""); // "This value must be less than or equal to %{count}");
21-
parser.addArgument("message-min", ""); // "This value must be greater than or equal to %{count}"); // prettier-ignore
22-
parser.addArgument("message-number", ""); // "This value must be a number");
23-
parser.addArgument("message-required", ""); // "This field is required");
17+
parser.addArgument("message-date", ""); // "This value must be a valid date"
18+
parser.addArgument("message-datetime", ""); // "This value must be a valid date and time"
19+
parser.addArgument("message-email", ""); // "This value must be a valid email address"
20+
parser.addArgument("message-max", ""); // "This value must be less than or equal to %{count}"
21+
parser.addArgument("message-min", ""); // "This value must be greater than or equal to %{count}"
22+
parser.addArgument("message-number", ""); // "This value must be a number"
23+
parser.addArgument("message-required", ""); // "This field is required"
2424
parser.addArgument("message-equality", "is not equal to %{attribute}.");
2525
parser.addArgument("not-after", null);
2626
parser.addArgument("not-before", null);
2727
parser.addArgument("equality", null);
2828
parser.addArgument("delay", 100); // Delay before validation is done to avoid validating while typing.
2929

30-
// BBB
31-
// TODO: deprecated. Will be removed with next major version.
30+
// Aliases
3231
parser.addAlias("message-integer", "message-number");
33-
parser.addArgument("error-template");
3432

3533
const KEY_ERROR_EL = "__patternslib__input__error__el";
3634
const KEY_ERROR_MSG = "__patternslib__input__error__msg";
@@ -121,19 +119,7 @@ class Pattern extends BasePattern {
121119
return;
122120
}
123121

124-
logger.debug(`
125-
validity_state.badInput ${validity_state.badInput}
126-
validity_state.customError ${validity_state.customError}
127-
validity_state.patternMismatch ${validity_state.patternMismatch}
128-
validity_state.rangeOverflow ${validity_state.rangeOverflow}
129-
validity_state.rangeUnderflow ${validity_state.rangeUnderflow}
130-
validity_state.stepMismatch ${validity_state.stepMismatch}
131-
validity_state.tooLong ${validity_state.tooLong}
132-
validity_state.tooShort ${validity_state.tooShort}
133-
validity_state.typeMismatch ${validity_state.typeMismatch}
134-
validity_state.valid ${validity_state.valid}
135-
validity_state.valueMissing ${validity_state.valueMissing}
136-
`);
122+
logger.debug(`validity_state: `, validity_state);
137123

138124
const input_options = parser.parse(input);
139125

0 commit comments

Comments
 (0)