Nuxt Form: Simplify Form Management

Share

Form management can often become complex in modern applications. With Nuxt Form, you simplify the entire process, from submission to data validation and error handling, while remaining fully reactive thanks to Nuxt.


Table of Contents

Introduction

I recently published a Nuxt module, my very first public module, and I'm quite happy to be able to share it with the community. This composable adds functionalities similar to those found in Inertia/Vue, but using Nuxt.

For those unfamiliar with Inertia, it's a package I discovered at the same time as Laravel. Inertia helps simplify communication between the front-end and the back-end, particularly through its composables that facilitate form management.

One composable in particular inspired me to create this module: useForm(). It allows you to create forms with reactive data, error handling, data transformations, success messages, etc.

I therefore decided to transpose the developer experience (DX) offered by Inertia's useForm to Nuxt. My goal is to make form management as smooth and intuitive as possible within the Nuxt ecosystem, while drawing inspiration from Inertia's best practices.

Manage your forms efficiently with the useForm composable in Nuxt

The main function available in Nuxt Form is useForm. It allows you to create a reactive form and manage its state. Here's how you can use it:

const form = useForm({
  email: '',
  password: '',
})

This useForm initializes the form fields (email and password in this example) with default values. It also generates a set of tools to interact with your form in a fluid and reactive way.

Form submission in Nuxt with post, put, delete

One of the great strengths of Nuxt Form is the ability to easily send data using the post, put, patch, and delete methods. These methods allow you to make API calls while automatically managing the form's state. For example, to submit data:

form.post('/api/endpoint', {
  onSuccess: (res) => {
    console.log('Success:', res);
    form.reset(); // Resets the form
  },
  onError: (err) => {
    console.warn('Error:', err);
  },
});

Transforming data with transform

The transform method allows you to manipulate data before sending it. This is useful if you want to format or validate data (for example, remove extra spaces or normalize email formats).

form.transform((data) => {
  return {
    email: data.email.trim().toLowerCase(),
    password: data.password.trim(),
  }
  }).post('/api/endpoint', {
  onSuccess: (res) => {
    console.log('Data submitted successfully', res);
  },
  onError: (err) => {
    console.error('Error submitting data', err);
  },
});

In this example, the form data is transformed before being sent, ensuring it is in the correct format.

Managing errors with form.errors

Displaying client-side errors

Nuxt Form provides simple and reactive error handling. The form.errors composable allows you to easily manage and display errors specific to each form field.

<template>
  <input v-model="form.email" type="text" placeholder="Enter your email" />
  <p v-if="form.errors.email">{{ form.errors.email }}</p>
</template>

When errors occur (e.g., server-side validations), they are automatically assigned to form.errors, and you can display them directly in your template.

Managing validation with Nitro

With Nitro and Nuxt Form, managing form validation is simple and efficient. Here's how it works:

import { createUserValidator } from '../validators'

export default defineEventHandler(async (event) => {
  const result = await readValidatedBody(event, createUserValidator.safeParse)
  if (!result.success) {
    return createValidationError(result.error)
  }
  // Save data to the database...
  return { statusCode: 201, message: 'success' }
})

The approach involves reading the request body with readValidatedBody. If validation fails, errors are returned via createValidationError, which generates an HTTP response with status 422 - Unprocessable Entity. These errors are then dispatched to form.errors, allowing you to easily display them in your user interface.

This method ensures robust server-side validation, essential for securing your forms in a Nuxt application. Furthermore, it integrates perfectly with reactive client-side error handling, providing a smooth user experience while maintaining optimal security.

Resetting the Form with reset

This all works perfectly when validation passes, but what about when errors occur? When an error is detected, it's crucial to be able to react quickly and reset the form or parts of it. This is where form.reset comes in, a powerful tool to reset your form to its initial state, or simply to clear the problematic fields. You can reset the entire form, or a specific field:

form.reset(); // Resets all fields
form.reset('password'); // Resets only the "password" field

Handling Success and Errors with onSuccess and onError in Nuxt Form

When submitting a form, it's crucial to know whether the operation was successful or if errors occurred. With Nuxt Form, you can manage these events using callbacks like onSuccess, onError, and onFinish, giving you complete control over the form submission flow.

Using onSuccess: Manage Successful Submissions

The onSuccess method is triggered when the form submission is successful. This allows you to perform additional actions, such as resetting the form or displaying a confirmation message to the user.

form.post('/api/endpoint', {
  onSuccess: (response) => {
    console.log('Successful submission:', response);
    // Reset the form after a successful submission
    form.reset();
  }
});

In this example, after sending the data via POST, onSuccess is used to reset the form using form.reset(), providing a smooth user experience.

This is particularly useful after a successful submission or if you want to allow the user to start over with blank values.

Using onError: Manage Submission Errors

When the submission fails, the onError method comes into play. It catches the errors returned by the server, allowing you to display them to the user and take corrective actions, such as resetting only the erroneous fields in the form.

form.post('/api/endpoint', {
  onError: (error) => {
    console.error('Error during submission:', error);
    form.reset("password")
  }
});

With onError, errors are handled in a targeted manner. In this example, if an error occurs during submission, only the password field is reset using form.reset("password"). This ensures that the other form fields remain unchanged, thus improving the user experience by limiting disruptions.

Voici la traduction en anglais avec un format Markdown :

Combining Callbacks for Optimal Management

Thanks to the onSuccess, onError, and onFinish callbacks, you have full control over how submissions are handled in your Nuxt application. This allows you to customize user interactions based on the success or failure of the submission while maintaining smooth and reactive form management.

These submission management methods not only improve the user experience but also enhance the reliability and security of your server exchanges by ensuring clear handling of both errors and successes.

Manage Form State with processing

The processing field is a reactive property that indicates when an action is in progress, such as during form submission. This allows you to display a "loading" state or disable buttons while the request is being processed.

<button type="submit" :disabled="form.processing">Submit</button>

With this simple usage, you prevent multiple submissions while the form is being processed.

FAQ

How to Install the Nuxt Form Module to Manage Your Forms?

To install Nuxt Form and start managing your forms easily in a Nuxt application, simply use the Nuxt CLI. Run the following command in your terminal:

npx nuxi module add @louislschvn/nuxt-form

This command will automatically add the module to your Nuxt project, simplifying the management of reactive forms, validation, and submissions.

Can I Contribute to the Nuxt Form Project?

Yes, contributions are always welcome! If you want to improve Nuxt Form, you can clone the GitHub repository and start contributing. Here are the steps to set up the project locally:

  1. Clone the repository from GitHub:
    git clone git@github.com:LouisLSCHVN/nuxt-form.git
    
  2. Prepare the development environment:
    npm run dev:prepare
    
  3. Start the project in development mode:
    npm run dev
    

Feel free to submit pull requests or report issues on the project's GitHub repository!

Conclusion

Thank you for taking the time to read this article. I hope you found answers to your questions and that this overview of the Nuxt Form module is helpful. Don’t hesitate to contribute to the project; all the instructions are available in the README.md file on the GitHub repository.

If you enjoyed the project, feel free to give it a star on GitHub to support me.