const todoForm = document.getElementById('todo-form'); const todoInput = document.getElementById('todo-input'); const todoList = document.getElementById('todo-list'); // Initialize todos from Local Storage, defaulting to an empty array let todos = JSON.parse(localStorage.getItem('todos')) || []; // Function to save todos to Local Storage const saveTodos = () => { localStorage.setItem('todos', JSON.stringify(todos)); }; // Function to render the entire list const renderTodos = () => { todoList.innerHTML = ''; // Clear existing list items if (todos.length === 0) { const emptyMessage = document.createElement('li'); emptyMessage.textContent = "Great job! No tasks currently pending."; emptyMessage.className = "todo-item empty-state"; todoList.appendChild(emptyMessage); return; } todos.forEach((todo, index) => { const listItem = document.createElement('li'); listItem.className = `todo-item ${todo.completed ? 'completed' : ''}`; listItem.setAttribute('role', 'listitem'); listItem.setAttribute('aria-checked', todo.completed); // Task Text (Clickable to toggle completion) const taskText = document.createElement('span'); taskText.className = 'task-text'; taskText.textContent = todo.text; taskText.setAttribute('tabindex', '0'); // Make text focusable for keyboard users taskText.addEventListener('click', () => toggleComplete(index)); taskText.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggleComplete(index); } }); // Actions container const actions = document.createElement('div'); actions.className = 'todo-actions'; // Delete Button const deleteBtn = document.createElement('button'); deleteBtn.textContent = 'Delete'; deleteBtn.className = 'delete-btn'; deleteBtn.setAttribute('aria-label', `Delete task: ${todo.text}`); deleteBtn.addEventListener('click', () => deleteTodo(index)); listItem.appendChild(taskText); actions.appendChild(deleteBtn); listItem.appendChild(actions); todoList.appendChild(listItem); }); }; // 1. Add Functionality const addTodo = (e) => { e.preventDefault(); const taskText = todoInput.value.trim(); if (taskText === "") { // Use standard constraint validation feedback if input is required, // but since we prevent default and trim, a simple focus is enough alert("Please enter a task."); todoInput.focus(); return; } const newTodo = { text: taskText, completed: false, id: Date.now() // Simple unique ID for future scalability if needed }; todos.push(newTodo); saveTodos(); renderTodos(); todoInput.value = ''; // Clear input todoInput.focus(); }; // 2. Delete Functionality const deleteTodo = (index) => { // Optional: add a visual confirmation dialog if (confirm(`Are you sure you want to delete "${todos[index].text}"?`)) { // Remove 1 element starting at the given index todos.splice(index, 1); saveTodos(); renderTodos(); } }; // 3. Mark as Complete Functionality (Toggle) const toggleComplete = (index) => { todos[index].completed = !todos[index].completed; saveTodos(); renderTodos(); // Re-render to apply the completed class and ARIA state }; // Event Listeners document.addEventListener('DOMContentLoaded', renderTodos); todoForm.addEventListener('submit', addTodo);