-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscript.js
More file actions
489 lines (390 loc) · 13.6 KB
/
script.js
File metadata and controls
489 lines (390 loc) · 13.6 KB
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
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
const taskInput = document.querySelector("#taskInput");
const taskAddBtn = document.querySelector("#addSvg");
const taskContainer = document.querySelector(".task-container");
const taskField = document.querySelector(".task");
const inValidTaskLength = document.querySelector(".task-length-error");
const taskCountText = document.querySelector("#clearAllTaskText");
const filterSelected = document.querySelector("#filter-list");
const clearAllTaskBtn = document.querySelector("#clearAllTaskBtn");
const taskCompletedIcon = "fa-solid fa-circle-check pendingSvg";
const taskUncompletedIcon = "fa-regular fa-circle pendingSvg";
// task counter for stating the number of pending tasks
let taskCount = 3;
// this is message is to shown when there's no tasks inside container
const noTasksMessage = `<div class="completed">
<p>Add a task to plan your day.</p>
</div>`;
// if user clicked on uncheck or check icon, format the task accordingly
const completedTask = (task) => {
const uncheckIcon = task.querySelector("i.pendingSvg");
const editIcon = task.querySelector("i.editSvg");
const taskId = Number.parseInt(task.getAttribute("taskid"));
const isTaskCompleted = uncheckIcon.className === taskUncompletedIcon;
// Update icon, text, and edit display using a conditional operator
uncheckIcon.className = isTaskCompleted ? taskCompletedIcon : taskUncompletedIcon;
editIcon.style.display = isTaskCompleted ? "none" : "block";
task.classList.toggle("checked", isTaskCompleted);
// Update the localStorage data
updateTaskStatus(isTaskCompleted, taskId);
// Update task count
taskCount += isTaskCompleted ? -1 : 1;
updateTaskCount();
};
// edit the task text when clicked on editIcon
const editTaskText = (task) => {
// make the task text editable
const editTaskText = task.querySelector(".taskText");
const previousTaskText = editTaskText.textContent;
editTaskText.setAttribute("contenteditable", "true");
editTaskText.focus();
// Listen for the blur event to detect when the user is done editing
editTaskText.addEventListener("blur", (e) => {
// Make the task text uneditable
editTaskText.setAttribute("contenteditable", "false");
// remove unwanted spaces
editTaskText.textContent = editTaskText.textContent.trim();
// if the newTaskText is less than 5 characters, then update to prevoius task text
if(editTaskText.textContent === '' || editTaskText.textContent.length < 5)
{
editTaskText.textContent = previousTaskText;
}
// update task text in storage
updateTaskTextInStorage(task);
});
}
// delete the task when clicked on deleteIcon
const deleteTask = (task) => {
// delete task from storage
deleteTaskFromStorage(task);
// remove the task from the list
task.remove();
// update task counts
taskCount--;
updateTaskCount();
};
// add new task to the list when clicked on plusIcon or pressed Enter key
const addNewTask = () => {
// reset the error message
inValidTaskLength.style.display = "none";
taskInput.style.border = "1.5px solid gray";
// get input field value and remove unwanted spaces
const newTask = taskInput.value.trim();
if (newTask !== '' && newTask.length >= 5) {
// cloning the structure of tasks
const newTaskField = taskField.cloneNode(true);
// select the task text field
const newTaskText = newTaskField.querySelector(".taskText");
newTaskText.textContent = newTask;
// append the task and empty the inputBox value
taskContainer.append(newTaskField);
taskInput.value = '';
// update task counts
taskCount++;
updateTaskCount();
// add the task data to localStorage
addNewTaskToLocalStorage(newTaskField);
}
else
{
inValidTaskLength.style.display = "block";
taskInput.style.border = "1.5px solid red";
}
// focus the input box for typing
taskInput.focus();
}
// add the task when clicked plusIcon
taskAddBtn.addEventListener("click", addNewTask);
// add the task when pressed Enter key
taskInput.addEventListener("keydown", (e) => {
if(e.key === "Enter")
addNewTask();
});
// check which task is clicked and which button is clicked
taskContainer.addEventListener("click", (e) => {
// select the particular task
const taskElement = e.target.parentElement;
if(taskElement.classList.contains("task"))
{
e.stopPropagation(); // Stop immediate propagation of the click event
// get the data value of clicked element
const clickedElement = e.target;
const data = clickedElement.getAttribute("data");
switch(data)
{
case 'check':
completedTask(taskElement);
break;
case 'task':
// do nothing :)
break;
case 'edit':
editTaskText(taskElement);
break;
case 'delete':
deleteTask(taskElement);
break;
}
}
});
// update the count of pending tasks
const updateTaskCount = () => {
// reset the taskCount
if(taskCount < 0)
taskCount = 0;
// check whether all tasks completed
if(taskCount === 0)
taskCountText.textContent = `Mission Accomplished!`;
else
taskCountText.textContent = `You have ${taskCount} pending tasks`;
// check if noTasksMessage can be added
if(taskCount < 2)
updateNoTaskMessage();
}
// add the message when no tasks are listed
const updateNoTaskMessage = () => {
// if there's nothing in task-container, show the message
if(taskContainer.childElementCount === 0)
taskContainer.innerHTML = noTasksMessage;
else if(taskCount === 1)
{
try {
// if newTask is added remove the noTasksMessage
const removeMessage = taskContainer.querySelector(".completed");
removeMessage.remove();
}
catch(error) {
console.log(`${error}`);
}
}
}
// remove all childs of "taskContainer" class
clearAllTaskBtn.addEventListener("click", () => {
// ask for confirmation
if(confirm("All the tasks will be cleared permanently."))
{
taskContainer.setHTML('');
// update task counts
taskCount = 0;
updateTaskCount();
// focus the input box for typing
taskInput.focus();
// format the localStorage for tasks data
localStorage.setItem("tasks", JSON.stringify([]));
}
});
// get data from local storage
const loadData = () => {
const tasks = JSON.parse(localStorage.getItem("tasks"));
return tasks ? tasks : [];
}
// list the tasks from storage
const listTasksFromStorage = () => {
// get data from local storage
const tasksData = loadData();
taskCount = 0;
// clear the task-container
taskContainer.innerHTML = '';
// list down the tasks
for(const task of tasksData)
{
const newTaskField = taskField.cloneNode(true);
// select the task text field and the text from storage
const newTaskText = newTaskField.querySelector(".taskText");
newTaskText.textContent = task.text;
// if true add the checked class
if(task.completed)
{
newTaskField.classList.add("checked");
const uncheckIcon = newTaskField.querySelector("i.pendingSvg");
uncheckIcon.className = taskCompletedIcon;
}
else
taskCount++;
// add taskid to tasks
newTaskField.setAttribute("taskid", task.id);
// append the task
taskContainer.append(newTaskField);
}
// update the taskCount
updateTaskCount();
}
// list only active tasks
const listActiveTask = () => {
// get data from local storage
const tasksData = loadData();
taskCount = 0;
// clear the task-container
taskContainer.innerHTML = '';
// list down the tasks
for(const task of tasksData)
{
// if the task is incomplete list it
if(!task.completed)
{
const newTaskField = taskField.cloneNode(true);
// select the task text field and the text from storage
const newTaskText = newTaskField.querySelector(".taskText");
newTaskText.textContent = task.text;
// add taskid to tasks
newTaskField.setAttribute("taskid", task.id);
// append the task
taskContainer.append(newTaskField);
taskCount++;
}
}
// update the taskCount
updateTaskCount();
}
// list completed Tasks
const listCompletedTasks = () => {
// get data from local storage
const tasksData = loadData();
// clear the task-container
taskContainer.innerHTML = '';
// list down the tasks
for(const task of tasksData)
{
// if the task is incomplete list it
if(task.completed)
{
const newTaskField = taskField.cloneNode(true);
// select the task text field and the text from storage
const newTaskText = newTaskField.querySelector(".taskText");
newTaskText.textContent = task.text;
// add taskid to tasks
newTaskField.setAttribute("taskid", task.id);
// change the sign to checked
newTaskField.classList.add("checked");
const uncheckIcon = newTaskField.querySelector("i.pendingSvg");
uncheckIcon.className = taskCompletedIcon;
// append the task
taskContainer.append(newTaskField);
}
}
// update the taskCount
taskCount = 0;
updateTaskCount();
}
// add initial tasks to the local storage
const executeOnceOnVisit = () => {
// function to add initial tasks data if visited first time
const addInitialTasks = () => {
// initial 3 tasks data
const initialTasks = [
{
id: 1,
text: "Follow @Alkaison on Twitter",
completed: false
},
{
id: 2,
text: "Complete the first task",
completed: false
},
{
id: 3,
text: "Thank you for visiting here",
completed: false
}
];
localStorage.setItem("tasks", JSON.stringify(initialTasks));
localStorage.setItem("firstVisit", true);
localStorage.setItem("taskId", 3);
}
// check if the user came first time
const firstVisit = localStorage.getItem("firstVisit");
if(!firstVisit)
addInitialTasks();
else
listTasksFromStorage();
}
// execute on first visit
executeOnceOnVisit();
// generate new taskID
const getNewTaskID = () => {
let currentTaskID = localStorage.getItem("taskId");
currentTaskID++;
localStorage.setItem("taskId", currentTaskID);
return currentTaskID;
}
// add new Task data to local storage
const addNewTaskToLocalStorage = (newTaskData) => {
// select task text and add the taskId
const taskText = newTaskData.querySelector(".taskText").textContent;
taskId = getNewTaskID();
newTaskData.setAttribute("taskid", taskId);
// load existing data from localStorage
const tasksData = loadData();
const newData = {
id: taskId,
text: taskText,
completed: false
}
// add the data and update localStorage
tasksData.push(newData);
localStorage.setItem("tasks", JSON.stringify(tasksData));
}
// delete data from localStorage
const deleteTaskFromStorage = (deleteTask) => {
// get data from local storage
const tasksData = loadData();
// get task id from task-element
const ID = deleteTask.getAttribute("taskid");
// filter and remove the task id data from storage
const newTasksData = tasksData.filter((task) => task.id != ID);
// update the localStorage data
localStorage.setItem("tasks", JSON.stringify(newTasksData));
}
// task completed or not
const updateTaskStatus = (status, taskId) => {
// get data from local storage
const tasksData = loadData();
// update status of task
for(const task of tasksData)
{
if(task.id === taskId)
{
task.completed = status;
}
}
// update the data at local storage
localStorage.setItem("tasks", JSON.stringify(tasksData));
}
// update task text into local storage
const updateTaskTextInStorage = (task) => {
// get data from local storage
const tasksData = loadData();
// select task text
const taskText = task.querySelector(".taskText").textContent;
const taskId = Number.parseInt(task.getAttribute("taskid"));
// update text of task
for(const task of tasksData)
{
if(task.id === taskId)
{
task.text = taskText;
}
}
// update the data at local storage
localStorage.setItem("tasks", JSON.stringify(tasksData));
}
// filter the tasks as All, Active, completed
filterSelected.addEventListener("change", (e) => {
// get the selected value
const filterValue = e.target.value;
// execute functions as per value
switch(filterValue)
{
case "all":
listTasksFromStorage();
break;
case "active":
listActiveTask();
break;
case "completed":
listCompletedTasks();
break;
default:
// do nothing :)
}
});