Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Editing a form with save and cancel options

I'm new to VueJS. I'm trying to create a form with simple Save and Cancel functionality. When binding the model to form fields they get updated immediately as the inputs are changed, but I don't want that tight binding. Instead, I want to be able to save and submit when the "Save" button is pressed and revert the changes when the "Cancel" button is pressed.

What's the suggested Vue way of doing this?

It would also be ideal if we can show the server save status and indicate it on the form if the submission is failed. If you know of any examples or samples that would be hugely helpful. Thanks!

See in JSFiddle

<template>
  <div id="app">
    <div>
      First Name:
      <input type="text" v-model="user.firstName" :disabled="!isEditing"
             :class="{view: !isEditing}">
    </div><div>
      Last Name:
      <input type="text" v-model="user.lastName" :disabled="!isEditing"
             :class="{view: !isEditing}">  
    </div>
    <button @click="isEditing = !isEditing">
      {{ isEditing ? 'Save' : 'Edit' }}
    </button>
    <button v-if="isEditing" @click="isEditing = false">Cancel</button>
  </div>
</template>

<script>
  var app = new Vue({
    el: '#app',
    data: {
      isEditing: false,
      user: {
        firstName: 'John',
        lastName: 'Smith'
      }
    }
  })
</script>

<style>
  .view {
    border-color: transparent;
    background-color: initial;
    color: initial
  }
</style>
like image 714
orad Avatar asked Sep 12 '17 01:09

orad


1 Answers

There's a few ways to handle this. You could create a separate component for the form, pass props to it, and then handle the editing/saving by emitting changes or if you want to keep it in a single component you could use value binding and refs, e.g.

var app = new Vue({
  el: '#app',
  data: {
    isEditing: false,
    user: {
      firstName: 'John',
      lastName: 'Smith'
    }
  },
  methods: {
    save() {
      this.user.firstName = this.$refs['first_name'].value;
      this.user.lastName = this.$refs['last_name'].value;
      this.isEditing = !this.isEditing;
    }
  }
})
.view {
  border-color: transparent;
  background-color: initial;
  color: initial
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>

<div id="app">
  <div>
    First Name:
    <input type="text" ref="first_name" :value="user.firstName" :disabled="!isEditing"
           :class="{view: !isEditing}">
  </div><div>
    Last Name:
    <input type="text" ref="last_name" :value="user.lastName" :disabled="!isEditing"
           :class="{view: !isEditing}">  
  </div>
  <button @click="isEditing = !isEditing" v-if="!isEditing">
    Edit
  </button>
  <button @click="save" v-else-if="isEditing">
  Save
  </button>
  
  <button v-if="isEditing" @click="isEditing = false">Cancel</button>
</div>

Or you could use a variable cache mechanism (with suggested edits) e.g.

var app = new Vue({
  el: '#app',
  data: {
    isEditing: false,
    user: {
      firstName: 'John',
      lastName: 'Smith',
    }
  },
  mounted() {
    this.cachedUser = Object.assign({}, this.user);
  },
  methods: {
    save() {
      this.cachedUser = Object.assign({}, this.user);
      this.isEditing = false;
    },
    cancel() {
      this.user = Object.assign({}, this.cachedUser);
      this.isEditing = false;
    }
  }
})
.view {
  border-color: transparent;
  background-color: initial;
  color: initial
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <div>
    First Name:
    <input type="text" v-model="user.firstName" :disabled="!isEditing"
           :class="{view: !isEditing}">
  </div><div>
    Last Name:
    <input type="text" v-model="user.lastName" :disabled="!isEditing"
           :class="{view: !isEditing}">  
  </div>
  <button @click="isEditing = !isEditing" v-if="!isEditing">Edit</button>
  <button @click="save" v-else-if="isEditing">Save</button>
  <button v-if="isEditing" @click="cancel">Cancel</button>
</div>

With any of these options you can set a status message at the start of the save method and then update it whenever you're done with the server call.

like image 80
Steven B. Avatar answered Nov 12 '22 20:11

Steven B.