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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With