Prevent submission of form by disabling button until modifications are made to the original data in Vue.js

For experimental purposes, I have created a simple form and am trying to implement a feature where the button remains disabled until the original form data is changed. Additionally, I want to ensure that the button stays disabled even if the changed data is reverted back to the original data (undo).

<template lang="pug">
  form(@click.prevent="save")
    .main
      input(v-model="user.name")
      input(v-model="user.email")
      input(v-model="user.age")
      select(v-model="user.sex")
        option Male
        option Female
    .footer
      button(:disabled="isFormEnable") Save
</template>

<script>
export default {
  name: 'userForm',
  data () {
    return {
      user: {
        name: 'John Doe',
        email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ed87828583ad8a">[email protected]</a>',
        age: '35',
        sex: 'Male',
      }
    }
  },

  computed: {
    isFormEnable () {
      // I am not sure what I need to do here but something like this may be:
      if (user.name) { return true }
    }
  },

  methods: {
    save () {
      console.log('Form Submitted')
    }
  }
}
</script>

Although I came across a jQuery solution here, I am specifically looking for a vanilla/ Vue.js solution.

$('form')
    .each(function(){
        $(this).data('serialized', $(this).serialize())
    })
    .on('change input', function(){
        $(this)             
            .find('input:submit, button:submit')
                .prop('disabled', $(this).serialize() == $(this).data('serialized'))
        ;
     })
    .find('input:submit, button:submit')
        .prop('disabled', true)
;

Answer №1

My approach involves using just one module to achieve the desired outcome

npm i deep-diff

deep-diff is specifically designed for comparing object values.

<script>
import { diff } from "deep-diff";

// setting the default form value
const defaultUser = {
  name: "John Doe",
  email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b0dadfd8def0d7ddd1d9dc9ed3dfdd">[email protected]</a>",
  age: "35",
  sex: "Male"
};

export default {
  //...
  data() {
    return {
      user: { ...defaultUser } // using object spread syntax to clone the object
    };
  },

  computed: {
    isFormEnable() {
      // checking if the user data matches the default value
      if (!diff(this.user, defaultUser)) return false;

      return true;
    }
  },
  //...
};
</script>

Answer №2

Learn how to implement form field changes detection using Computed and Watch properties:

<template>
  <form>
    <label>Full Name</label>
    <input v-model='form.fullName' />

    <label>Email</label>
    <input v-model='form.email' />

    <button :disabled="!isModified">Submit</button>
  <form>
</template>
<script>
import _ from 'lodash'

export default {
  data() {
    return {
      isModified: false,
      form: {},
    }
  },

  computed: {
    originalData() {
      return this.$store.state.form
    }
  },
  
  watch: {
    originalData() {
      this.form = _.cloneDeep(this.originalData)
    },

    form: {
      handler() {
        this.isModified = !_.isEqual(this.form, this.originalData)
      },
      deep: true,
    },
  },

  created() {
    this.$store.dispatch('initialize')
  }
}
</script>

Visit this website for in-depth insights and a comprehensive explanation.

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

How can I pass the value of a variable from one Vue.js 2 component to another?

Here is how I have structured my view: <div class="row"> <div class="col-md-3"> <search-filter-view ...></search-filter-view> </div> <div class="col-md-9"> <search-result-view ...></ ...

What is the method for setting the content-type in an AJAX request for Android browsers?

I am facing an issue with my ajax call to the Rails server. The response from the server varies between HTML and JSON based on the content type. Surprisingly, this works smoothly on iPhone and desktop browsers like Chrome, but I am encountering a problem o ...

What is the best way to adjust the size of a Div slideshow using

I need help with creating a slideshow that covers my webpage width 100% and height 500px. The image resolution is 1200*575. Can someone assist me with this? CSS #slide{ width : 100%; height: 500px; } HTML <!DOCTYPE html> <html> ...

Encountered an issue while attempting to start the JavaScript debug adapter in Visual Studio

When attempting to debug my script code in Visual Studio, I encountered an error. How can I resolve this issue? ...

The print preview displays a single div in an incorrect location

