diff --git a/docs/components/content/examples/FormGroupEagerValidationExample.vue b/docs/components/content/examples/FormGroupEagerValidationExample.vue new file mode 100644 index 0000000000..d17d5a9a28 --- /dev/null +++ b/docs/components/content/examples/FormGroupEagerValidationExample.vue @@ -0,0 +1,19 @@ + + + diff --git a/docs/content/3.forms/10.form.md b/docs/content/3.forms/10.form.md index 7ebb2244bd..1dbd20a615 100644 --- a/docs/content/3.forms/10.form.md +++ b/docs/content/3.forms/10.form.md @@ -161,6 +161,10 @@ async function onSubmit (event: FormSubmitEvent) { The Form component automatically triggers validation upon `submit`, `input`, `blur` or `change` events. This ensures that any errors are displayed as soon as the user interacts with the form elements. You can control when validation happens this using the `validate-on` prop. +::callout{icon="i-heroicons-light-bulb"} +Note that the `input` event is not triggered until after the initial `blur` event. This is to prevent the form from being validated as the user is typing. You can override this behavior by setting the [`eager-validation`](/forms/form-group#eager-validation) prop on [`FormGroup`](/forms/form-group) to `true`. +:: + ::component-example --- component: 'form-example-elements' diff --git a/docs/content/3.forms/9.form-group.md b/docs/content/3.forms/9.form-group.md index b8f7af0bad..605b22e776 100644 --- a/docs/content/3.forms/9.form-group.md +++ b/docs/content/3.forms/9.form-group.md @@ -163,6 +163,12 @@ code: >- This will only work with form elements that support the `size` prop. :: +### Eager Validation + +By default, validation is only triggered after the initial `blur` event. This is to prevent the form from being validated as the user is typing. You can override this behavior by setting the `eager-validation` prop to `true` + +:component-example{component="form-group-eager-validation-example"} + ## Slots ### `label` diff --git a/src/runtime/components/forms/FormGroup.vue b/src/runtime/components/forms/FormGroup.vue index 897f010f91..d253668c0f 100644 --- a/src/runtime/components/forms/FormGroup.vue +++ b/src/runtime/components/forms/FormGroup.vue @@ -94,6 +94,10 @@ export default defineComponent({ ui: { type: Object as PropType>, default: undefined + }, + eagerValidation: { + type: Boolean, + default: false } }, setup (props) { @@ -114,7 +118,8 @@ export default defineComponent({ error, inputId, name: computed(() => props.name), - size: computed(() => props.size) + size: computed(() => props.size), + eagerValidation: computed(() => props.eagerValidation) }) return { diff --git a/src/runtime/composables/useFormGroup.ts b/src/runtime/composables/useFormGroup.ts index e05cb949cf..c185f67cc5 100644 --- a/src/runtime/composables/useFormGroup.ts +++ b/src/runtime/composables/useFormGroup.ts @@ -9,6 +9,7 @@ type InputProps = { color?: string name?: string isFieldset?: boolean + eagerValidation?: boolean } export const useFormGroup = (inputProps?: InputProps, config?: any) => { @@ -49,7 +50,7 @@ export const useFormGroup = (inputProps?: InputProps, config?: any) => { } const emitFormInput = useDebounceFn(() => { - if (blurred.value) { + if (blurred.value || formGroup?.eagerValidation.value) { emitFormEvent('input', formGroup?.name.value) } }, 300) diff --git a/src/runtime/types/form.d.ts b/src/runtime/types/form.d.ts index c3e1507fa3..4ef7ccbf5e 100644 --- a/src/runtime/types/form.d.ts +++ b/src/runtime/types/form.d.ts @@ -32,4 +32,5 @@ export interface InjectedFormGroupValue { name: Ref size: Ref error: Ref + eagerValidation: Ref }