bold-space-49 / assets /js /script.js
akhaliq's picture
akhaliq HF Staff
Upload folder using huggingface_hub
57361f3 verified
Raw
History Blame Contribute Delete
3.7 kB
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);