Skip to content

Commit

Permalink
feat(validation): add eager and invalid-input options
Browse files Browse the repository at this point in the history
  • Loading branch information
KaelWD committed Jun 20, 2024
1 parent 784eb14 commit 7e730fa
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 19 deletions.
32 changes: 20 additions & 12 deletions packages/docs/src/pages/en/components/forms.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,29 @@ This also demonstrates the **validate-on** prop, which tells the `v-form` compon

## Validation state

By default, all inputs run their validation rules when mounted but do not display errors to the user.
When rules run is controlled with the **validate-on** prop which accepts a string containing `input`, `blur`, `submit`, `invalid-input`, `eager`, or `lazy`.
<br>
When rules run is controlled with the **validate-on** prop which accepts a string containing `input`, `blur`, `submit`, or `lazy`.
`input`, `blur`, `submit`, and `eager` set when a validation error can first be displayed to the user, while `lazy` disables validation on mount (useful for async rules).
<br>
`input`, `blur`, and `submit` set when a validation error can first be displayed to the user, while `lazy` disables validation on mount (useful for async rules).
By default, all inputs run their validation rules when mounted but do not display errors to the user. Adding `eager` will display errors immediately, or `lazy` to disable this.
<br>
`lazy` can be combined with other options, and implies `input` on its own.

| `validate-on=` | `"input"` | `"blur"` | `"submit"` | `"lazy"` |
|----------------|:---------:|:--------:|:----------:|:--------:|
| On mount |||||
| On input |||| * |
| On blur |||| * |
| On submit |||| * |
<p class="text-caption">* Uses the behavior of whatever it's combined with.</p>
`eager` and `lazy` can be combined with other options but not each other, and both imply `input` on their own.
<br>
`invalid-input` behaves the same as `blur` unless the field is invalid, then it will run on input instead until validation passes again.

| `validate-on=` | `"input"` | `"blur"` | `"submit"` | `"invalid-input"` | `"eager"` | `"lazy"` |
|----------------|:---------:|:--------:|:----------:|:-----------------:|:-------------:|:--------:|
| On mount ||||| ✅<sup>†</sup> ||
| On input ||||| * | * |
| On blur ||||| * | * |
| On submit |||||||
<p class="text-caption">
* Uses the behavior of whatever it's combined with, the same as on="input" by default.
<br>
† Displays errors immediately on mount or reset.
<br>
‡ Only if the validation failed previously.
</p>

The form's current validation status is accessed using `v-model` or the submit event. It can be in one of three states:

Expand Down
24 changes: 17 additions & 7 deletions packages/vuetify/src/composables/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,15 @@ export type ValidationRule =
| ((value: any) => ValidationResult)
| ((value: any) => PromiseLike<ValidationResult>)

type ValidateOnValue = 'blur' | 'input' | 'submit'
type ValidateOnValue = 'blur' | 'input' | 'submit' | 'invalid-input'
type ValidateOn =
| ValidateOnValue
| `${ValidateOnValue} lazy`
| `${ValidateOnValue} eager`
| `lazy ${ValidateOnValue}`
| `eager ${ValidateOnValue}`
| 'lazy'
| 'eager'

export interface ValidationProps {
disabled: boolean | null
Expand All @@ -33,7 +41,7 @@ export interface ValidationProps {
rules: readonly ValidationRule[]
modelValue: any
'onUpdate:modelValue': EventProp | undefined
validateOn?: ValidateOnValue | `${ValidateOnValue} lazy` | `lazy ${ValidateOnValue}` | 'lazy'
validateOn?: ValidateOn
validationValue: any
}

Expand Down Expand Up @@ -92,13 +100,15 @@ export function useValidation (
const validateOn = computed(() => {
let value = (props.validateOn ?? form?.validateOn.value) || 'input'
if (value === 'lazy') value = 'input lazy'
if (value === 'eager') value = 'input eager'
const set = new Set(value?.split(' ') ?? [])

return {
blur: set.has('blur') || set.has('input'),
input: set.has('input'),
submit: set.has('submit'),
blur: set.has('blur') || set.has('input') || set.has('invalid-input'),
invalidInput: set.has('invalid-input'),
lazy: set.has('lazy'),
eager: set.has('eager'),
}
})
const isValid = computed(() => {
Expand Down Expand Up @@ -139,12 +149,12 @@ export function useValidation (

onMounted(async () => {
if (!validateOn.value.lazy) {
await validate(true)
await validate(!validateOn.value.eager)
}
form?.update(uid.value, isValid.value, errorMessages.value)
})

useToggleScope(() => validateOn.value.input, () => {
useToggleScope(() => validateOn.value.input || (validateOn.value.invalidInput && isValid.value === false), () => {
watch(validationModel, () => {
if (validationModel.value != null) {
validate()
Expand Down Expand Up @@ -177,7 +187,7 @@ export function useValidation (
async function resetValidation () {
isPristine.value = true
if (!validateOn.value.lazy) {
await validate(true)
await validate(!validateOn.value.eager)
} else {
internalErrorMessages.value = []
}
Expand Down

0 comments on commit 7e730fa

Please # to comment.