Reputation: 15
I'm a newbie and I fetched some data from firebase and after being able to display, add and delete them successfully. I also want to edit them and update them to firebase again.
So I bind the post I wish to edit to an input wth v-model, called an editPost function on the edit button and I also passed in the index but the issue I'm having is that if I clicked the edit button on one of the posts it is also firing the other edit buttons
This is my template:
<div v-for="(post, i) in posts" :key="i">
<h3>By: {{ post.name }}</h3>
<p>
{{ post.post }}
</p>
<p>{{ post.date }}</p>
<button @click="deletePost(i)">delete</button>
<button v-if="editMode" @click="editPost(i)">Edit</button>
<input type="text" v-if="!editMode" v-model="post.post">
<button v-if="!editMode" @click="savePost">Save</button>
<button v-if="!editMode" @click="cancleEditMode">Cancle</button>
</div>
This is where I called the editPost function:
const editMode = ref(true)
const postItem = ref("")
const editPost = (i) => {
editMode.value = false
postItem.value = posts.value.find((post) => post.i === i)
console.log(i)
}
Upvotes: 0
Views: 192
Reputation: 391
You are on the right track! One thing I notice right away is that you are using the index as the key which is fine for learning and experimentation. However, when it comes to updating the item in the database, index is irrelevant. You should use the item id instead which is also the key in the database.
It appears from this snippet that your UI is dependent on the variable editMode
which is true on page load. Upon clicking editPost
that variable turns false as executed by your editPost()
function. Reason I mention this is because I assume you wish to only put a single item or 'post' in edit mode. However, as it is written now, you are changing the state for the entire component, therefore every post will be in edit mode.
The easiest way to fix this would only modify your code a touch. Alternatively, you could implement Vuex/Pinia for global state management, or refactor the post to another component with its own state. For simplicity, I'm showing the first option here.
<div v-for="(post, id) in posts" :key="id">
<button @click="deletePost(id)">delete</button>
<div v-if="post === postItemToEdit">
<input type="text" v-model="post.post">
<button @click="savePost">Save</button>
<button @click="cancleEditMode">Cancle</button>
</div>
<button v-else @click="editPost(post)">Edit</button>
</div>
<script>
const postItemToEdit = ref()
const editPost = (post) => {
postItemToEdit.value = post
console.log(postItemToEdit)
}
</script>
Note grouping inputs in one v-if div
so as not to repeat the v-if each time. Also using v-else for simplicity on the alternative option.
Upvotes: 1