London | 26-ITP-Jan | Carlos Abreu |Sprint 3 | Todo List#1147
London | 26-ITP-Jan | Carlos Abreu |Sprint 3 | Todo List#1147carlosyabreu wants to merge 14 commits intoCodeYourFuture:mainfrom
Conversation
| // Append a new task to todos[] | ||
| export function addTask(todos, task, completed = false) { | ||
| todos.push({ task, completed }); | ||
| export function addTask(todos, task, completed = false, deadline = null) { |
There was a problem hiding this comment.
How can a user choose a deadline for the task?
There was a problem hiding this comment.
If addTask function had a deadline parameter but the function body doesn't actually use it (it still only creates { task, completed }), there are a few ways a user could choose a deadline:
Modify the function to include deadline in the task object
First, it needs to update the function implementation to actually store the deadline:
// Updated todos.mjs
export function addTask(todos, task, completed = false, deadline = null) {
todos.push({ task, completed, deadline });
}
Then a user could specify a deadline when calling the function:
// Pass deadline as the 4th parameter
const deadline = new Date("2026-12-31");
Todos.addTask(todos, "Finish project", false, deadline);
// Or with different deadlines
Todos.addTask(todos, "Morning meeting", false, new Date("2026-04-07T09:00:00"));
Todos.addTask(todos, "Submit report", false, new Date("2026-04-10"));
There was a problem hiding this comment.
How would an end user call a function when using the web page?
There was a problem hiding this comment.
That's an interesting question.
I would expose this functionality to end users through a web page creating a UI that allows users to interact with these functions.
Here's how I could build a web interface using HTML and CSS:
<title>Todo List App</title> <style> .todo-item { margin: 10px 0; padding: 10px; border: 1px solid #ccc; } .completed { text-decoration: line-through; background-color: #e0ffe0; } button { margin-left: 10px; } </style>Todo List
<!-- Add Task Form -->
<div>
<input type="text" id="taskInput" placeholder="Enter task description">
<input type="datetime-local" id="deadlineInput">
<button id="addBtn">Add Task</button>
</div>
<!-- Todo List Display -->
<div id="todoList"></div>
<script type="module" src="web-app.js"></script>
JavaScript Frontend (web-app.js):
// Import the todos module
import * as Todos from "./todos.mjs";
// Initialize empty todo list
let todos = [];
// DOM elements
const taskInput = document.getElementById('taskInput');
const deadlineInput = document.getElementById('deadlineInput');
const addBtn = document.getElementById('addBtn');
const todoListDiv = document.getElementById('todoList');
// Function to render the todo list to the page
function renderTodos() {
if (!todoListDiv) return;
todoListDiv.innerHTML = '';
todos.forEach((todo, index) => {
const todoDiv = document.createElement('div');
todoDiv.className = 'todo-item';
if (todo.completed) {
todoDiv.classList.add('completed');
}
// Task text with deadline info
let taskHtml = `<strong>${todo.task}</strong>`;
if (todo.deadline) {
const deadlineDate = new Date(todo.deadline);
taskHtml += ` <small>(Due: ${deadlineDate.toLocaleString()})</small>`;
}
// Toggle completed button
const toggleBtn = document.createElement('button');
toggleBtn.textContent = todo.completed ? '✓ Completed' : '○ Incomplete';
toggleBtn.onclick = () => {
Todos.toggleCompletedOnTask(todos, index);
renderTodos(); // Re-render to show changes
};
// Delete button
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete';
deleteBtn.onclick = () => {
Todos.deleteTask(todos, index);
renderTodos(); // Re-render to show changes
};
todoDiv.innerHTML = taskHtml;
todoDiv.appendChild(toggleBtn);
todoDiv.appendChild(deleteBtn);
todoListDiv.appendChild(todoDiv);
});
// Show message if list is empty
if (todos.length === 0) {
todoListDiv.innerHTML = '<p>No tasks yet. Add one above!</p>';
}
}
// Add task function (connects UI to the todos module)
function addTaskFromUI() {
const taskText = taskInput.value.trim();
if (!taskText) {
alert('Please enter a task description');
return;
}
// Get deadline from input
let deadline = null;
if (deadlineInput.value) {
deadline = new Date(deadlineInput.value);
}
// Call the addTask function with deadline
// Note: You need to update todos.mjs to actually use the deadline parameter
Todos.addTask(todos, taskText, false, deadline);
// Clear inputs
taskInput.value = '';
deadlineInput.value = '';
// Re-render the updated list
renderTodos();
}
// Event listeners
addBtn.addEventListener('click', addTaskFromUI);
taskInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
addTaskFromUI();
}
});
// Initial render
renderTodos();
The end users would interact adding a task with deadline:
Type task description in the text box.
Select a date/time from the datetime-local input (this is how users choose a deadline)
Click "Add Task" button or press Enter
Toggling task completion:
Clicking the Completed or Incomplete button next to any task, then the task's appearance will change.
Deleting a task:
Click the Delete button next to any task
There was a problem hiding this comment.
Why didn't you commit this changes? At the moment the code includes parts that are not really functional. They should either be removed or additional code should be added to make it work
There was a problem hiding this comment.
You're absolutely right!
Looking more closely to the code it had a critical issue the todos.mjs function wasn't actually storing the deadline parameter. I refactored the code based on your feedback.
Thank you
| for (let i = todos.length - 1; i >= 0; i--) { | ||
| if (todos[i].completed) { | ||
| todos.splice(i, 1); | ||
| } | ||
| } |
There was a problem hiding this comment.
This works correctly. You can also research build in array functions that allow you to filter elements
There was a problem hiding this comment.
Thank you for pointing that out.
Definitely I'll research that option of building an array functions that allows element filtering to expand my knowledge.
c32bdbd to
e529e16
Compare
|
@Luro91 |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>Todo List App</title> | ||
| <style> | ||
| body { |
There was a problem hiding this comment.
Why did you move the styles to the html file?
| }); | ||
| }); | ||
|
|
||
| describe("deleteCompleted()", () => { |
There was a problem hiding this comment.
All 3 tests fail for me with the error "Todos.deleteCompleted is not a function"
| <div id="todoList"></div> | ||
| </div> | ||
|
|
||
| <script type="module" src="web-app.js"></script> |
There was a problem hiding this comment.
Why did you change the name of the script file?
| <div class="add-task-form"> | ||
| <input type="text" id="taskInput" placeholder="Enter task description (e.g., Finish project report)"> | ||
| <input type="datetime-local" id="deadlineInput"> | ||
| <button id="addBtn">➕ Add Task</button> |
There was a problem hiding this comment.
The add task button does not work for me. Nothing happens when I click it
…ide the same rounded container
|
Sorry @Luro91 for the delay. Going back to this project. Your initial question was: Based on initial change I've done the deadline parameter in todos.mjs exists but is never used by the UI, so users have no way to set it. The previous existing code at that time only allows adding a task description and toggling completion/deletion. |
|
The button for deleting completed task is missing and the tests are failing. It's nice that you also spend time on the extension task with the adding a date and time field. However the core functionality is the important part which should be working as expected. I recommend that you always check the core functionality and make sure it is working as expected first. Please also ask clarifying questions if you are unsure about my comments and let me know how I can communicate more clearly. I did not understand why you added the needed changes as a comment instead of committing them, since you anyway already did the work of writing the code. |
|
@Luro91 As shown by these screenshots: |
… test expectations
Sorry for being not clear. I am referring to the button that will delete all completed tasks. |
|
|
||
| // Command to execute this script: | ||
| // npm test todos.test.mjs | ||
| // node --test todos.test.mjs |
There was a problem hiding this comment.
Afternoon @Luro91
As I was unsure which framework you used to test (todos.test.mjs) I used a few test frameworks to cover most cases.
Based on this scenario, first I run (npm test) and check (package.json) looking for ("jest", "mocha", "vitest", "test": "...").
Later, I tried using Jest but because Jest does not support .mjs out of the box cleanly, I run (npx jest todos.test.mjs).
I even tried Mocha (npx mocha todos.test.mjs) and Vitest (npx vitest run todos.test.mjs).
But I decided to drop these approaches and my best guest the framework you would be using was Node as Node ≥ v18 has built-in test runner. But left (npm test todos.test.mjs) as a comment.
node --test todos.test.mjs
|
|
||
| describe("addTask()", () => { | ||
| test("Add a task to an empty ToDo list", () => { | ||
| it("Add a task to an empty ToDo list", () => { |
|
You wrote below: I didn't implement this functionality because on the requirement there is no mention of that. |
Which requirements are you following? These https://github.com/CodeYourFuture/Module-Data-Groups/tree/main/Sprint-3/todo-list? |





Learners, PR Template
Self checklist
Changelist
Todo list app PR for Sprint 3 of Data Groups module