I'm running into a problem where the toggle logic is broken. Simple todo-list, on click you should get the toggle of isCompleted. It happens right for the first item, but then it seems the value of isDone is random. Moreover, the changed state doesn't stay if I refresh. But when I console.log the returned object from the update, the field is correctly changed.
function updateTodo(task) {
//const updateUrl = "/api/todos/" + task.data("id");
const isDone = !(task.data("completed"));
const updateData = {
isCompleted: isDone
};
//$.ajax({
//method: "PUT",
//url: updateUrl,
//data: updateData
//})
task.toggleClass("done");
task.data("completed", isDone);
console.log("task.data completed:" + task.data("completed"));
}
// change status on todo
$("#todo-list").on("click", "li", function() {
updateTodo($(this));
});
body {
font-family: "Lato", sans-serif;
margin: 0;
padding: 0;
background-color: #efefef;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
header {
margin-bottom: 20px;
width: 50%;
text-align: center;
}
header h1 {
font-size: 3em;
color: purple;
font-weight: 500;
margin-bottom: 0px;
}
header h1 span {
font-weight: 800;
}
header h2 {
font-size: 1.2em;
font-weight: 400;
color: purple;
}
section {
width: 50%;
text-align: center;
padding: 20px;
margin-bottom: 20px;
}
.wrap {
display: inline-block;
/* centering */
position: absolute;
left: 50%;
margin-right: 50%;
transform: translate(-50%, -50%);
}
input {
/* cleaning up */
outline: none;
border: none;
padding: 20px;
font-size: 24px;
/* customize */
background: transparent;
border-bottom: 1px solid #fff;
color: purple;
z-index: 20;
}
.bg {
/* position */
position: absolute;
top: 0%;
height: 100%;
width: 0;
/* customize */
background: #fff;
transition: width 0.6s cubic-bezier(0.52, -0.43, 0.47, 1.29);
z-index: -2;
}
input:focus+.bg {
background: #fff;
width: 100%;
}
input::-webkit-input-placeholder {
color: #fff;
transition: color .3s ease;
}
input:focus::-webkit-input-placeholder {
color: transparent;
}
/* List */
#todo-list {
width: 50%;
list-style: none;
margin: 0;
padding: 0;
}
#todo-list li {
height: 60px;
line-height: 60px;
font-size: 1.5em;
background-color: white;
margin-bottom: 4px;
box-shadow: 1px 1px 1px silver;
color: purple;
}
#todo-list li.done {
background-color: #efefef;
text-decoration: line-through;
box-shadow: none;
border: 1px solid lightgray;
}
/* Delete buton */
#todo-list li span.delete {
display: inline-block;
background-color: crimson;
color: white;
text-align: center;
height: 60px;
width: 0px;
left: -60px;
margin-right: 20px;
transition: 0.2s ease-in;
opacity: 0;
}
#todo-list li:hover span.delete {
width: 60px;
opacity: 1;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Todo API</title>
<link href="app.css" rel="stylesheet" type="text/css">
<script src="http://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
</head>
<body>
<header>
<h1>todo<span>list</span></h1>
<h2>simple todo-list built with node</h2>
</header>
<section>
<div class="wrap">
<input type="text" id="todo-input" placeholder="What should you do ?">
<div class="bg"></div>
</div>
</section>
<ul id="todo-list">
<li class="task"><span class="delete">X</span>Debug code</li>
<li class="task"><span class="delete">X</span>Try this one</li>
</ul>
</body>
</html>
Listener:
$("#todo-list").on("click", "li", function () {
updateTodo($(this));
});
AJAX request and toggle:
function updateTodo(task) {
const updateUrl = "/api/todos/" + task.data("id");
const isDone = !(task.data("completed"));
const updateData = {isCompleted: isDone};
$.ajax({
method: "PUT",
url: updateUrl,
data: updateData
})
.then(function (todo) {
console.log(todo);
task.toggleClass("done");
task.data("completed", isDone);
console.log("task Data completed:" + task.data("completed"));
})
.catch(function (err) {
console.log(err);
});
}
The update route :
exports.updateTodo = function (req, res) {
db.Todo.findByIdAndUpdate(req.params.todoId, req.body, {new: true})
.then(function (todo) {
res.json(todo);
})
.catch(function (err) {
res.send(err);
});
}
I feel dumb trying to solve this for so long. I rewrite the code step by step, but I don't have a clue what's wrong.
Someone can give me a hint?
Thanks a lot for your time ! Cheers