├── index.html ├── script.js └── style.css /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Todo 9 | 10 | 11 |
12 |

To-do list

13 |
14 | 20 | 21 |
22 | 25 |
26 |
27 |
28 |

0 items total

29 | 30 |
31 |
32 |
33 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | // Retrieve todo from local storage or initialize an empty array 2 | let todo = JSON.parse(localStorage.getItem("todo")) || []; 3 | const todoInput = document.getElementById("todoInput"); 4 | const todoList = document.getElementById("todoList"); 5 | const todoCount = document.getElementById("todoCount"); 6 | const addButton = document.querySelector(".btn"); 7 | const deleteButton = document.getElementById("deleteButton"); 8 | 9 | // Initialize 10 | document.addEventListener("DOMContentLoaded", function () { 11 | addButton.addEventListener("click", addTask); 12 | todoInput.addEventListener("keydown", function (event) { 13 | if (event.key === "Enter") { 14 | event.preventDefault(); // Prevents default Enter key behavior 15 | addTask(); 16 | } 17 | }); 18 | deleteButton.addEventListener("click", deleteAllTasks); 19 | displayTasks(); 20 | }); 21 | 22 | function addTask() { 23 | const newTask = todoInput.value.trim(); 24 | if (newTask !== "") { 25 | todo.push({ text: newTask, disabled: false }); 26 | saveToLocalStorage(); 27 | todoInput.value = ""; 28 | displayTasks(); 29 | } 30 | } 31 | 32 | function displayTasks() { 33 | todoList.innerHTML = ""; 34 | todo.forEach((item, index) => { 35 | const p = document.createElement("p"); 36 | p.innerHTML = ` 37 |
38 | 41 |

${item.text}

44 |
45 | `; 46 | p.querySelector(".todo-checkbox").addEventListener("change", () => 47 | toggleTask(index) 48 | ); 49 | todoList.appendChild(p); 50 | }); 51 | todoCount.textContent = todo.length; 52 | } 53 | 54 | function editTask(index) { 55 | const todoItem = document.getElementById(`todo-${index}`); 56 | const existingText = todo[index].text; 57 | const inputElement = document.createElement("input"); 58 | 59 | inputElement.value = existingText; 60 | todoItem.replaceWith(inputElement); 61 | inputElement.focus(); 62 | 63 | inputElement.addEventListener("blur", function () { 64 | const updatedText = inputElement.value.trim(); 65 | if (updatedText) { 66 | todo[index].text = updatedText; 67 | saveToLocalStorage(); 68 | } 69 | displayTasks(); 70 | }); 71 | } 72 | 73 | function toggleTask(index) { 74 | todo[index].disabled = !todo[index].disabled; 75 | saveToLocalStorage(); 76 | displayTasks(); 77 | } 78 | 79 | function deleteAllTasks() { 80 | todo = []; 81 | saveToLocalStorage(); 82 | displayTasks(); 83 | } 84 | 85 | function saveToLocalStorage() { 86 | localStorage.setItem("todo", JSON.stringify(todo)); 87 | } 88 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --gradient: linear-gradient( 3 | 180deg, 4 | rgba(45, 112, 1253, 0.73) 0%, 5 | #163e92 100% 6 | ); 7 | --dark: #001747; 8 | --grey: #b1bacb; 9 | --grey-border: rgba(210, 210, 210, 0.75); 10 | --grey-light: #eeeeee; 11 | --grey-dark: $405175; 12 | --blue: #2d70fd; 13 | --green: #00d8a7; 14 | --white: #ffffff; 15 | } 16 | 17 | body { 18 | background: var(--gradient); 19 | margin: 0; 20 | height: 100vh; 21 | display: flex; 22 | flex-direction: column; 23 | justify-content: space-evenly; 24 | align-items: center; 25 | } 26 | 27 | .btn { 28 | color: var(--white); 29 | font-size: 1.1rem; 30 | padding: 0.7rem 1.5rem; 31 | border-radius: 0.3rem; 32 | background-color: var(--blue); 33 | border: none; 34 | position: absolute; 35 | right: 0.5rem; 36 | bottom: 0.5rem; 37 | } 38 | 39 | h1, 40 | h2, 41 | h3, 42 | h4, 43 | h5, 44 | h6, 45 | p { 46 | margin: 0; 47 | } 48 | 49 | /* Todo Container */ 50 | 51 | .todo { 52 | display: flex; 53 | flex-direction: column; 54 | justify-content: space-around; 55 | border-radius: 2rem; 56 | background: var(--white); 57 | padding: 3rem; 58 | height: 50%; 59 | width: 60%; 60 | box-shadow: 0 1rem 3rem 1rem rgba(0, 23, 71, 0.15); 61 | max-width: 30rem; 62 | } 63 | 64 | h2 { 65 | text-transform: uppercase; 66 | height: 3rem; 67 | color: var(--dark); 68 | text-align: center; 69 | } 70 | 71 | .input { 72 | position: relative; 73 | display: flex; 74 | } 75 | 76 | .input-field { 77 | width: 100%; 78 | border: 0.06rem solid #d2d2d2bf; 79 | border-radius: 0.5rem; 80 | padding: 1.25rem; 81 | font-size: 1rem; 82 | } 83 | 84 | input[type="text"]::placeholder { 85 | color: var(--grey); 86 | } 87 | 88 | .todo-container { 89 | display: flex; 90 | gap: 1rem; 91 | } 92 | 93 | ul { 94 | padding: 0; 95 | margin: 0; 96 | overflow-y: scroll; 97 | } 98 | 99 | li { 100 | display: flex; 101 | flex-direction: column; 102 | gap: 1.2rem; 103 | padding: 1.3rem; 104 | } 105 | 106 | #todoList p { 107 | display: flex; 108 | gap: 1rem; 109 | color: var(--dark); 110 | align-items: center; 111 | } 112 | 113 | #todoList .disabled { 114 | color: #8f98a8; 115 | } 116 | 117 | .disabled { 118 | display: flex; 119 | text-decoration: line-through; 120 | } 121 | 122 | input[type="checkbox"] { 123 | appearance: none; 124 | -webkit-appearance: none; 125 | -moz-appearance: none; 126 | cursor: pointer; 127 | } 128 | 129 | input[type="checkbox"]::before { 130 | content: "\2713"; 131 | display: inline-block; 132 | width: 2rem; 133 | height: 2rem; 134 | font-size: 1.7rem; 135 | text-align: center; 136 | border: 0.06rem solid var(--grey-border); 137 | border-radius: 50%; 138 | color: transparent; 139 | } 140 | 141 | input[type="checkbox"]:checked::before { 142 | color: var(--white); 143 | background-color: var(--green); 144 | border: 0.06rem solid var(--green); 145 | border-radius: 50%; 146 | } 147 | 148 | .counter { 149 | border: 0.06rem solid var(--grey-light); 150 | } 151 | 152 | .counter-container { 153 | height: 2rem; 154 | display: flex; 155 | justify-content: space-between; 156 | color: var(--grey); 157 | } 158 | 159 | .counter-container p { 160 | align-self: center; 161 | } 162 | 163 | .counter-container button { 164 | border: none; 165 | background-color: transparent; 166 | color: var(--grey); 167 | font-size: 1rem; 168 | } 169 | 170 | .footer { 171 | display: flex; 172 | gap: 1.8rem; 173 | background-color: var(--white); 174 | padding: 1.2rem; 175 | border-radius: 0.5rem; 176 | } 177 | 178 | .made-by, 179 | .author { 180 | font-size: 0.9rem; 181 | } 182 | 183 | .made-by { 184 | color: var(--grey-dark); 185 | } 186 | 187 | .author { 188 | color: var(--blue); 189 | font-weight: bold; 190 | } 191 | 192 | .scroll { 193 | height: 15rem; 194 | scrollbar-width: thin; 195 | } 196 | 197 | .scroll::-webkit-scrollbar { 198 | width: 0.6rem; 199 | } 200 | 201 | .scroll::-webkit-scrollbar-thumb { 202 | background-color: var(--blue); 203 | border-radius: 0.5rem; 204 | } 205 | 206 | .scroll::-webkit-scrollbar-track { 207 | display: none; 208 | } 209 | --------------------------------------------------------------------------------