├── README.md ├── app.js ├── github.svg ├── index.html ├── instagram.svg ├── linkedin.svg └── style.css /README.md: -------------------------------------------------------------------------------- 1 | # to-do-webpage -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //Select DOM 2 | const todoInput = document.querySelector(".todo-input"); 3 | const todoButton = document.querySelector(".todo-button"); 4 | const todoList = document.querySelector(".todo-list"); 5 | const filterOption = document.querySelector(".filter-todo"); 6 | 7 | //Event Listeners 8 | document.addEventListener("DOMContentLoaded", getTodos); 9 | todoButton.addEventListener("click", addTodo); 10 | todoList.addEventListener("click", deleteTodo); 11 | filterOption.addEventListener("click", filterTodo); 12 | 13 | //Functions 14 | function getItemFromLocalStorage() { 15 | const todos = JSON.parse(localStorage.getItem("todos")) || []; 16 | 17 | return todos; 18 | } 19 | 20 | function addTodo(e) { 21 | //Prevent natural behaviour 22 | e.preventDefault(); 23 | if (todoInput.value.trim() === "") { 24 | //alert("Fill the box"); 25 | openmodal("red", "Please enter a Task!"); 26 | return; 27 | } 28 | 29 | // alert("Duplicate task") 30 | if(isDuplicate(todoInput.value)){ 31 | openmodal('red','This Task is already added!'); 32 | return; 33 | } 34 | 35 | 36 | //Create todo div 37 | const todoDiv = document.createElement("div"); 38 | todoDiv.classList.add("todo"); 39 | //Create list 40 | const newTodo = document.createElement("li"); 41 | newTodo.innerText = todoInput.value; 42 | 43 | let newTodoItem = { 44 | id: Math.round(Math.random() * 100), //id for selection 45 | task: todoInput.value, 46 | status: "incomplete", 47 | }; 48 | todoDiv.setAttribute("key", newTodoItem.id); 49 | 50 | //Save to local - do this last 51 | //Save to local 52 | saveLocalTodos(newTodoItem); 53 | // 54 | newTodo.classList.add("todo-item"); 55 | newTodo.classList.add("todo") 56 | todoDiv.appendChild(newTodo); 57 | todoInput.value = ""; 58 | const edit = document.createElement("div"); 59 | edit.innerHTML = 60 | `
`; 74 | edit.classList.add("hide"); 75 | todoDiv.appendChild(edit); 76 | //Create Completed Button 77 | const completedButton = document.createElement("button"); 78 | completedButton.innerHTML = ``; 79 | completedButton.classList.add("complete-btn"); 80 | todoDiv.appendChild(completedButton); 81 | //Create edit button 82 | const editButton = document.createElement("button"); 83 | editButton.innerHTML = ``; 84 | editButton.classList.add("edit-btn"); 85 | editButton.addEventListener("click", () => editTodo(newTodoItem, todoDiv)); 86 | todoDiv.appendChild(editButton); 87 | //Create trash button 88 | const trashButton = document.createElement("button"); 89 | trashButton.innerHTML = ``; 90 | trashButton.classList.add("trash-btn"); 91 | todoDiv.appendChild(trashButton); 92 | //attach final Todo 93 | todoList.appendChild(todoDiv); 94 | } 95 | 96 | function deleteTodo(e) { 97 | const item = e.target; 98 | const todo = item.parentElement; 99 | const id = todo.getAttribute("key"); 100 | 101 | if (item.classList[0] === "trash-btn") { 102 | // e.target.parentElement.remove(); 103 | todo.classList.add("fall"); 104 | //at the end 105 | removeLocalTodos(id); 106 | todo.addEventListener("transitionend", (e) => { 107 | todo.remove(); 108 | }); 109 | } 110 | if (item.classList[0] === "complete-btn") { 111 | todo.classList.toggle("completed"); 112 | let status = ""; 113 | if (todo.classList.contains("completed")) { 114 | status = "completed"; 115 | } 116 | saveStatus(id, status); 117 | } 118 | //Prevent natural behaviour 119 | e.preventDefault(); 120 | if (todoInput.value === "") { 121 | alert("Fill the box"); 122 | return; 123 | } 124 | //Create todo div 125 | const todoDiv = document.createElement("div"); 126 | todoDiv.classList.add("todo"); 127 | //Create list 128 | const newTodo = document.createElement("li"); 129 | newTodo.innerText = todoInput.value; 130 | //Save to local - do this last 131 | //Save to local 132 | saveLocalTodos(todoInput.value); 133 | // 134 | newTodo.classList.add("todo-item"); 135 | todoDiv.appendChild(newTodo); 136 | todoInput.value = ""; 137 | //Create Completed Button 138 | const completedButton = document.createElement("button"); 139 | completedButton.innerHTML = ``; 140 | completedButton.classList.add("complete-btn"); 141 | todoDiv.appendChild(completedButton); 142 | //Create trash button 143 | const trashButton = document.createElement("button"); 144 | trashButton.innerHTML = ``; 145 | trashButton.classList.add("trash-btn"); 146 | todoDiv.appendChild(trashButton); 147 | //attach final Todo 148 | todoList.appendChild(todoDiv); 149 | } 150 | 151 | function deleteTodo(e) { 152 | const item = e.target; 153 | 154 | if (item.classList[0] === "trash-btn") { 155 | // e.target.parentElement.remove(); 156 | const todo = item.parentElement; 157 | todo.classList.add("fall"); 158 | //at the end 159 | removeLocalTodos(todo); 160 | todo.addEventListener("transitionend", (e) => { 161 | todo.remove(); 162 | }); 163 | } 164 | if (item.classList[0] === "complete-btn") { 165 | const todo = item.parentElement; 166 | todo.classList.toggle("completed"); 167 | const status = "completed"; 168 | const id = todo.getAttribute("key"); 169 | saveStatus(id, status); 170 | } 171 | } 172 | 173 | //save the status of the task -> and persist by saving it to the localstorage 174 | function saveStatus(id, status) { 175 | const todos = getItemFromLocalStorage(); 176 | const intId = Number(id); 177 | const newTodo = todos.find((todo) => todo.id === intId); 178 | const newStatus = 179 | newTodo.status === "incomplete" ? "completed" : "incomplete"; 180 | const todoIndex = todos.indexOf(newTodo); 181 | todos.splice(todoIndex, 1); 182 | newTodo.status = newStatus; 183 | todos.splice(todoIndex, 0, newTodo); 184 | localStorage.setItem("todos", JSON.stringify(todos)); 185 | } 186 | 187 | function filterTodo(e) { 188 | const todos = todoList.childNodes; 189 | todos.forEach((todo) => { 190 | // console.log(e.target.value); 191 | 192 | if ( 193 | e.target.value === "completed" && 194 | todo.classList.contains("completed") 195 | ) { 196 | todo.style.display = "flex"; 197 | } else if ( 198 | e.target.value === "completed" && 199 | !todo.classList.contains("completed") 200 | ) { 201 | todo.style.display = "none"; 202 | } else if ( 203 | e.target.value === "incomplete" && 204 | !todo.classList.contains("completed") 205 | ) { 206 | todo.style.display = "flex"; 207 | } else if ( 208 | e.target.value === "incomplete" && 209 | !todo.classList.contains("incomplete") 210 | ) { 211 | todo.style.display = "none"; 212 | } else { 213 | todo.style.display = "flex"; 214 | } 215 | }); 216 | } 217 | 218 | //save the task to the local storage 219 | function saveLocalTodos(todo) { 220 | let todos = getItemFromLocalStorage(); 221 | todos.push(todo); 222 | localStorage.setItem("todos", JSON.stringify(todos)); 223 | } 224 | 225 | //function to delete a task 226 | function removeLocalTodos(id) { 227 | const intId = Number(id); 228 | let todos = getItemFromLocalStorage(); 229 | const newTodo = todos.filter((todo) => todo.id !== intId); 230 | 231 | localStorage.setItem("todos", JSON.stringify(newTodo)); 232 | } 233 | 234 | //function to toggle display 235 | function editTodo(todo, todoDiv) { 236 | for (let i = 0; i < todoDiv.children.length; i++) { 237 | if (i == 1) { 238 | todoDiv.children[i].classList.remove("hide"); 239 | } else { 240 | todoDiv.children[i].classList.add("hide"); 241 | } 242 | } 243 | const editBtn = document.getElementById(`editBtn-` + `${todo.id}`); 244 | editBtn.addEventListener("click", () => editTask(todo, todoDiv)); 245 | } 246 | 247 | function editTask(todo, todoDiv) { 248 | let todos = getItemFromLocalStorage(); 249 | const editInput = document.getElementById(`edit-` + `${todo.id}`).value; 250 | if (editInput === "") { 251 | //alert("Fill the box"); 252 | openmodal("red", "Fill the box"); 253 | return; 254 | } 255 | todos.forEach((t) => { 256 | if (t.id == todo.id) { 257 | t.task = editInput; 258 | } 259 | }); 260 | localStorage.setItem("todos", JSON.stringify(todos)); 261 | todoDiv.children[0].innerText = editInput; 262 | } 263 | 264 | function isDuplicate(){ 265 | let todos = getItemFromLocalStorage(); 266 | let tasks = []; 267 | 268 | for (var i = 0; i < todos.length; i++){ 269 | tasks.push(todos[i].task); 270 | } 271 | 272 | return tasks.includes(todoInput.value); 273 | } 274 | 275 | function getTodos() { 276 | let todos = getItemFromLocalStorage(); 277 | todos.forEach(function (todo) { 278 | //Create todo div 279 | const todoDiv = document.createElement("div"); 280 | todoDiv.classList.add("todo"); 281 | if (todo.status === "completed") { 282 | todoDiv.classList.add("completed"); 283 | } 284 | todoDiv.setAttribute("key", todo.id); 285 | //Create list 286 | const newTodo = document.createElement("li"); 287 | newTodo.innerText = todo.task; 288 | newTodo.classList.add("todo-item"); 289 | todoDiv.appendChild(newTodo); 290 | //Create Completed Button 291 | const completedButton = document.createElement("button"); 292 | completedButton.innerHTML = ``; 293 | completedButton.classList.add("complete-btn"); 294 | todoDiv.appendChild(completedButton); 295 | //Create trash button 296 | const trashButton = document.createElement("button"); 297 | trashButton.innerHTML = ``; 298 | trashButton.classList.add("trash-btn"); 299 | todoDiv.appendChild(trashButton); 300 | //attach final Todo 301 | todoList.appendChild(todoDiv); 302 | }); 303 | } 304 | 305 | 306 | function saveLocalTodos(todo) { 307 | let todos; 308 | if (localStorage.getItem("todos") === null) { 309 | todos = []; 310 | } else { 311 | todos = JSON.parse(localStorage.getItem("todos")); 312 | } 313 | todos.push(todo); 314 | localStorage.setItem("todos", JSON.stringify(todos)); 315 | } 316 | function removeLocalTodos(todo) { 317 | let todos; 318 | if (localStorage.getItem("todos") === null) { 319 | todos = []; 320 | } else { 321 | todos = JSON.parse(localStorage.getItem("todos")); 322 | } 323 | const todoIndex = todo.children[0].innerText; 324 | todos.splice(todos.indexOf(todoIndex), 1); 325 | localStorage.setItem("todos", JSON.stringify(todos)); 326 | } 327 | 328 | function getTodos() { 329 | let todos; 330 | if (localStorage.getItem("todos") === null) { 331 | todos = []; 332 | } else { 333 | todos = JSON.parse(localStorage.getItem("todos")); 334 | } 335 | todos.forEach(function (todo) { 336 | //Create todo div 337 | const todoDiv = document.createElement("div"); 338 | todoDiv.classList.add("todo"); 339 | if (todo.status == "completed") { 340 | todoDiv.classList.toggle("completed"); 341 | } 342 | //Create list 343 | const newTodo = document.createElement("li"); 344 | newTodo.innerText = todo.task; 345 | newTodo.classList.add("todo-item"); 346 | todoDiv.appendChild(newTodo); 347 | todoInput.value = ""; 348 | //input box 349 | const edit = document.createElement("div"); 350 | edit.innerHTML = 351 | ` `; 365 | edit.classList.add("hide"); 366 | todoDiv.appendChild(edit); 367 | //Create Completed Button 368 | const completedButton = document.createElement("button"); 369 | completedButton.innerHTML = ``; 370 | completedButton.classList.add("complete-btn"); 371 | todoDiv.appendChild(completedButton); 372 | //Create edit button 373 | const editButton = document.createElement("button"); 374 | editButton.innerHTML = ``; 375 | editButton.classList.add("edit-btn"); 376 | editButton.addEventListener("click", () => editTodo(todo, todoDiv)); 377 | todoDiv.appendChild(editButton); 378 | //Create trash button 379 | const trashButton = document.createElement("button"); 380 | trashButton.innerHTML = ``; 381 | trashButton.classList.add("trash-btn"); 382 | todoDiv.setAttribute("key", todo.id); 383 | todoDiv.appendChild(trashButton); 384 | //attach final Todo 385 | todoList.appendChild(todoDiv); 386 | }); 387 | } 388 | 389 | function deleteAll() { 390 | [...document.getElementsByClassName("todo")].map((n) => n && n.remove()); 391 | localStorage.removeItem("todos"); 392 | document.getElementById("confirmation_box").classList.add("hide"); 393 | } 394 | 395 | function openmodal(color, message) { 396 | //pass color as either 'red' (for error), 'blue' for info and 'green' for success 397 | console.log("in"); 398 | document.getElementById("content").classList.add(color); 399 | document.getElementById("modal-text").innerText = message; 400 | document.getElementById("Modal").classList.add("true"); 401 | } 402 | function closemodal() { 403 | document.getElementById("Modal").classList.remove("true"); 404 | } 405 | 406 | var today = new Date(); 407 | var date = today.toString(); 408 | document.getElementById("d1").innerHTML = date; 409 | function show_alert() { 410 | if (localStorage.getItem("todos") === null) { 411 | let html='Please add items first'; 412 | console.log(html); 413 | } 414 | else{ 415 | document.getElementById("confirmation_box").classList.remove("hide"); 416 | } 417 | 418 | } 419 | function goback() { 420 | document.getElementById("confirmation_box").classList.add("hide"); 421 | } -------------------------------------------------------------------------------- /github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |