I am creating a table which is looping through an array and displays the array in the table as list. I am displaying the address as an input field value :value="location.address"
The input fields are set to disabled and when I click on the edit button I updated the disabled property to false so that the input field can be edited. I have added a new property called editedAddress: null
and set that to null which is updated to the current address property this.editedAddress = this.locations[index].address
.
What I want is that when I click on the edit button, I want the address to be updated. I have added the following code for the update button but it does not work.
btnUpdate(index){
this.locations[index].address = this.editedAddress;
this.locations[index].disabled = !this.locations[index].disabled
}
Here is the full code
<template>
<div>
<table>
<tr>
<th>#</th>
<th>Locations</th>
<th>Actions</th>
</tr>
<tr v-for="(location, index) in locations" :key="index">
<td>{{index 1}}</td>
<td>
<input type="text" :value="location.address" :disabled="location.disabled">
</td>
<td>
<div class="action-btns">
<button @click="btnEdit(index)">Edit</button>
<button @click="btnUpdate(index)">Update</button>
<button @click="btnDelete(index)">Delete</button>
</div>
</td>
</tr>
</table>
<input type="text" v-model="address">
<button @click="addBtn">Add</button>
</div>
</template>
<script>
export default {
data(){
return{
locations:[
{
address:'Mall of lahore',
disabled: true
},
{
address: 'The Post Office',
disabled: true
},
{
address: 'Mall of Dubai',
disabled: true
}
],
address: '',
editedAddress: null
}
},
methods:{
btnEdit(index){
this.locations[index].disabled = !this.locations[index].disabled
this.editedAddress = this.locations[index].address
},
btnUpdate(index){
this.locations[index].address = this.editedAddress;
this.locations[index].disabled = !this.locations[index].disabled
},
btnDelete(index){
this.locations.splice(index , 1)
},
addBtn(){
let newAddress = {
address: this.address,
disabled: true
}
this.locations.push(newAddress)
this.address = '';
}
}
}
</script>
Please let me know what I am doing wrong or if there is a better way to solve it
CodePudding user response:
Your input field is bound to location.address
.
So, you are not editing your editedAddress
at all.
You can add @change="editedAddress = $event.target.value"
to your input field to change editedAddress
<input type="text" :value="location.address" :disabled="location.disabled" @change="editedAddress = $event.target.value" >
Tip: use Vue Dev Tools or JSON.stringify to check the data in your vue app
JSON.stringify(editedAddress): {{JSON.stringify(editedAddress)}}
Here is the link playground with the fix
CodePudding user response:
Since you don't explain what exactly do you mean by "I have added the following code for the update button but it does not work" I will assume that you UI is not being updated.
This is a caveats of reactivity in Vue reactive system https://vuejs.org/v2/guide/reactivity.html#For-Arrays
Probably Vue is not being able to pick that there were a change in your item inside the array locations
.
To make Vue understand that there was a change you can use Vue.set
:
btnUpdate(index){
Vue.set(this.locations[index], 'address', this.editedAddress);
// do the same for the other line
},
After this Vue should be able to pick that there was a change and re-render the UI for you.
Another approach is to replace the entire array (but in most cases this is a bit overkill)
btnUpdate(index){
const locations = [...this.locations];
locations[index].address = this.editedAddress;
this.locations = locations;
},