@@ -21,26 +21,31 @@ completeAllBtn.addEventListener('click', () => {
2121 let savedTasks = JSON . parse ( localStorage . getItem ( 'tasks' ) ) ;
2222 let taskTitles = document . querySelectorAll ( '.todo' ) ;
2323
24- for ( let i = 0 , len = savedTasks . length ; i < len ; i ++ ) {
25- var check = document . getElementsByName ( " completed" ) [ i ] ;
24+ for ( let i = 0 ; i < savedTasks . length ; i ++ ) {
25+ var check = document . getElementsByName ( ' completed' ) [ i ] ;
2626 check . checked = "checked" ;
27- updateTaskInStorage ( taskTitles [ i ] . innerHTML , true ) ;
27+ const taskTitleId = Number ( taskTitles [ i ] . id ) ;
28+ updateTaskInStorage ( taskTitleId , true ) ;
2829 }
2930} ) ;
3031
3132// Create TODO
3233addBtn . addEventListener ( 'click' , ( ) => {
33- newTodo = document . querySelector ( 'textarea' ) . value ;
34- saveTaskToStorage ( newTodo ) ;
35- createTodo ( newTodo ) ;
34+ const newTodoTitle = sanitiseInput ( document . querySelector ( 'textarea' ) . value ) ;
35+
36+ const newTodoTask = generateTask ( newTodoTitle ) ;
37+
38+ saveTaskToStorage ( newTodoTask ) ;
39+ createTodo ( newTodoTask ) ;
3640 hidePage ( ) ;
3741} ) ;
3842
3943document . querySelector ( 'textarea' ) . addEventListener ( 'keypress' , ( key ) => {
40- newTodo = document . querySelector ( 'textarea' ) . value ;
44+ const newTodoTitle = sanitiseInput ( document . querySelector ( 'textarea' ) . value ) ;
45+ const newTodoTask = generateTask ( newTodoTitle ) ;
4146 if ( key . which === 13 ) {
42- saveTaskToStorage ( newTodo ) ;
43- createTodo ( newTodo ) ;
47+ saveTaskToStorage ( newTodoTask ) ;
48+ createTodo ( newTodoTask ) ;
4449 hidePage ( ) ;
4550 }
4651} ) ;
@@ -51,55 +56,87 @@ todoContainer.addEventListener('click', (e) => {
5156
5257 if ( item . classList [ 2 ] == 'delete' ) {
5358 item . parentElement . remove ( ) ;
54- const taskTitle = item . parentElement . children [ 1 ] . innerHTML ;
55- deleteTaskFromStorage ( taskTitle ) ;
59+ const taskId = Number ( item . parentElement . children [ 1 ] . id ) ;
60+ deleteTaskFromStorage ( taskId ) ;
5661 }
5762} ) ;
5863
5964cancelBtn . addEventListener ( 'click' , hidePage ) ;
6065
6166function hidePage ( ) {
6267 document . querySelector ( '.add-task' ) . classList . toggle ( 'hidden' ) ;
68+
6369 if ( document . querySelector ( '.add-task' ) . classList [ 0 ] != 'hidden' ) {
6470 document . querySelector ( 'textarea' ) . focus ( ) ;
6571 }
72+
6673 document . querySelector ( 'textarea' ) . value = '' ;
6774} ;
6875
6976function createTodo ( newTodo ) {
7077 const isChecked = newTodo . isChecked ? 'checked' : '' ;
71- const taskTitle = newTodo . title || newTodo ;
78+
7279 const demoTodo = document . createElement ( 'LI' ) ;
73- const createdElement = `<input type='checkbox' ${ isChecked } name='completed' onchange='updateTaskInStorage("${ taskTitle } ")'> <p class='todo'>${ taskTitle } </p><i class='far fa-trash-alt delete'></i>` ;
80+ const createdElement = `<input type='checkbox' ${ isChecked } name='completed' onchange="updateTaskInStorage(${ newTodo . id } )"> <p class='todo' id=${ newTodo . id } >${ newTodo . title } </p><i class='far fa-trash-alt delete'></i>` ;
81+
7482 demoTodo . innerHTML = createdElement ;
7583 todoContainer . appendChild ( demoTodo ) ;
7684} ;
7785
7886function saveTaskToStorage ( addedTask ) {
7987 let savedTasks = JSON . parse ( localStorage . getItem ( 'tasks' ) ) || [ ] ;
80- const newTask = {
81- id : Date . now ( ) ,
82- title : addedTask ,
83- isChecked : false
84- } ;
85- savedTasks . push ( newTask ) ;
88+
89+ savedTasks . push ( addedTask ) ;
90+
8691 localStorage . setItem ( 'tasks' , JSON . stringify ( savedTasks ) ) ;
8792}
8893
89- function deleteTaskFromStorage ( removedTask ) {
90- console . log ( removedTask ) ;
94+ function deleteTaskFromStorage ( removedTaskId ) {
9195 let savedTasks = JSON . parse ( localStorage . getItem ( 'tasks' ) ) ;
96+
9297 const newTaskList = savedTasks . filter ( taskItem => {
93- return taskItem . title !== removedTask ;
98+ return taskItem . id !== removedTaskId ;
9499 } ) ;
100+
95101 localStorage . setItem ( 'tasks' , JSON . stringify ( newTaskList ) ) ;
96102}
97103
98- function updateTaskInStorage ( completedTask , isCompleted ) {
104+ function updateTaskInStorage ( completedTaskId , isCompleted ) {
99105 let savedTasks = JSON . parse ( localStorage . getItem ( 'tasks' ) ) ;
106+
100107 const taskIndex = savedTasks . findIndex ( taskItem => {
101- return taskItem . title === completedTask ;
108+ return taskItem . id === completedTaskId ;
102109 } ) ;
103- savedTasks [ taskIndex ] . isChecked = isCompleted || ! savedTasks [ taskIndex ] . isChecked ;
110+
111+ if ( savedTasks [ taskIndex ] ) {
112+ savedTasks [ taskIndex ] . isChecked = isCompleted || ! savedTasks [ taskIndex ] ?. isChecked ;
113+ }
104114 localStorage . setItem ( 'tasks' , JSON . stringify ( savedTasks ) ) ;
105115}
116+
117+ function sanitiseInput ( htmlString ) {
118+ const entityMap = {
119+ '&' : '&' ,
120+ '<' : '<' ,
121+ '>' : '>' ,
122+ '"' : '"' ,
123+ "'" : ''' ,
124+ '/' : '/' ,
125+ '`' : '`' ,
126+ '=' : '='
127+ } ;
128+
129+ const string = String ( htmlString ) . replace ( / [ & < > " ' ` = \/ ] / g, function ( s ) {
130+ return entityMap [ s ] ;
131+ } ) ;
132+
133+ return string . trim ( ) ;
134+ }
135+
136+ function generateTask ( taskTitle ) {
137+ return {
138+ id : Date . now ( ) ,
139+ title : taskTitle ,
140+ isChecked : false
141+ } ;
142+ }
0 commit comments