Skip to content

Commit c32bdbd

Browse files
committed
Created webapp.js based on voluntier feedback
1 parent 914c913 commit c32bdbd

1 file changed

Lines changed: 127 additions & 0 deletions

File tree

Sprint-3/todo-list/webapp.js

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Import the todos module
2+
import * as Todos from "./todos.mjs";
3+
4+
// Initialize empty todo list
5+
let todos = [];
6+
7+
// Wait for DOM to be fully loaded before accessing elements
8+
document.addEventListener('DOMContentLoaded', () => {
9+
// DOM elements
10+
const taskInput = document.getElementById('taskInput');
11+
const deadlineInput = document.getElementById('deadlineInput');
12+
const addBtn = document.getElementById('addBtn');
13+
const todoListDiv = document.getElementById('todoList');
14+
15+
// Check if elements exist to prevent errors
16+
if (!taskInput || !deadlineInput || !addBtn || !todoListDiv) {
17+
console.error('Required DOM elements not found');
18+
return;
19+
}
20+
21+
// Function to format deadline for display
22+
function formatDeadline(deadline) {
23+
if (!deadline) return '';
24+
try {
25+
const deadlineDate = new Date(deadline);
26+
// Check if date is valid
27+
if (isNaN(deadlineDate.getTime())) {
28+
return ' (Invalid date)';
29+
}
30+
return ` (Due: ${deadlineDate.toLocaleString()})`;
31+
} catch (e) {
32+
return ' (Invalid date)';
33+
}
34+
}
35+
36+
// Function to render the todo list to the page
37+
function renderTodos() {
38+
if (!todoListDiv) return;
39+
40+
todoListDiv.innerHTML = '';
41+
42+
if (todos.length === 0) {
43+
todoListDiv.innerHTML = '<p>No tasks yet. Add one above!</p>';
44+
return;
45+
}
46+
47+
todos.forEach((todo, index) => {
48+
const todoDiv = document.createElement('div');
49+
todoDiv.className = 'todo-item';
50+
if (todo.completed) {
51+
todoDiv.classList.add('completed');
52+
}
53+
54+
// Task text with deadline info
55+
const deadlineText = formatDeadline(todo.deadline);
56+
const taskText = document.createElement('span');
57+
taskText.innerHTML = `<strong>${escapeHtml(todo.task)}</strong>${deadlineText}`;
58+
59+
// Toggle completed button
60+
const toggleBtn = document.createElement('button');
61+
toggleBtn.textContent = todo.completed ? '✓ Completed' : '○ Incomplete';
62+
toggleBtn.onclick = () => {
63+
Todos.toggleCompletedOnTask(todos, index);
64+
renderTodos(); // Re-render to show changes
65+
};
66+
67+
// Delete button
68+
const deleteBtn = document.createElement('button');
69+
deleteBtn.textContent = 'Delete';
70+
deleteBtn.onclick = () => {
71+
Todos.deleteTask(todos, index);
72+
renderTodos(); // Re-render to show changes
73+
};
74+
75+
todoDiv.appendChild(taskText);
76+
todoDiv.appendChild(toggleBtn);
77+
todoDiv.appendChild(deleteBtn);
78+
todoListDiv.appendChild(todoDiv);
79+
});
80+
}
81+
82+
// Helper function to escape HTML to prevent XSS
83+
function escapeHtml(text) {
84+
const div = document.createElement('div');
85+
div.textContent = text;
86+
return div.innerHTML;
87+
}
88+
89+
// Add task function (connects UI to the todos module)
90+
function addTaskFromUI() {
91+
if (!taskInput || !deadlineInput) return;
92+
93+
const taskText = taskInput.value.trim();
94+
95+
if (!taskText) {
96+
alert('Please enter a task description');
97+
return;
98+
}
99+
100+
// Get deadline from input
101+
let deadline = null;
102+
if (deadlineInput.value) {
103+
deadline = deadlineInput.value;
104+
}
105+
106+
// Call the addTask function with deadline
107+
Todos.addTask(todos, taskText, false, deadline);
108+
109+
// Clear inputs
110+
taskInput.value = '';
111+
deadlineInput.value = '';
112+
113+
// Re-render the updated list
114+
renderTodos();
115+
}
116+
117+
// Event listeners
118+
addBtn.addEventListener('click', addTaskFromUI);
119+
taskInput.addEventListener('keypress', (e) => {
120+
if (e.key === 'Enter') {
121+
addTaskFromUI();
122+
}
123+
});
124+
125+
// Initial render
126+
renderTodos();
127+
});

0 commit comments

Comments
 (0)