Skip to content
This repository was archived by the owner on Apr 9, 2025. It is now read-only.

Latest commit

 

History

History
215 lines (181 loc) · 8.94 KB

File metadata and controls

215 lines (181 loc) · 8.94 KB

useFormHandler

useFormHandler is our composable to handle forms, it takes one object as optional argument and returns various objects and methods that will allow us to handle our forms.

Props

initialValues: Record<string,any>

::: warning Changing the initialValues will trigger a form reset, this means the formState and the values will return to its initial state. :::

Values which we use to initialize the form, this is useful when we get an initial value state for the form from an external call.

Example

<template>
  <input v-bind="register('firstName')" /> // Should initially be 'John'
  <input v-bind="register('lastName')" /> // Should initially be 'Doe'
  <pre>{{ values }}</pre>
  // Should show the initialized values
</template>
<script setup lang="ts">
import { useFormHandler } from 'vue-form-handler'

const { register, values } = useFormHandler({
  initialValues: {
    firstName: 'John',
    lastName: 'Doe',
  },
})
</script>

interceptor: Interceptor

Function that allows us to intercept any value assignment, accept or deny it and perform operations before and after the assignment happens.

Params

The interceptor will be called passing an object as a parameter with the following:

attribute type description
name string Name of the field that is about to be set
value any Value of the field that is about to be set
clearError ClearError API - clearError
clearField ClearField API - clearField
formState FormState API - formState
modifiedValues ModifiedValues API - modifiedValues
resetField ResetField API - resetField
resetForm ResetForm API - resetForm
setError SetError API - setError
setValue SetValue API - setValue
triggerValidation TriggerValidation API - triggerValidation
values Record<string,any> API - values

::: info As you can see, the interceptor is provided with everything the handler does provide but in a separate context. :::

Expected return

The interceptor expects a type of boolean or a Promise<boolean>, return true to proceed setting the value and false if the value should not be set.

Example

<template>
  <select v-bind="register('continent')" placeholder="Choose your country">
    <option disabled value="null">Choose your continent</option>
    <option value="AM">America</option>
    <option value="AS">Asia</option>
    <option value="EU">Europe</option>
  </select>
  <select v-bind="register('country')" placeholder="Choose your country">
    <option disabled value="null">Choose your country</option>
    <option value="CAN">Canada</option>
    <option value="USA">United States</option>
    <option value="JAP">Japan</option>
    <option value="CHN">China</option>
    <option value="ESP">Spain</option>
    <option value="DEU">Germany</option>
  </select>
</template>
<script setup lang="ts">
import { useFormHandler } from 'vue-form-handler'

const interceptor = ({ name, clearField }) => {
  if (name === 'continent') {
    clearField('country')
  }
  return true
}

const { register } = useFormHandler({
  interceptor,
})
</script>

validate: FormValidation

Use this function in the case you'd rather perform a custom/different validation when submitting your form

Example

<template @submit.prevent="handleSubmit(successFn)">
  <form>
    <input v-bind="register('firstName')" />
    <input v-bind="register('lastName')" />
    <input type="number" v-bind="register('age')" />
    <input type="submit" />
  </form>
</template>
<script setup lang="ts">
import { useFormHandler } from 'vue-form-handler'

const validation = (values) => values.age && Number(values.age) >= 18
const successFn = (form: Record<string, any>) => {
  console.log({ form })
}

const { register, handleSubmit } = useFormHandler({
  validation,
})
</script>

validationMode: 'onChange' | 'onBlur' | 'onSubmit' | 'always'

This option allows you to configure the validation mode or strategy the handler will follow.

name type description
onChange string Validation will trigger on the change event with each input, and lead to multiple re-renders.
onBlur string Validation will trigger on the blur event.
onSubmit string Validation will trigger on the submit event.
always string Validation will trigger on change and blur events.

::: warning Using the always validationMode will have a more significant impact on performance. :::

Return

Type Declarations

export declare const useFormHandler: <
  T extends Record<string, any> = Record<string, any>,
  R extends T = T,
>({
  initialValues,
  interceptor,
  validate,
  validationMode,
  injectionKey,
}?: FormHandlerParams<T, R>) => {
  build: Build<T>
  clearError: (name?: keyof T | undefined) => void
  clearField: (name: keyof T) => Promise<void>
  formState: {
    readonly isDirty: boolean
    readonly isTouched: boolean
    readonly isValid: boolean
    readonly isValidating: boolean
    readonly dirty: import('@vue/reactivity').DeepReadonly<
      import('@vue/reactivity').UnwrapRef<Record<keyof T, boolean>>
    >
    readonly touched: import('@vue/reactivity').DeepReadonly<
      import('@vue/reactivity').UnwrapRef<Record<keyof T, boolean>>
    >
    readonly errors: import('@vue/reactivity').DeepReadonly<
      import('@vue/reactivity').UnwrapRef<Record<keyof T, string | undefined>>
    >
    readonly validating: import('@vue/reactivity').DeepReadonly<
      import('@vue/reactivity').UnwrapRef<Record<keyof T, boolean>>
    >
  }
  handleSubmit: (
    successFn: HandleSubmitSuccessFn,
    errorFn?: HandleSubmitErrorFn
  ) => Promise<void>
  modifiedValues: <TModified extends T>() => TModified
  register: (name: keyof T, options?: RegisterOptions) => RegisterReturn
  resetField: (name: keyof T) => void
  resetForm: () => void
  setError: (name: keyof T, error: string) => void
  setValue: (name: keyof T, value?: any) => Promise<void>
  triggerValidation: (name?: keyof T | undefined) => Promise<void>
  unregister: (name: keyof T) => void
  values: import('@vue/reactivity').DeepReadonly<
    import('@vue/reactivity').UnwrapNestedRefs<T>
  >
}