Search code examples
javascriptvue.jsvalidationvuejs3formkit

FormKit: how to do async/server-side validation?


How can I do async/server-side validation using FormKit (with Vue3)? Not only on submit but also after user removes focus from the input.

Basic validation example:

<FormKit
  type="text"
  label="Number"
  validation="required|number|between:20,50"
  validation-visibility="live"
  help="Enter a number between 20 and 50."
/>

Don't find any examples or mentions anywhere other than the documentation mention async once.


Solution

  • Creating a custom async rule

    In FormKit, validation rules are just functions that accept a core node and return a boolean value — true for a passing validation, and false for failing:

    const rules = {
      async checkUsername ({ value }) {
        return new Promise((r) => setTimeout(() => r(value === 'foouser'), 500))
      }
    }
    

    The checkUsername async rule above will pass validation if the user types in foouser as their username. Notice the rule is wrapped in a rules object, which allows you to define as many rules as you want.

    Adding your async rule to your input

    You can define your custom rules directly on a <FormKit /> input, or globally to use on any input. For this solution, we'll put the rule directly on the input.

    Add your custom rules via the :validation-rules prop, which makes any rules inside available to the validation prop. We can optionally add custom validation messages via the :validation-messages prop.

    <FormKit
      type="text"
      label="Pick a username"
      help="Type “foouser” to pass validation"
      validation="checkUsername"
      :validation-rules="rules"
      :validation-messages="{ checkUsername: 'Your custom message.' }"
    />
    

    Validation

    Not only on submit but also after user removes focus from the input.

    Validation in FormKit actually happens real-time. The only thing you need to do is define when to show the user the validation messages, whether real-time (validation-visibility="live"), on blur (default behavior), or on submit. This is known as validation-visibility.

    The full solution, with improved user experience (UX)

    For async rules, it's usually a good idea to show the user a loading spinner so they know an operation is happening real time, and feedback when the server responds. Here's a full example that:

    1. Shows a loading spinner while the rule is validating.
    2. Shows the validation message if the rule fails.
    3. Shows a checkmark if the validation passes.

    Full solution: https://formkit.link/9741f666840a11954233982ee189ab43

    Note: In this contrived example, the backend is just mocked.