From f0c455205c7c4f81a3c0de8498cd5f5fe9ecde8a Mon Sep 17 00:00:00 2001 From: Ebrahim_Moqbel Date: Thu, 17 Sep 2026 14:15:09 +0100 Subject: [PATCH 1/4] titled the app and added a delete completed button --- Sprint-3/todo-list/index.html | 73 ++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/Sprint-3/todo-list/index.html b/Sprint-3/todo-list/index.html index 4d12c4654..a59484d86 100644 --- a/Sprint-3/todo-list/index.html +++ b/Sprint-3/todo-list/index.html @@ -1,40 +1,51 @@ - + - - - - ToDo List - - + + + + ToDo List + + - - - -
-

My ToDo List

+ + + +
+

My ToDo List

-
- - -
+
+ + + +
-
    -
+
    - - - -
    - + +
    + From 1ec4254df8a4089cc886398e2aa405a4bff64474 Mon Sep 17 00:00:00 2001 From: Ebrahim_Moqbel Date: Thu, 17 Sep 2026 14:19:06 +0100 Subject: [PATCH 2/4] added a test case for the deleteCompleted function --- Sprint-3/todo-list/todos.test.mjs | 32 +++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/Sprint-3/todo-list/todos.test.mjs b/Sprint-3/todo-list/todos.test.mjs index bae7ae491..a4e11e011 100644 --- a/Sprint-3/todo-list/todos.test.mjs +++ b/Sprint-3/todo-list/todos.test.mjs @@ -13,7 +13,7 @@ function createMockTodos() { { task: "Task 1 description", completed: true }, { task: "Task 2 description", completed: false }, { task: "Task 3 description", completed: true }, - { task: "Task 4 description", completed: false }, + { task: "Task 4 description", completed: false }, ]; } @@ -29,7 +29,6 @@ describe("addTask()", () => { }); test("Should append a new task to the end of a ToDo list", () => { - const todos = createMockTodos(); const lengthBeforeAddition = todos.length; Todos.addTask(todos, theTask.task, theTask.completed); @@ -42,7 +41,6 @@ describe("addTask()", () => { }); describe("deleteTask()", () => { - test("Delete the first task", () => { const todos = createMockTodos(); const todosBeforeDeletion = createMockTodos(); @@ -53,7 +51,7 @@ describe("deleteTask()", () => { expect(todos[0]).toEqual(todosBeforeDeletion[1]); expect(todos[1]).toEqual(todosBeforeDeletion[2]); - expect(todos[2]).toEqual(todosBeforeDeletion[3]); + expect(todos[2]).toEqual(todosBeforeDeletion[3]); }); test("Delete the second task (a middle task)", () => { @@ -66,7 +64,7 @@ describe("deleteTask()", () => { expect(todos[0]).toEqual(todosBeforeDeletion[0]); expect(todos[1]).toEqual(todosBeforeDeletion[2]); - expect(todos[2]).toEqual(todosBeforeDeletion[3]); + expect(todos[2]).toEqual(todosBeforeDeletion[3]); }); test("Delete the last task", () => { @@ -79,7 +77,7 @@ describe("deleteTask()", () => { expect(todos[0]).toEqual(todosBeforeDeletion[0]); expect(todos[1]).toEqual(todosBeforeDeletion[1]); - expect(todos[2]).toEqual(todosBeforeDeletion[2]); + expect(todos[2]).toEqual(todosBeforeDeletion[2]); }); test("Delete a non-existing task", () => { @@ -94,7 +92,6 @@ describe("deleteTask()", () => { }); describe("toggleCompletedOnTask()", () => { - test("Expect the 'completed' property to toggle on an existing task", () => { const todos = createMockTodos(); const taskIndex = 1; @@ -111,13 +108,12 @@ describe("toggleCompletedOnTask()", () => { const todos = createMockTodos(); const todosBeforeToggle = createMockTodos(); Todos.toggleCompletedOnTask(todos, 1); - - expect(todos[0]).toEqual(todosBeforeToggle[0]); + + expect(todos[0]).toEqual(todosBeforeToggle[0]); expect(todos[2]).toEqual(todosBeforeToggle[2]); expect(todos[3]).toEqual(todosBeforeToggle[3]); }); - test("Expect no change when toggling on a non-existing task", () => { const todos = createMockTodos(); const todosBeforeToggle = createMockTodos(); @@ -130,3 +126,19 @@ describe("toggleCompletedOnTask()", () => { }); }); +// write a Jest test that verifies `deleteCompleted()` works correctly. +describe("deleteCompleted()", () => { + test("should delete all the tasks that are marked completed", () => { + let myTodos = [ + { task: "Description of task 1", completed: false }, + { task: "Description of task 2", completed: true }, + { task: "Description of task 2", completed: true }, + ]; + + Todos.deleteCompleted(myTodos); + + expect(myTodos).toEqual([ + { task: "Description of task 1", completed: false }, + ]); + }); +}); From 08149c3de30e9ad345f6c0b6ee44f2f36ac3ac5b Mon Sep 17 00:00:00 2001 From: Ebrahim_Moqbel Date: Thu, 17 Sep 2026 14:20:28 +0100 Subject: [PATCH 3/4] implemented the deleteCompletedTasks function and added the even listener to the UI --- Sprint-3/todo-list/script.mjs | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Sprint-3/todo-list/script.mjs b/Sprint-3/todo-list/script.mjs index ba0b2ceae..e82adf7bf 100644 --- a/Sprint-3/todo-list/script.mjs +++ b/Sprint-3/todo-list/script.mjs @@ -1,4 +1,4 @@ -// Store everything imported from './todos.mjs' module as properties of an object named Todos +// Store everything imported from './todos.mjs' module as properties of an object named Todos import * as Todos from "./todos.mjs"; // To store the todo tasks @@ -8,15 +8,18 @@ const todos = []; window.addEventListener("load", () => { document.getElementById("add-task-btn").addEventListener("click", addNewTodo); + document + .getElementById("delete-completed-btn") + .addEventListener("click", deleteCompletedTasks); + // Populate sample data - Todos.addTask(todos, "Wash the dishes", false); + Todos.addTask(todos, "Wash the dishes", false); Todos.addTask(todos, "Do the shopping", true); render(); }); - -// A callback that reads the task description from an input field and +// A callback that reads the task description from an input field and // append a new task to the todo list. function addNewTodo() { const taskInput = document.getElementById("new-task-input"); @@ -28,6 +31,11 @@ function addNewTodo() { taskInput.value = ""; } +// delete the completed tasks +function deleteCompletedTasks() { + Todos.deleteCompleted(todos); + render(); +} // Note: // - Store the reference to the
      element with id "todo-list" here @@ -45,12 +53,11 @@ function render() { }); } - // Note: // - First child of #todo-item-template is a
    • element. // We will create each ToDo list item as a clone of this node. // - This variable is declared here to be close to the only function that uses it. -const todoListItemTemplate = +const todoListItemTemplate = document.getElementById("todo-item-template").content.firstElementChild; // Create a
    • element for the given todo task @@ -62,15 +69,15 @@ function createListItem(todo, index) { li.classList.add("completed"); } - li.querySelector('.complete-btn').addEventListener("click", () => { + li.querySelector(".complete-btn").addEventListener("click", () => { Todos.toggleCompletedOnTask(todos, index); render(); }); - - li.querySelector('.delete-btn').addEventListener("click", () => { + + li.querySelector(".delete-btn").addEventListener("click", () => { Todos.deleteTask(todos, index); render(); }); return li; -} \ No newline at end of file +} From aedcd82e68e84758826306ca6f8621117b6aacdd Mon Sep 17 00:00:00 2001 From: Ebrahim_Moqbel Date: Thu, 17 Sep 2026 14:21:29 +0100 Subject: [PATCH 4/4] implemented the delete completed function to delete all the tasks that has been completed --- Sprint-3/todo-list/todos.mjs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Sprint-3/todo-list/todos.mjs b/Sprint-3/todo-list/todos.mjs index f17ab6a25..f1103a377 100644 --- a/Sprint-3/todo-list/todos.mjs +++ b/Sprint-3/todo-list/todos.mjs @@ -26,4 +26,12 @@ export function toggleCompletedOnTask(todos, taskIndex) { if (todos[taskIndex]) { todos[taskIndex].completed = !todos[taskIndex].completed; } -} \ No newline at end of file +} +// remove all the completed tasks from the given list +export function deleteCompleted(toDoList) { + for (let i = toDoList.length - 1; i >= 0; i--) { + if (toDoList[i].completed) { + deleteTask(toDoList, i); + } + } +}