Using Vue to create a single submit() method that works with multiple forms

Having multiple forms with the same logic for validation and submission, I want to streamline my code by creating a single method to handle form actions. Currently, there is redundancy in my code as each .vue file contains the same onSubmit() method.

Here is how my HTML looks:

<div id="app">
    <myform-one></myform-one>
    <myform-two></myform-two>
</div>

My JavaScript (main.js - webpack entry file):

import Vue from 'vue';
import Myform1 from './myform1.vue';
import Myform2 from './myform2.vue';

new Vue({
    el: '#app',
    components: {
        myformOne: Myform1,
        myformTwo: Myform2
    }
});

And now, the Vue component files:

myform1.vue:

<template>
    <div>
        <form @submit.prevent="onSubmit">
            <input type="text" v-model="fields.fname11" />
            <input type="text" v-model="fields.fname12" />
            <button type="submit">submit</button>
        </form>
    </div>
</template>

<script>
    let formfields = {
        fname11: '',
        fname12: ''
    };

    export default {
        data() {
            return {
                fields: formfields
            }
        },

        methods: {
            onSubmit() {
                // code responsible for reading, validating and sending data here
                // ...
                console.log(this.fields);
            }
        },
    }
</script>

and myform2.vue:

<template>
    <div>
        <form @submit.prevent="onSubmit">
            <input type="text" v-model="fields.fname21" />
            <input type="text" v-model="fields.fname22" />
            <input type="text" v-model="fields.fname23" />
            <button type="submit">submit</button>
        </form>
    </div>
</template>

<script>
    let formfields = {
        fname21: '',
        fname22: '',
        fname23: '',
    };

    export default {
        data() {
            return {
                fields: formfields
            }
        },

        methods: {
            onSubmit() {
                // code responsible for reading, validating and sending data here
                // ...
                console.log(this.fields);
            }
        },
    }
</script>

Is there a way to create and utilize a common method submitForm()? And where should its code ideally reside for good coding practices?

Answer №1

Implementing Vue3 (using Quasar in my case, but adaptable to any framework):

Imagine you have a parent component that houses multiple forms <Forms />:

To start, create a composable function named useForms.js:

import { ref } from 'vue'

const forms = ref([])

export function useForms(){
  
  const checkForms = () => {
    forms.value.forEach((form) => form.validate()
  }  

  const addFormToFormsArray = (form) => {
    forms.value.push(form)
  }

  return { forms, addFormToFormsArray, checkForms }
}

Next, import the function into your <Forms /> component:

<template>
  <Form />
  <Form />
  <Form />
  <button @click="checkForms">Check Form</button>
</template>

<script setup>
import { useForms } from '../useForms';

const { checkForms } = useForms()
</script>

Lastly, within each <Form /> component:

<template>
  <form ref="form">
    .../content
  </form>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useForms } from '../useForms';

const form = ref(null)

onMounted(() => {
  addFormToFormsArray(form.value)
})

const { checkForms, addFormToFormsArray } = useForms()
</script>

When running the check function in the parent component, it should iterate through each form and identify any potential issues.

Answer №2

Develop a dedicated file to house the following logic:

// formActions.js
export default function (formData) {
   // include code for data retrieval, validation, and transmission here
   // ...
}

Utilize this logic in various components by importing it:

import formActions from "../services/formActions.js"
...
methods: {
  handleSubmit() {
    formActions(this.formData)
  }
}

Answer №3

We have a few options to consider, but my personal favorite involves creating a mixin that can be easily reused. You can learn more about mixins in the Vue documentation on mixins.

export const form_actions = {
  methods: {
     on_submit() {
      //logic for handling form submission
     },
     //other reusable methods can go here
  }
}

To use this mixin in your components, simply do the following:

import { form_actions } from 'path_to_mixin'
export default {
  mixins: [form_actions]
}

When you include the mixin in a component, all its properties (such as created hooks, methods, and data) will be merged with the component. This allows you to easily access the mixin method like this.on_submit().

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for deactivating a form field through ajax within a commandlink located in a datatable

I'm facing an issue where I have a form capturing Contract records and displaying them in a datatable. The datatable has an "Edit" commandlink tag, which when clicked should populate the form with the contract data, but disable the Contract No field. ...

Displaying selected values in a Multi Select Listbox upon submission of the same form when an error occurs

When the page is first loaded: Retrieve the values from the table field and store them in a variable If the field is blank, do not take any action Populate the listbox with default custom values When the form is submitted (on the same page) and multipl ...

Achieve the effect of making the Bootstrap JS Collapse text bold after it has been

Is there a way to make Bootstrap JS Collapse text Bold after it has been clicked on? <tr data-toggle="collapse" data-target="#demo8" class="accordion-toggle"> <td> <div class="fa ...

