├── 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 |
--------------------------------------------------------------------------------