-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript.js
305 lines (258 loc) · 8.76 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
console.log("TEST");
// Constants and variables for DOM elements and todo list
const todoInput = document.querySelector("#task-input");
const taskContainer = document.querySelector(".ctn-tasks");
const form = document.querySelector(".ctn-input");
let todos = []; // Array for saving todos
//URL for API
const urlAPI = "http://localhost:4730/todos/";
////////////////////////////////////////////////////
//Saving and loading todos from the local storage ✅
// Function to save todos to local storage
function saveTodos() {
localStorage.setItem("todos", JSON.stringify(todos));
}
// Function to load todos from local storage
function loadTodos() {
const storedTodos = localStorage.getItem("todos");
if (storedTodos !== null) {
todos = JSON.parse(storedTodos);
todos.forEach(function (todo) {
// For each loaded todo, the render function is called to display it
renderTodo(todo);
});
}
}
//funtion to add todos to todolist
function addTodo(event) {
// Prevents the default behaviour of the form tag (reloading the page)
event.preventDefault();
// Input value without starting and final white space
const inputValue = todoInput.value.trim();
if (inputValue !== "") {
// If the input is not empty => creating new object
const newTodo = {
description: inputValue,
done: false,
id: Math.floor(Math.random() * 99999999),
};
// The new task is added to the array and rendered
todos.push(newTodo);
console.log(todos);
renderTodo(newTodo);
//Clear Value
todoInput.value = "";
//TEST
console.log(newTodo);
// The new task is sent to the local storage and to the backend API
saveTodos();
sendToBackend(newTodo);
}
}
////////////////////////////////////////////////////
//Creating new todo ✅
//Render a new task in the user interface
function renderTodo(todo) {
const taskItem = document.createElement("div");
taskItem.classList.add("task-item");
//Create Checkbox and connect with Object status done: true/false
const checkBox = document.createElement("input");
checkBox.type = "checkbox";
checkBox.id = "task-" + todo.id;
//TEST
console.log("log in renderTodo : ", todo.done);
//changes todo done value (for Backend Use)
checkBox.checked = todo.done;
checkBox.todoObj = todo;
//Create label, set ID and connect with Object description
const taskText = document.createElement("label");
taskText.textContent = todo.description;
taskText.setAttribute("for", "task-" + todo.id);
//Add checkbox and label to task-Item (html-div = task-item)
taskItem.appendChild(checkBox);
taskItem.appendChild(taskText);
//add to task-container (html-div = ctn-task)
taskContainer.appendChild(taskItem);
}
// Function for switching the status of a task
async function toggleCheckbox(event) {
if (event.target.type === "checkbox") {
const todo = event.target.todoObj;
todo.done = event.target.checked;
console.log("Updated todo:", todo);
try {
// Changes are sent to the backend API
await updateInBackend(todo);
} catch (error) {
//The local storage will be refreshed if errors appear
console.error("Error updating todo in backend:", error);
saveTodos();
updateInBackend(todo); // Repeat attempt to send the changes to the API
}
}
}
//Eventlistener submit input
form.addEventListener("submit", addTodo);
//Eventlistener Checkbox checked
taskContainer.addEventListener("change", toggleCheckbox);
////////////////////////////////////////////////////
//Filterinng of todos ✅
//Variables - Filter options for todos
const active = document.querySelector("#active");
const done = document.querySelector("#done");
const all = document.querySelector("#all");
//// Function to display tasks based on the selected filter
function showTodos(filter) {
const taskItems = document.querySelectorAll(".task-item");
taskItems.forEach(function (item) {
switch (filter) {
case "all":
item.style.display = "block";
break;
case "active":
if (!item.querySelector('input[type="checkbox"]').checked) {
item.style.display = "block";
} else {
item.style.display = "none";
}
break;
case "done":
if (item.querySelector('input[type="checkbox"]').checked) {
item.style.display = "block";
} else {
item.style.display = "none";
}
break;
}
});
}
// Eventlistener for filteroption "Active"
active.addEventListener("click", function () {
showTodos("active");
});
// Eventlistener for filteroption "Done"
done.addEventListener("click", function () {
showTodos("done");
});
// Eventlistener for filteroption "All"
all.addEventListener("click", function () {
showTodos("all");
});
////////////////////////////////////////////////////
//Delete todos with done:true
//function to remove completed Tasks in the API ⭕️
async function removeDone(event) {
console.log("Removing done todos...");
// Iterate backwards through the array
for (let i = todos.length - 1; i >= 0; i--) {
if (todos[i].done) {
console.log("Deleting done todo:", todos[i]);
// Get the ID of the task which is supposed to be deleted
const todoId = todos[i].id;
// Remove the task from the DOM
const checkboxId = "task-" + todoId;
const taskItem = document.getElementById(checkboxId).parentNode;
taskItem.remove();
try {
// Remove the task from the API
const url = urlAPI + todoId;
console.log("DELETE URL:", url);
const response = await fetch(urlAPI + todoId, {
method: "DELETE",
});
if (!response.ok) {
throw new Error("Failed to delete todo from backend.");
}
// Remove the task from the local todos array
todos.splice(i, 1);
console.log("Todo deleted from local array.");
// Save the updated local todos list to the localStorage
saveTodos();
console.log("Local todos updated.");
} catch (error) {
console.error("Error deleting todo from backend:", error);
continue; // Continue to next iteration even if an error comes up
}
}
}
}
//// Event listener and const for removing completed tasks
document.addEventListener("DOMContentLoaded", function () {
const clearButton = document.querySelector(".btn-clear");
clearButton.addEventListener("click", removeDone);
});
////////////////////////////////////////////////////
// Save the updated local todos list to the localStorage
saveTodos();
// Initial load of todos from local storage
document.addEventListener("DOMContentLoaded", function () {
loadTodos(); // First loading the todos
saveTodos(); // Then save todos, if before loaded
});
//////////////////////////////////////////////////////////////////////////////////////////
//API
//Load Data from API ✅
// Function which loads Data from Backend
async function loadFromBackend() {
//Request to Server
fetch(urlAPI)
//request successful? Yes - response pass to function (request params)
.then((request) => request.json())
//JSON parsing promise successful? Yes- parsed JSON data pass to function (as todos)
.then((todosFromAPI) => {
// Clear existing todos before loading from API
todos = [];
todosFromAPI.forEach(renderTodo);
//TEST
console.log("Zeigt API ITEMS an", todosFromAPI);
});
}
loadFromBackend();
////////////////////////////////////////////////////
//Send Data to the API ✅
//Function which sends new Items to Backend
function sendToBackend(todo) {
fetch(urlAPI, {
//POST-Method
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(todo),
})
.then((response) => {
if (!response.ok) {
throw new Error("Failed to add todo to backend.");
}
return response.json();
})
.then((data) => {
console.log("Todo added successfully:", data);
})
.catch((error) => {
console.error("Error adding todo to backend:", error);
});
}
////////////////////////////////////////////////////
//Updating Data in the API ✅
async function updateInBackend(todo) {
try {
const response = await fetch(urlAPI + todo.id, {
// HTTP method POST for adding new data
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(todo), // Converts the task into JSON format & sends it as a request body
});
// Check if the request was successful
if (!response.ok) {
// Error message if the request fails
throw new Error("Failed to update todo in backend.");
}
console.log("Todo updated successfully:", todo);
} catch (error) {
// Error response to an error during the update process
console.error("Error updating todo in backend:", error);
}
}