What is the best way to specify a submission destination for a custom form component in Vue?

I am looking to streamline the use of a form component across my website, however, I need the submit button to perform different actions depending on which page calls the form-component.

Experimenting with Vue components and data passing is new to me as I have previously worked on messy one-page apps.

My current strategy involves having the form gather inputs/filters from the form component and then when the submit button is clicked, somehow sending this data to the calling element - which will then handle it based on the specific scenario at hand. Is this the right approach for this situation (?)

  • Is my plan an appropriate use of Vue / a valid method for submitting a form from an external form-component?

  • How can I trigger the submission to send data / execute a method outside of my DashboardForm.vue component?

  • What is the best way to send fetched data from DashboardForm.vue in ReportType1.vue and reuse this functionality in ReportType2.vue?

This is the structure of my Vue Form component (DashboardForm.vue):

<template>

    <div class="row">

        <div class="col-12">
            <div class="card">
                <div class="card-body">

                    <form id="mainForm" class="form-material row" method="POST">
                        <div class="" id="date-range">
                            <datepicker v-model="startDate" input-class="form-control inputDate" placeholder="Start Date" required></datepicker>
                            <div class="input-group-append">
                                <span class="input-group-text b-0 text-white"> to </span>
                            </div>
                            <datepicker v-model="endDate" input-class="form-control inputDate" placeholder="End Date" required></datepicker>
                            <input type="button" class="btn btn-info waves-effect waves-light" v-on:click="groupFilterDisplay(true);" value="Filter by Group"/>
                            <!-- <input type="button" id="submit-btn" class="btn btn-success waves-effect waves-light" v-on:click="loadNew" value="Submit"/> -->
                            <input type="button" id="submit-btn" class="btn btn-success waves-effect waves-light" value="Submit"/>
                        </div>
                    </form>

                </div>
            </div>
        </div>

        <transition name="fade">
            <div id="groupFilter" class="popupGroupFilter" v-if="groupFilter">
                <div id="filterArea">
                    <input type="text" v-model="searchGroupInput" placeholder="Search" class="gfSearch">
                    <span class="gfTitle">Filter by Group</span>
                    <hr>
                </div>
                <div class="ulTree">
                    <ul>
                        <tree_item class="item" v-bind:model="groupTree"></tree_item>
                    </ul>
                </div>
                <div v-on:click="applyGroupFilter();" class="gfClose gfApply"><span>✔ Apply</span></div>
                <div v-on:click="groupFilterDisplay(false);" class="gfClose"><span>X Close</span></div>
            </div>
        </transition>

    </div>
</template>

<script>
// import { GF } from '../mixins/GF.js';

export default {
    name: 'DashboardForm',
    // mixins: [GF],
    data() {
        return {
            groupTree:          window.groups,
            searchGroupInput:   '',
            searchGroupArray:   [],
            groupFilterApplied: false,
            groupFilterBackup:  [],
            selectedIds:        [],

            groupFilter:        false, 
            startDate:          null,
            endDate:            null,
            mode:               0,
        }
    },
    props: {
        options: Array
    },
    watch: {
        'searchGroupInput': function (newVal, oldVal) {
            this.groupTree = this.searchGroupResult();
        }
    },
    methods: {
        recurseGroups: function (arr, action) {
        },
        applyGroupFilter: function () {

        },
        groupFilterDisplay: function (display) {

        },
        searchGroupResult: function () {
        },
        fetchGroupIds: function () {
        }
    }
};
</script>

Below is an example of a component that utilizes the DashboardForm ( ReportType1.vue):

<script>
    import DashboardForm    from "../tools/DashboardForm.vue";

    export default {
        components: {
            DashboardForm
        },
        data() {
            return {
            };
        },
        created() {
        },
        mounted() {
        },
        destroyed() {
        },
        watch: {
        },
        methods: {
        }
    }
</script>

<!-- Template -->
<template>
    <div>

        <!-- Include Form -->
        <DashboardForm/>

        <!-- Display form result -->
        <div id="resultContainer"> <datatable/> </div>

    </div>
</template>

Answer №1

If I've understood correctly, we're aiming to create a reusable form component. Let me provide you with a brief explanation of how VUE components communicate.

  1. The component receives necessary inputs through the use of props.
  2. The component can receive inner HTML content from its user using slot.
  3. The component triggers events to notify its user about any internal changes.

Here are examples illustrating these cases:

The template for your component named my-form:

<form>
    <div class="row">
        <slot></slot>
    </div>
    <div class="row">
        <div class="col-12">
            <button type="button" class="btn btn-default" @click="onSubmit"></button>
            <button v-if="hasReset" class="btn btn-danger" @click="onReset"></button>
        </div>
    </div>
</form>

The JavaScript file for your component:

export default {
name: 'my-form',
data() {
    return {
    }
},
props: {
    reset: boolean
},
computed: {
    hasReset: function(){
        return this.reset;
    }
}
methods: {
    onSubmit: function(){
        let data = { "name": "dummy data" };
        this.$emit("submit", data);
    },
    onReset: function(){
        let data = { "name": "" };
        this.$emit("reset", data);
    }
}
}

You can now include and use the my-form component in the following way:

<my-form :reset="formHasReset" @submit="onFormSubmit" @reset="onFormReset">
    <input class="col-12" type="text" name="name">
    <input class="col-12" type="text" name="username">
    <input class="col-12" type="password" name="password">
    <input class="col-12" type="email" name="email">
</my-form>

