Skip to content

Commit 215d421

Browse files
feat: adds new validation rule examples
1 parent 5fd79e3 commit 215d421

File tree

5 files changed

+111
-222
lines changed

5 files changed

+111
-222
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<template>
2+
<FormKit type="group">
3+
<FormKit
4+
type="date"
5+
name="startDate"
6+
label="Start Date"
7+
help="Select a start date"
8+
/>
9+
<FormKit
10+
type="date"
11+
name="endDate"
12+
label="End Date"
13+
validation="date_after_node:startDate"
14+
validation-label="End Date"
15+
:help="`Select an end date after the start date`"
16+
/>
17+
</FormKit>
18+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<template>
2+
<FormKit
3+
type="date"
4+
label="Select a date after or equal to 2020-01-01"
5+
validation="date_after_or_equal:2020-01-01"
6+
validation-label="Date"
7+
help="The selected date must be after or equal to 2020-01-01"
8+
/>
9+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<template>
2+
<FormKit type="group">
3+
<FormKit
4+
type="date"
5+
name="startDate"
6+
label="Start Date"
7+
help="Select a start date"
8+
/>
9+
<FormKit
10+
type="date"
11+
name="endDate"
12+
label="End Date"
13+
validation="date_before_node:startDate"
14+
validation-label="End Date"
15+
:help="`Select an end date before the start date`"
16+
/>
17+
</FormKit>
18+
</template>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<template>
2+
<FormKit
3+
type="date"
4+
label="Select a date before or equal to 2020-01-01"
5+
validation="date_before_or_equal:2020-01-01"
6+
validation-label="Date"
7+
help="The selected date must be before 2020-01-01"
8+
/>
9+
</template>

essentials/validation.md

+57-222
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ You can use rule hints together. To do so, just place multiple hints before the
167167

168168
## Available rules
169169

