I have a Vue app: it is To Do List, where after adding some notes by clicking button Add Task we receive a list of items to do. On the front of each item we have button Delete and checkbox to have opportunity to mark it as done. The bug is when I for example mark one of the items in the list as checked and after that delete it-marker that it was checked goes to the other item which was not marked as checked initially. Can you please advice how it can be solved using Vue.js or any other option? Below is my code:
Vue.createApp({
data(){
return{
placeholder: 'Start typing',
inputvalue: '',
notes: []
}
},
mounted() {
this.notes = JSON.parse(localStorage.getItem('note')) || [];
},
watch: {
notes: {
handler: function() {
localStorage.setItem('note', JSON.stringify(this.notes));
},
deep: true
}
},
methods: {
addnewtask(){
if (this.inputvalue !== ''){
this.notes.push(this.inputvalue)
this.inputvalue=''
}
},
removetask(index){
if (confirm('Do you really want to delete?'))
this.notes.splice(index, 1)
}
}
}).mount(app)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>To Do List</title>
</head>
<link rel="stylesheet" href="style.css">
<body>
<div id="app">
<div >
<h1>To Do List</h1>
<div >
<input
type="text"
v-bind:placeholder="placeholder"
v-model="inputvalue"
v-on:keypress.enter="addnewtask"
/>
<button v-on:click="addnewtask">Add Task</button>
</div>
<hr />
<ul v-if="notes.length !== 0"...>
<li v-for="(note, index) in notes">
<div>
<input type="checkbox"/>
({{index 1}}) {{note}}
</div>
<button v-on:click="removetask(index)">Delete</button>
</li>
<hr />
<li>
<strong>Total: {{notes.length}}</strong>
</li>
</ul>
<div v-else>No task exist, please add first one.</div>
</div>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script src="Vue3.js"></script>
</body>
</html>
CodePudding user response:
The main issue in you code is, you don't store any information about which task is checked and which one is not.let's say you checked 3rd task and then delete it, the new 3rd item from the top will be auto checked as it has no information about the task so can't differentiate between the new and the deleted task.
This can be solved many way one easy solution is, in your notes
array store two types of data. One title
and one is isChecked
then v-model the checked value in template.
Update your addnewtask()
function like this,
addnewtask() {
if (this.inputvalue !== "") {
this.notes.push({
title: this.inputvalue,
isChecked: false,
});
this.inputvalue = "";
}
},
In html use a v-modal to add a two way data binding for the note.isChecked
and update note
like note.title
since note is currently an object now.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>To Do List</title>
</head>
<link rel="stylesheet" href="style.css" />
<body>
<div id="app">
<div >
<h1>To Do List</h1>
<div >
<input
type="text"
v-bind:placeholder="placeholder"
v-model="inputvalue"
v-on:keypress.enter="addnewtask"
/>
<button v-on:click="addnewtask">Add Task</button>
</div>
<hr />
<ul v-if="notes.length !== 0" ...>
<li v-for="(note, index) in notes">
<div>
<input type="checkbox" v-model="note.isChecked" />
({{index 1}}) {{note.title}}
</div>
<button v-on:click="removetask(index)">
Delete
</button>
</li>
<hr />
<li>
<strong>Total: {{notes.length}}</strong>
</li>
</ul>
<div v-else>No task exist, please add first one.</div>
</div>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script src="Vue3.js"></script>
</body>
</html>
Here is a vue playgroud link for your code demo.