6

I have a simple form which I have created just for experiment purpose. I am trying to keep the button disable unless original form data is changed but still keep the button disabled if the data changes is reverted back to 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: '[email protected]',
        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>

I found a jQuery solution here but I am looking for vanilla/vue javascript 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)
;
1
  • Instead of using computed, you can try using watched which watches properties change and reacts acc. to them Commented Apr 3, 2018 at 10:06

2 Answers 2

3

Here's how i would do it with the help of 1 module

npm i deep-diff

deep-diff is for comparing object values.

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

// default form value
const defaultUser = {
  name: "John Doe",
  email: "[email protected]",
  age: "35",
  sex: "Male"
};

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

  computed: {
    isFormEnable() {
      // check if it's default value
      if (!diff(this.user, defaultUser)) return false;

      return true;
    }
  },
  //...
};
</script>
Sign up to request clarification or add additional context in comments.

Comments

0

Here's how to do it natively with Computed and Watch properties:

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

    <label>Age</label>
    <input v-model='form.age' />

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

export default {
  data() {
    return {
      changed: false, // for storing form change state
      form: {}, // data variable to store current form data binding
    }
  },

  computed: {
    // store the original form data
    originalForm() {
      return this.$store.state.form
    }
  },
  
  watch: {
    // by watching the original form data
    // create a clone of original form data
    // and assign it to the form data variable
    originalForm() {
      this.form = _.cloneDeep(this.originalForm)
    },

    // watch the changes on the form data variable
    form: {
      handler() {
        // using lodash to compare original form data and current form data
        this.changed = !_.isEqual(this.form, this.originalForm)
      },
      // useful to watch deeply nested properties on a data variable
      deep: true,
    },
  },

  created() {
    // dispatch an action to fill the store with data
    this.$store.dispatch('init')
  }
}
</script>

Checkout this blog for more details and better understanding.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.