170-
FormKit ships with over 20 production-ready validation rules, covering most validation needs. If you dont find one that meets your exact requirement, you can add a [custom rule](#custom-rules) to suit your needs.
170+
FormKit ships with over 35 production-ready validation rules, covering most validation needs. If you don't find one that meets your exact requirement, you can add a [custom rule](#custom-rules) to suit your needs.
171171

172172
- [accepted](#accepted)
173173
- [alpha](#alpha)
@@ -185,6 +185,10 @@ FormKit ships with over 20 production-ready validation rules, covering most vali
185185
- [date_after](#date-after)
186186
- [date_before](#date-before)
187187
- [date_between](#date-between)
188+
- [date_before_or_equal](#date-before-or-equal)
189+
- [date_after_or_equal](#date-after-or-equal)
190+
- [date_before_node](#date-before-node)
191+
- [date_after_node](#date-after-node)
188192
- [date_format](#date-format)
189193
- [email](#email)
190194
- [ends_with](#ends-with)
@@ -265,7 +269,7 @@ layout: "auto"
265269

266270
### Confirm
267271

268-
Checks if the value of one input matches the value of another input — often used for password confirmations. There are two ways to specify which input to match:
272+
Checks if the value of one input matches the value of another input — often used for password confirmations. There are two ways to specify which input to match:
269273

270274
- Append `_confirm` to the `name` attribute of the second input.
271275
- Pass the `name` of the first input as an argument to the confirm rule in the second input `confirm:name_of_input_1` (more specific).
@@ -400,9 +404,57 @@ layout: "auto"
400404
---
401405
::
402406

407+
### Date before or equal
408+
409+
Determines if a date is before or equal to the current date or a date supplied as the rule's argument. Dates used can either be JavaScript `Date` objects or strings that can be parsed by [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).
410+
411+
::Example
412+
---
413+
name: "Date before or equal"
414+
file: "_content/_examples/rule-date-before-or-equal/rule-date-before-or-equal.vue"
415+
layout: "auto"
416+
---
417+
::
418+
419+
### Date after or equal
420+
421+
Determines if a date is after or equal to the current date or a date supplied as the rule's argument. Dates used can either be JavaScript `Date` objects or strings that can be parsed by [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).
422+
423+
::Example
424+
---
425+
name: "Date after or equal"
426+
file: "_content/_examples/rule-date-after-or-equal/rule-date-after-or-equal.vue"
427+
layout: "auto"
428+
---
429+
::
430+
431+
### Date before node
432+
433+
Determines if a date is before the date in another node specified by its address. The address is provided as an argument to the rule. Dates used can either be JavaScript `Date` objects or strings that can be parsed by [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).
434+
435+
::Example
436+
---
437+
name: "Date before node"
438+
file: "_content/_examples/rule-date-before-node/rule-date-before-node.vue"
439+
layout: "auto"
440+
---
441+
::
442+
443+
### Date after node
444+
445+
Determines if a date is after the date in another node specified by its address. The address is provided as an argument to the rule. Dates used can either be JavaScript `Date` objects or strings that can be parsed by [`Date.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).
446+
447+
::Example
448+
---
449+
name: "Date after node"
450+
file: "_content/_examples/rule-date-after-node/rule-date-after-node.vue"
451+
layout: "auto"
452+
---
453+
::
454+
403455
### Date format
404456

405-
Ensures the format of an inputs date matches a specific date format. The format should be specified using the following formatting tokens:
457+
Ensures the format of an input's date matches a specific date format. The format should be specified using the following formatting tokens:
406458

407459
| Token | Valid values |
408460
| ----- | ------------------------------------------------------------- |
@@ -418,7 +470,7 @@ Ensures the format of an input’s date matches a specific date format. The form
418470
type: "warning"
419471
label: ""
420472
---
421-
Native date inputs always output the same format <code>YYYY-MM-DD ...</code> even though they display dates according to the browsers locale. Using this rule to specify a <em>different</em> format would result in an input that can never be valid.
473+
Native date inputs always output the same format <code>YYYY-MM-DD ...</code> even though they display dates according to the browser's locale. Using this rule to specify a <em>different</em> format would result in an input that can never be valid.
422474
::
423475

424476
::Example
@@ -467,7 +519,7 @@ layout: "auto"
467519

468520
### Length
469521

470-
Checks that the inputs value is over a given length, or between two length values. It works to validate arrays (like [lists](/inputs/list)), objects (like [groups](/inputs/group)), or string lengths. Can be used to simulate the native `maxlength` and `minlength` as well.
522+
Checks that the input's value is over a given length, or between two length values. It works to validate arrays (like [lists](/inputs/list)), objects (like [groups](/inputs/group)), or string lengths. Can be used to simulate the native `maxlength` and `minlength` as well.
471523

472524
::Example
473525
---
@@ -676,220 +728,3 @@ layout: "auto"
676728
## Custom rules
677729

678730
Validation rules are functions that accept a [core node](/essentials/architecture#node) and return a boolean value — `true` for passing and `false` for failing. Additionally, any arguments passed to the validation rule are available as arguments `1-n`. Writing your own is straight forward — for example:
679-
680-
```js
681-
/**
682-
* File: my-custom-rules/monday.js
683-
*
684-
* A contrived validation rule that ensures the input’s value is monday or mon.
685-
*/
686-
const monday = function (node) {
687-
return node.value === 'monday' || node.value === 'mon'
688-
}
689-
690-
export default monday
691-
```
692-
693-
### Defining custom rule behaviors
694-
695-
As mentioned in the [validation rule hints](#rule-hints) section, validation rules — including your custom rules — operate according to default behaviors: they run in sequence, are skipped when the input's value is empty, are synchronous, and are blocking. If you want your rule's defaults to operate differently, you can override these on your custom validation rule:
696-
697-
```js
698-
/**
699-
* A contrived validation rule that ensures the input’s value is monday or mon.
700-
*/
701-
const monday = function (node) {
702-
return node.value === 'monday' || node.value === 'mon'
703-
}
704-
705-
// override default rule behaviors for your custom rule
706-
monday.blocking = false
707-
monday.skipEmpty = false
708-
monday.debounce = 20 // milliseconds
709-
monday.force = true
710-
711-
export default monday
712-
```
713-
714-
You can also override these behaviors on a case-by-case basis with [rule hints](#rule-hints).
715-
716-
Once you have a validation function written — you need to register the validation rule with FormKit — either globally or specifically on an input.
717-
718-
### Multi-input validation rules
719-
720-
Validation rules can depend on values from other inputs in your [form’s tree](/essentials/architecture). To do so, use node traversal to locate another node and access its value:
721-
722-
::Example
723-
---
724-
name: "Custom validation dependency"
725-
file: "_content/_examples/custom-validation-dependency/custom-validation-dependency.vue"
726-
layout: "auto"
727-
---
728-
::
729-
730-
731-
::Callout
732-
---
733-
type: "warning"
734-
label: "Pure functions"
735-
---
736-
Validation rules should always be pure functions. Use only the arguments passed in and do not perform any side effects.
737-
::
738-
739-
### Adding a rule globally
740-
741-
To use a validation rule anywhere in your project, you can specify it wherever your FormKit plugin is registered with Vue.
742-
743-
```js
744-
import { createApp } from 'vue'
745-
import App from './App.vue'
746-
import { plugin, defaultConfig } from '@formkit/vue'
747-
import monday from './my-custom-rules/monday'
748-
749-
// prettier-ignore
750-
createApp(App).use(plugin, defaultConfig({
751-
rules: { monday },
752-
})).mount('#app')
753-
```
754-
755-
Once installed you can use your validation rule in anywhere in your project.
756-
757-
```html
758-
<FormKit validation="required|monday" />
759-
```
760-
761-
To customize the error message which shows up when your custom validation fails, follow the instructions [here](#global-validation-message).
762-
763-
### Adding a rule via prop
764-
765-
To add a validation to a specific input use the `validation-rules` prop.
766-
767-
::Example
768-
---
769-
name: "Custom validation rules"
770-
file: "_content/_examples/validation-custom/validation-custom.vue"
771-
layout: "auto"
772-
---
773-
::
774-
775-
::Callout
776-
---
777-
type: "tip"
778-
label: "Custom message"
779-
---
780-
Your custom rules probably need a custom message — the next section of the docs will cover that.
781-
::
782-
783-
## Custom messages
784-
785-
There are several ways to customize your validation message. The most basic of which is to use the <code>validation-label</code> prop — allowing you to change the name of the field as used in the pre-defined validation messages.
786-
787-
::Example
788-
---
789-
name: "Custom validation rules"
790-
file: "_content/_examples/validation-label/validation-label.vue"
791-
layout: "auto"
792-
---
793-
::
794-
795-
If you need to be more specific you have two options:
796-
797-
- Override a rule’s message using a prop.
798-
- Override a validation rule’s message globally.
799-
800-
### Validation message prop
801-
802-
You can easily override validation messages directly on your `FormKit` input by providing an object of strings or functions.
803-
804-
#### Using strings
805-
806-
To override a validation message on a single FormKit input, add the `validation-messages` prop with an object of rule names and a corresponding message.
807-
808-
::Example
809-
---
810-
name: "Custom validation rules"
811-
file: "_content/_examples/validation-custom-messages/validation-custom-messages.vue"
812-
layout: "auto"
813-
---
814-
::
815-
816-
#### Using functions
817-
818-
If you need more power for your validation rules, you can use a function instead of a string. The function is passed a context object.
819-
820-
##### Validation message context object:
821-
822-
| Behavior | Description |
823-
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
824-
| args | An array of arguments passed to the rule. For example <code>['Vue', 'React', 'Angular']</code> from the rule <code>is:Vue,React,Angular</code>. |
825-
| name | The name of the field (first available from: <code>validation-label</code>, <code>label</code>, then <code>name</code>). |
826-
| node | The [FormKit core <code>node</code>](/essentials/architecture). |
827-
828-
Let’s re-write the above example using a function instead of a string for even more control of the <code>validation-messages</code> prop:
829-
830-
::Example
831-
---
832-
name: "Custom validation rules"
833-
file: "_content/_examples/validation-custom-messages/validation-custom-messages-function.vue"
834-
layout: "auto"
835-
---
836-
::
837-
838-
### Global validation message
839-
840-
If there are validation rule messages you'd like to override (or add) across your entire project, you can define those message rules when registering FormKit under the language key you'd like to override:
841-
842-
```js
843-
import { createApp } from 'vue'
844-
import App from './App.vue'
845-
import { plugin, defaultConfig } from '@formkit/vue'
846-
import monday from './my-custom-rules/monday'
847-
848-
// prettier-ignore
849-
createApp(App).use(plugin, defaultConfig({
850-
messages: {
851-
en: {
852-
validation: {
853-
required({ name }) {
854-
return `Please fill out the ${name} field.`
855-
}
856-
}
857-
}
858-
}
859-
})).mount('#app')
860-
```
861-
862-
## Moving validation messages
863-
864-
If you would like to render an input’s validation messages outside of the `<FormKit />` component, you can leverage the `<FormKitMessages />` component by passing the input’s node as a prop. Using this component disables the default display of messages (located beneath the input) and moves them to wherever the `<FormKitMessages />` component is located:
865-
866-
::Example
867-
---
868-
name: "Submit invalid"
869-
file: "_content/_examples/formkit-messages/normal-input.vue"
870-
---
871-
::
872-
873-
## Extracting messages
874-
875-
::Callout
876-
---
877-
type: "tip"
878-
label: "The <FormKitSummary> component"
879-
---
880-
FormKit 1.0.0 introduced the [FormKitSummary](/inputs/form#validation-and-error-summary) component which provides an "out of the box" solution to for displaying all the validation messages in a given form or subtree.
881-
::
882-
883-
To get all the validation messages from an [input’s core node](/essentials/architecture), you can use the `getValidationMessages` function exported from `@formkit/validation`. This function will recursively check the given node and all children for validation messages and return a Map of core nodes to validation messages, making it ideal for use with forms:
884-
885-
::Example
886-
---
887-
name: "Submit invalid"
888-
file: "_content/_examples/submit-invalid/submit-invalid.vue"
889-
---
890-
::
891-
892-
893-
## Triggering validation
894-
895-
Trying to manually trigger validation is an anti-pattern in FormKit and should be avoided. Validation is continually computed via fine-grained reactivity. If a value or prop that is used in a validation rule changes, the validation will be automatically be re-run. This ensures validity state, settlement state, submission state and any other validation-related properties can always be trusted.

0 commit comments

Comments
 (0)