This is a template for the To-do list item.
It can simplify the creation of list item node in JS script.
-->
+
Task description
+
+
diff --git a/Sprint-3/todo-list/package.json b/Sprint-3/todo-list/package.json
index ce181158a..1e6403d8b 100644
--- a/Sprint-3/todo-list/package.json
+++ b/Sprint-3/todo-list/package.json
@@ -18,6 +18,7 @@
"homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme",
"devDependencies": {
"http-server": "^14.1.1",
- "jest": "^30.0.4"
+ "jest": "^30.0.4",
+ "jsdom": "^29.1.1"
}
}
diff --git a/Sprint-3/todo-list/script.mjs b/Sprint-3/todo-list/script.mjs
index ba0b2ceae..c786daa38 100644
--- a/Sprint-3/todo-list/script.mjs
+++ b/Sprint-3/todo-list/script.mjs
@@ -7,12 +7,16 @@ const todos = [];
// Set up tasks to be performed once on page load
window.addEventListener("load", () => {
document.getElementById("add-task-btn").addEventListener("click", addNewTodo);
+ document.getElementById("clear-completed-btn").addEventListener("click", () => {
+ Todos.deleteCompleted(todos);
+ populateTodoList();
+ });
// Populate sample data
- Todos.addTask(todos, "Wash the dishes", false);
- Todos.addTask(todos, "Do the shopping", true);
+ Todos.addTask(todos, "Wash the dishes","2026-05-01", false);
+ Todos.addTask(todos, "Do the shopping","2026-05-02", true);
- render();
+ populateTodoList();
});
@@ -20,15 +24,45 @@ window.addEventListener("load", () => {
// append a new task to the todo list.
function addNewTodo() {
const taskInput = document.getElementById("new-task-input");
+ const deadlineInput = document.getElementById("task-deadline");
const task = taskInput.value.trim();
+ const deadline = deadlineInput.value;
if (task) {
- Todos.addTask(todos, task, false);
- render();
+ Todos.addTask(todos, task, deadline, false);
+ populateTodoList();
}
taskInput.value = "";
+ deadlineInput.value = "";
+}
+function createListItem(todo, index) {
+ const li = todoListItemTemplate.cloneNode(true);
+
+ // FIX: This line ensures the date string is actually added to the UI
+ const deadlineDisplay = todo.deadline ? ` (Due: ${todo.deadline})` : "";
+ li.querySelector(".description").textContent = todo.task + deadlineDisplay;
+
+ if (todo.completed) {
+ li.classList.add("completed");
+ // Requirement: Checkbox becomes ticked ✅
+ li.querySelector(".complete-btn span").className = "fa-solid fa-square-check";
+ }
+
+ // Action listeners...
+ li.querySelector('.complete-btn').addEventListener("click", () => {
+ Todos.toggleCompletedOnTask(todos, index);
+ populateTodoList();
+ });
+
+ li.querySelector('.delete-btn').addEventListener("click", () => {
+ Todos.deleteTask(todos, index);
+ populateTodoList();
+ });
+
+ return li;
}
+
// Note:
// - Store the reference to the
element with id "todo-list" here
// to avoid querying the DOM repeatedly inside render().
@@ -36,7 +70,7 @@ function addNewTodo() {
const todoListEl = document.getElementById("todo-list");
// Render the whole todo list
-function render() {
+function populateTodoList() {
todoListEl.innerHTML = "";
todos.forEach((todo, index) => {
@@ -54,23 +88,3 @@ const todoListItemTemplate =
document.getElementById("todo-item-template").content.firstElementChild;
// Create a
element for the given todo task
-function createListItem(todo, index) {
- const li = todoListItemTemplate.cloneNode(true); // true => Do a deep copy of the node
-
- li.querySelector(".description").textContent = todo.task;
- if (todo.completed) {
- li.classList.add("completed");
- }
-
- li.querySelector('.complete-btn').addEventListener("click", () => {
- Todos.toggleCompletedOnTask(todos, index);
- render();
- });
-
- li.querySelector('.delete-btn').addEventListener("click", () => {
- Todos.deleteTask(todos, index);
- render();
- });
-
- return li;
-}
\ No newline at end of file
diff --git a/Sprint-3/todo-list/todos.mjs b/Sprint-3/todo-list/todos.mjs
index f17ab6a25..0cafe9367 100644
--- a/Sprint-3/todo-list/todos.mjs
+++ b/Sprint-3/todo-list/todos.mjs
@@ -10,8 +10,8 @@
*/
// Append a new task to todos[]
-export function addTask(todos, task, completed = false) {
- todos.push({ task, completed });
+export function addTask(todos, task, deadline = "", completed = false) {
+ todos.push({ task, deadline, completed });
}
// Delete todos[taskIndex] if it exists
@@ -26,4 +26,9 @@ export function toggleCompletedOnTask(todos, taskIndex) {
if (todos[taskIndex]) {
todos[taskIndex].completed = !todos[taskIndex].completed;
}
-}
\ No newline at end of file
+}
+export function deleteCompleted(todos) {
+ const remaining = todos.filter(t => !t.completed);
+ todos.length = 0;
+ todos.push(...remaining);
+}