Corresponding JavaScript:

data(){
    formHasReset: true
},
methods: {
    onFormSubmit: function(data){
        console.log(data.name); //Expecting 'dummy data'
    },
    onFormReset: function(data){
        console.log(data.name); //Expecting ''             
    }
}

I trust that clarification helps! :).

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

The definition of Csrftoken is missing

The code I am currently using, as per the recommended documentation, is: function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); ...

What's the best way to ensure that your item list automatically updates the rendered list when an item is deleted

I've developed a web cart using Redux. The cart functions as expected, except for one issue - when I delete an item from the cart, the changes are only displayed after refreshing or navigating to another page. How can I update the view dynamically as ...

React state update not triggering a component re-render

I've been attempting to toggle the visibility of a div by clicking on another div, but I'm encountering an issue. The div becomes invisible on the first click only if it was visible initially. After that, it remains invisible and does not update. ...

Using Moment.js to showcase historical information within a specified timeframe based on the user's timezone

I'm finding it challenging to properly handle historical data display: Current Situation: The database contains records stored in "YYYY-MM-DD HH:mm:ss" format in UTC+0 (MariaDB - DateTime type) A web application (using moment.js) allows users to se ...

Tips for preserving the integrity of square brackets while extracting data from JSON

Everyone: We've decided to utilize Newtonsoft JSON.NET for serializing some C# POCOs, and here's what we have: { "RouteID": "123321213312", "DriverName": "JohnDoe", "Shift": "Night", "ItineraryCoordinates": [ [ 9393, 44 ...

Material UI does not support the inline attribute for applying CSS properties

Trying to adjust the CSS for Material-UI When setting the width, everything works fine. However, when attempting to set display inline, an error occurs ---> "inline is not defined" Can anyone provide guidance on how to resolve this issue? Sharing my cod ...

extract the field name from the json object

I need to send coordinates to the Google Maps API, but I'm struggling to remove the field name from my JSON object before sending the parameters. Object {TempPoints: "{lat: 51.478,lng: -3.192},{lat: 51.478,lng: -3.192…{lat: 51.47840998047034,lng: - ...

Enhancing jQuery Rating Plugin

Currently, I am working on customizing the jQuery Bar Rating System Plugin. You can view an example of the plugin by visiting this link: . The rating system on my end will resemble Example D. Rather than having the plugin based on user input, my goal is to ...

Tips for comparing two arrays in node.js

I am faced with the task of comparing two arrays. let runArray = ['Welcome', 'Hello'] let data = [{ Node:'Good', Session:'2', Run:'Welcome', Run_Group:'Display', Elapsed_Ms: '1000& ...

What is causing the warnings for a functional TypeScript multidimensional array?

I have an array of individuals stored in a nested associative array structure. Each individual is assigned to a specific location, and each location is associated with a particular timezone. Here is how I have defined my variables: interface AssociativeArr ...

Is there a way to adjust the padding of html and body elements to 0 in Vue.js without interfering with the styling of bootstrap

In my Vuejs project, I am designing a bootstrap navbar that has left and right margin spacing, even though I have not added any body or html padding. When I navigate to the welcome.blade.php file and set the body and html padding to 0 as shown below: *{ ...

Halt the update of a variable when a different variable reaches zero

I am currently working on a jQuery script that updates variables based on scroll events. var scrollTop = $(window).scrollTop(); var width = site.logoWidth - scrollTop; var logoPadding = scrollTop; My goal is to prevent the logoPadding variable from updat ...

Wrapping a group of elements with opening and closing tags using jQuery

I have a collection of distinct elements, like so: <section class="box-1"></section> <section class="box-2"></section> <section class="box-3"></section> My objective is to enclose all three elements within a div with a ...

Angular SPA boasting an impressive one million pages

Currently, I am in the process of transitioning my webshop, which contains numerous products, to an Angular SPA application using ngRoute and HTML5 mode. I have come up with a method where I receive some of my routes from the server as a JSON object, but s ...

Tips for utilizing the Apollo cache consistently during page transitions in NextJs

In the official examples repository of NextJS, I found this apolloClient.js file: import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client' import { concatPagination } from '@apollo/client/utilities' import merge from &apos ...

Adding static files to your HTML page with node.js

This is not a question about using express.static() In my application, I have multiple pages that share the same JS and CSS dependencies. Instead of adding <script> or <link> tags to every single page, I'm looking for a way to include the ...

Leveraging pre-rendered HTML in Vue.js components for both parent and child elements

Currently, I am rendering all the HTML server-side and attempting to use Vue to set this HTML as the $el for two components. According to the lifecycle diagram, this should be possible. There is a parent Vue instance (which binds to #main) that contains a ...

Cutting an in-memory Base64 PNG using ONLY JavaScript on the client side without relying on canvas

Scenario: Working with JavaScript in a SDK environment, either on node.js or a browser. Situation: I have a base64 string containing a PNG image encoded using base64 (extracted from selenium webdriver's takeScreenshot function). Inquiry: How can I c ...

Transferring information between pop-up and webpage

I have developed a simple form within an ERP system that allows users to create quick support tickets. However, instead of manually inputting the client ID in the form, I want to provide them with a more user-friendly option. My idea is to include a search ...

Manipulating events through adjusting values of a JQuery-UI range-slider

My range-slider's values are being set with the code: $('...').slider( 'values', [ 0, 10000 ] );. However, I am facing an issue where this line triggers the change( event, ui ) event twice. Is there a way to ensure it only triggers ...