I have successfully created a javascript plot and wanted to incorporate a legend that overlaps the plot. Unfortunately, the function I used does not support directly overlapping legends, but it does allow for placing the legend in a separate div. To work a ...

The functionality of the AJAX Script is failing to load properly on mobile devices

Currently, I am undertaking a project that involves ESP32 Arduino programming to create a webpage where users can interact with buttons to activate relays. Additionally, I have implemented a slider using a short script. This project is inspired by the ESP3 ...

Troubleshooting drag-and-drop functionality in a JavaScript HTML5 application resembling a Gmail upload interface

Here is a snapshot of my user interface: Each node in the tree structure is represented by an <li> element along with an <a> link. Furthermore, each folder serves as a dropzone for file uploads similar to the drag-and-drop feature found in Gm ...

Is it a glitch or intentional design in Vue's template vslots feature?

I have noticed that some of my computed properties do not execute when they access the same data. To illustrate, consider this basic example: <template v-for="item in foo" v-slot:['sameSlot`]="{sameBlah}"> {{ JSON.stringify ...

Prevent regex special characters in JavaScript while preserving the original string for keyword matching

As I develop my web page, I encountered an issue while trying to highlight text based on user input in the search box. My search algorithm matches each space-separated keyword, but ran into problems when including brackets in the search term. This caused a ...

Unlocking the secrets of accessing HashMaps containing Objects post conversion to JSON

In my Java code, I have created a data structure using HashMap that stores PriceBreak objects along with corresponding PricingElement ArrayLists. This data has been sent to the client via GSON. However, when I try to access this object in JavaScript and lo ...

Unable to assign a value to the HTMLInputElement's property: The input field can only be set to a filename or an empty string programmatically

When attempting to upload an image, I encountered the error message listed in the question title: This is my template <input type="file" formControlName="avatar" accept=".jpg, .jpeg .svg" #fileInput (change)="uploa ...

How can I get my ReactJS file to properly show the user's email address?

After clicking submit, I encountered errors in both localhost (3000 and htdocs). When using localhost 3000, upon hitting submit, I was redirected to http://localhost:3000/index.php with the error message: Cannot POST /index.php While in localhost via the ...

Can the geocoder API/search box be utilized to locate specific markers on a map?

Incorporating Mapbox into an Angular application with a high volume of markers on the map (potentially thousands) and hoping to implement a search box for users to easily locate specific markers based on unique names and coordinates. Is this functionalit ...

Downloading multiple files on both iOS and Android devices

Is there a way to download assets (mp3/jpeg) in an Asynchronous manner? I have over 200 files in each case and the process is taking too long. Are there any techniques to speed up the download process on both iOS and Android? ...

Efficiently loading an image in one go

Rendering approximately 3000 records, each row displays: Customer Profile Edit Customer Name, Action 1 John Edit image | Delete image 2 John Edit image | Delete image 3 John Edit image | Delete image 4 John ...

Restrict the quantity of user responses with JavaScript

For this questionnaire, users are limited to selecting and ranking only 3 out of the 5 listed Social Apps. I am currently using questback to build the survey, but I require assistance in implementing a JavaScript condition. <table> <tr> & ...

Images on web pages are automatically resized to fit into a smaller preview window

Currently, I am facing an issue with the display of images in my grid windows on my website . The images are appearing as partial representations instead of rescaled versions where the whole picture is resized to fit the grid window. I have attempted mod ...

NodeJS application experiencing significant delays due to slow response times from MySQL database queries

Currently, I am in the process of learning about Node.js. Through utilizing Express and Node-Mysql, I have been able to effectively query my mysql database and return the outcomes as JSON to the client. However, there seems to be a significant delay. Eve ...

Obtain the value of a JavaScript form with a dynamically generated field name

I am struggling with a simple javascript code and for some reason, it's not working. var number = 5; var netiteration = "net"+number; // now netiteration is equal to net5 var formvalue = document.forms.myformname.netiteration.value; Why is this co ...

What is the process for installing fontawesome using npm?

I encountered an error while attempting to install that looks like the following: $ npm install --save @fortawesome/fontawesome-free npm WARN saveError ENOENT: no such file or directory, open 'C:\Users\Admin\Desktop\package.json&a ...