Skip to content

Commit 88e8cfc

Browse files
fix: restores custom rule docs
1 parent 215d421 commit 88e8cfc

File tree

1 file changed

+217
-0
lines changed

1 file changed

+217
-0
lines changed

essentials/validation.md

+217
Original file line numberDiff line numberDiff line change
@@ -728,3 +728,220 @@ layout: "auto"
728728
## Custom rules
729729

730730
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:
731+
732+
```js
733+
/**
734+
* File: my-custom-rules/monday.js
735+
*
736+
* A contrived validation rule that ensures the input’s value is monday or mon.
737+
*/
738+
const monday = function (node) {
739+
return node.value === 'monday' || node.value === 'mon'
740+
}
741+
742+
export default monday
743+
```
744+
745+
### Defining custom rule behaviors
746+
747+
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:
748+
749+
```js
750+
/**
751+
* A contrived validation rule that ensures the input’s value is monday or mon.
752+
*/
753+
const monday = function (node) {
754+
return node.value === 'monday' || node.value === 'mon'
755+
}
756+
757+
// override default rule behaviors for your custom rule
758+
monday.blocking = false
759+
monday.skipEmpty = false
760+
monday.debounce = 20 // milliseconds
761+
monday.force = true
762+
763+
export default monday
764+
```
765+
766+
You can also override these behaviors on a case-by-case basis with [rule hints](#rule-hints).
767+
768+
Once you have a validation function written — you need to register the validation rule with FormKit — either globally or specifically on an input.
769+
770+
### Multi-input validation rules
771+
772+
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:
773+
774+
::Example
775+
---
776+
name: "Custom validation dependency"
777+
file: "_content/_examples/custom-validation-dependency/custom-validation-dependency.vue"
778+
layout: "auto"
779+
---
780+
::
781+
782+
783+
::Callout
784+
---
785+
type: "warning"
786+
label: "Pure functions"
787+
---
788+
Validation rules should always be pure functions. Use only the arguments passed in and do not perform any side effects.
789+
::
790+
791+
### Adding a rule globally
792+
793+
To use a validation rule anywhere in your project, you can specify it wherever your FormKit plugin is registered with Vue.
794+
795+
```js
796+
import { createApp } from 'vue'
797+
import App from './App.vue'
798+
import { plugin, defaultConfig } from '@formkit/vue'
799+
import monday from './my-custom-rules/monday'
800+
801+
// prettier-ignore
802+
createApp(App).use(plugin, defaultConfig({
803+
rules: { monday },
804+
})).mount('#app')
805+
```
806+
807+
Once installed you can use your validation rule in anywhere in your project.
808+
809+
```html
810+
<FormKit validation="required|monday" />
811+
```
812+
813+
To customize the error message which shows up when your custom validation fails, follow the instructions [here](#global-validation-message).
814+
815+
### Adding a rule via prop
816+
817+
To add a validation to a specific input use the `validation-rules` prop.
818+
819+
::Example
820+
---
821+
name: "Custom validation rules"
822+
file: "_content/_examples/validation-custom/validation-custom.vue"
823+
layout: "auto"
824+
---
825+
::
826+
827+
::Callout
828+
---
829+
type: "tip"
830+
label: "Custom message"
831+
---
832+
Your custom rules probably need a custom message — the next section of the docs will cover that.
833+
::
834+
835+
## Custom messages
836+
837+
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.
838+
839+
::Example
840+
---
841+
name: "Custom validation rules"
842+
file: "_content/_examples/validation-label/validation-label.vue"
843+
layout: "auto"
844+
---
845+
::
846+
847+
If you need to be more specific you have two options:
848+
849+
- Override a rule’s message using a prop.
850+
- Override a validation rule’s message globally.
851+
852+
### Validation message prop
853+
854+
You can easily override validation messages directly on your `FormKit` input by providing an object of strings or functions.
855+
856+
#### Using strings
857+
858+
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.
859+
860+
::Example
861+
---
862+
name: "Custom validation rules"
863+
file: "_content/_examples/validation-custom-messages/validation-custom-messages.vue"
864+
layout: "auto"
865+
---
866+
::
867+
868+
#### Using functions
869+
870+
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.
871+
872+
##### Validation message context object:
873+
874+
| Behavior | Description |
875+
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
876+
| 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>. |
877+
| name | The name of the field (first available from: <code>validation-label</code>, <code>label</code>, then <code>name</code>). |
878+
| node | The [FormKit core <code>node</code>](/essentials/architecture). |
879+
880+
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:
881+
882+
::Example
883+
---
884+
name: "Custom validation rules"
885+
file: "_content/_examples/validation-custom-messages/validation-custom-messages-function.vue"
886+
layout: "auto"
887+
---
888+
::
889+
890+
### Global validation message
891+
892+
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:
893+
894+
```js
895+
import { createApp } from 'vue'
896+
import App from './App.vue'
897+
import { plugin, defaultConfig } from '@formkit/vue'
898+
import monday from './my-custom-rules/monday'
899+
900+
// prettier-ignore
901+
createApp(App).use(plugin, defaultConfig({
902+
messages: {
903+
en: {
904+
validation: {
905+
required({ name }) {
906+
return `Please fill out the ${name} field.`
907+
}
908+
}
909+
}
910+
}
911+
})).mount('#app')
912+
```
913+
914+
## Moving validation messages
915+
916+
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:
917+
918+
::Example
919+
---
920+
name: "Submit invalid"
921+
file: "_content/_examples/formkit-messages/normal-input.vue"
922+
---
923+
::
924+
925+
## Extracting messages
926+
927+
::Callout
928+
---
929+
type: "tip"
930+
label: "The <FormKitSummary> component"
931+
---
932+
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.
933+
::
934+
935+
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:
936+
937+
::Example
938+
---
939+
name: "Submit invalid"
940+
file: "_content/_examples/submit-invalid/submit-invalid.vue"
941+
---
942+
::
943+
944+
945+
## Triggering validation
946+
947+
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)