Trigger an action in the clean-up function of useEffect

I am facing an issue with a form component in a Material UI <Tab /> where users can update their address information. The data is fetched from the API using redux-thunk, and the form fields are pre-filled with server data before the update occurs. h ...

The pagination feature of the material-ui data grid is experiencing issues with double clicks because of its compatibility with the react-grid-layout library for

I am currently using the react-grid-layout library to manage the resizing of both charts and a material-ui data grid table. However, I am encountering an issue where when clicking on the table pagination arrow, it does not work properly. I have to click tw ...

Is there an easier method to utilize ES6's property shorthand when passing an object in TypeScript, without needing to prefix arguments with interface names?

When working with JavaScript, I often find myself writing functions like the one below to utilize ES6's property shorthand feature: function exampleFunction({param1, param2}) { console.log(param1 + " " + param2); } //Usage: const param1 = "param1" ...

Tips for tackling drag and drop functionality with only HTML, CSS, and JavaScript

Currently, I am faced with a challenge involving drag and drop TEST. Observing the image provided below, you will notice 3 columns each containing 3 small boxes of varying colors. These boxes are draggable, meaning they can be moved between columns follow ...

Error encountered in node.js script due to misuse of Sqlite's SQLITE_MISUSE functionality

Upon running my code with this query, I have encountered a situation where all tables are listed sometimes, while other times only one table is shown and consistently the following error is displayed: Query Error: Error: SQLITE_MISUSE: unknown error I ha ...

Generating JSON data on the fly using D3.js scripting

I am attempting to create a JSON object dynamically by pulling data from an array in D3 JavaScript. (The code below is not the exact one I used, but similar) let radius = [10,20,30]; let jsonradius = '[{'; for (let i = 0; i < radius.le ...

I encountered an error in my Vue CLI project despite having worked on numerous Vue projects in the past

Issue: 'C:\Users\Karim\Desktop\vue project 2020\image-new-project\node_modules\colorette' does not have a valid exports main View error image This is a blockquote ...

What is the best way to use jQuery to insert this block of HTML into a page from a JSON response?

<script type="text/javascript"> var dataString2 = 'run=captchagood&comment=' + comment; $.ajax({ type: "POST", url: "process.php", data: dataString2, dataType: "json", error: 'error', success: function ...

Is it feasible to incorporate turn.js into an Angular project using cdn resources?

I'm currently working on an Angular project and I have successfully integrated the turn.js library to create a flipbook. https://i.sstatic.net/Mg86k.png However, when I try to navigate to the next page in the book, it briefly shows the next page but ...

Guide to dynamically binding two input fields in a table using Jquery

I'm looking for help with binding 2 input text fields that were dynamically added to a table inside a loop using JavaScript/JQuery Syntax. My goal is to automatically populate the second field with text from the first one. I was successful in achievin ...

JavaScript Arrays and Their Mysterious Undefined Elements

Creating a basic HTML document with a JavaScript script can be quite simple. ... <script type = "text/javascript"> src = "xxx.js"></script> ... <body> <ul id ="pics"> <li><a href="A.jpg">A</a></li> ...

Vue's innate lifecycle hook

I am looking for a way to automatically run a specific function as a beforeMount hook in every component of my Vue project without having to declare it individually. Essentially, I want a default behavior where if the hook is not explicitly stated in a com ...

Retrieve information from the SEMrush API response dataset

I am currently facing an issue with extracting data from the SEMrush api, as their response does not adhere to the standard "key:value" JSON format. Instead, each key and value is displayed in separate rows as shown below. Request Example: http://api.sem ...

Using ThreeJS to assign various textures based on the position of the object

Recently, I delved into the world of ThreeJS and embarked on creating a model of the Earth using a Sphere mesh. Alongside this, I crafted a model of the Sun and now desire to infuse two distinct textures onto the Earth model based on its orientation. Speci ...

Configuring settings for gulp-jshint

I'm currently utilizing gulp to compile my JavaScript code. My intention is to run jshint on the files before concatenating them, but I'm encountering difficulties in configuring the options properly. Am I handling this process correctly? var re ...

Merging data sets with Javascript: A comprehensive guide

As a newcomer to the world of javscript, I'm faced with what seems like a simple question. I'm working with two datasets that contain a common column and I'd like to merge them together. The structure of the datasets is as follows: const da ...

Why is my output getting mixed up with the header on the navigation bar page?

output capture image https://i.sstatic.net/BYJnk.jpg here is the code snippet //ui.r library(shiny) navbarPage(theme = "style.css",img(src="logo.jpeg", width="300px"), tabPanel("Dashboard"), tabPanel("Products"), tags$head( t ...