Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 109 additions & 40 deletions To do List/To do list.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title> To-Do List </title>
<title>To-Do List</title>

<style>
body {
font-family: 'Poppins', sans-serif;
Expand Down Expand Up @@ -33,7 +34,6 @@
color: #2c3e50;
}

/* ---------- Input Area ---------- */
.input-field {
display: flex;
margin-bottom: 15px;
Expand Down Expand Up @@ -69,7 +69,6 @@
background-color: #0056b3;
}

/* ---------- Control Buttons ---------- */
.control-buttons {
display: flex;
justify-content: space-between;
Expand Down Expand Up @@ -104,7 +103,6 @@
background-color: #c82333;
}

/* ---------- Task List ---------- */
ul {
list-style-type: none;
padding: 0;
Expand Down Expand Up @@ -161,11 +159,13 @@
border: none;
cursor: pointer;
font-size: 18px;
transition: color 0.3s ease;
padding: 5px;
border-radius: 4px;
transition: color 0.3s ease, background-color 0.3s ease;
}

.delete-btn:hover {
color: #b91c1c;
background-color: #f8d7da;
}

.no-tasks {
Expand All @@ -175,59 +175,94 @@
margin-top: 10px;
}

/* ---------- Scrollbar ---------- */
::-webkit-scrollbar {
width: 6px;
}

::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 3px;
}

.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
</style>
</head>

<body>
<div class="todo-container">
<h2> To-Do List 🧠</h2>

<!-- Input Field -->
<div class="input-field">
<input id="taskInput" type="text" placeholder="Enter your task..." />
<button id="addTaskButton">Add</button>
</div>
<h2>To-Do List 🧠</h2>

<form id="taskForm" class="input-field">
<input
id="taskInput"
type="text"
placeholder="Enter your task..."
aria-label="Enter new task"
required
/>
<button type="submit" id="addTaskButton">Add</button>
</form>

<!-- Control Buttons -->
<div class="control-buttons">
<button id="selectAllBtn">Select All</button>
<button id="deleteSelected">Delete Selected</button>
<button id="selectAllBtn" type="button">Select All</button>
<button id="deleteSelected" type="button">Delete Selected</button>
</div>

<!-- Task List -->
<ul id="taskList"></ul>
<ul id="taskList" aria-label="Task list"></ul>
<p id="noTasks" class="no-tasks" style="display:none;">No tasks yet 🎯</p>
</div>

<script>
const addTaskButton = document.getElementById('addTaskButton');
// DOM Elements
const taskForm = document.getElementById('taskForm');
const selectAllBtn = document.getElementById('selectAllBtn');
const deleteSelectedBtn = document.getElementById('deleteSelected');
const taskInput = document.getElementById('taskInput');
const taskList = document.getElementById('taskList');
const noTasksMsg = document.getElementById('noTasks');

// Initialize app
window.addEventListener('DOMContentLoaded', renderTasks);
addTaskButton.addEventListener('click', addTask);
taskInput.addEventListener('keypress', e => { if (e.key === 'Enter') addTask(); });
// Initialize
window.addEventListener('DOMContentLoaded', () => {
renderTasks();
taskInput.focus();
});

taskForm.addEventListener('submit', handleAddTask);
selectAllBtn.addEventListener('click', toggleSelectAll);
deleteSelectedBtn.addEventListener('click', deleteSelectedTasks);

// Helpers
const getTasks = () => JSON.parse(localStorage.getItem('tasks')) || [];
const saveTasks = tasks => localStorage.setItem('tasks', JSON.stringify(tasks));
// Local Storage Helpers
const getTasks = () => {
try {
return JSON.parse(localStorage.getItem('tasks')) || [];
} catch {
return [];
}
};

const saveTasks = (tasks) => {
localStorage.setItem('tasks', JSON.stringify(tasks));
};

function addTask() {
// Add Task
function handleAddTask(event) {
event.preventDefault();
const text = taskInput.value.trim();
if (text === '') return alert('Please enter a task.');
if (text === '') {
alert('Please enter a task.');
taskInput.focus();
return;
}

const newTask = {
id: Date.now(),
Expand All @@ -245,6 +280,7 @@ <h2> To-Do List 🧠</h2>
taskInput.focus();
}

// Render Tasks
function renderTasks() {
const tasks = getTasks();
taskList.innerHTML = '';
Expand All @@ -254,22 +290,34 @@ <h2> To-Do List 🧠</h2>
const li = document.createElement('li');
if (task.completed) li.classList.add('completed');

// Left part (checkbox + text)
const taskLeft = document.createElement('div');
taskLeft.classList.add('task-left');

const checkboxWrapper = document.createElement('div');
const checkboxId = `task-${task.id}`;
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = checkboxId;
checkbox.checked = task.selected;

checkbox.addEventListener('change', () => {
task.selected = checkbox.checked;
task.completed = checkbox.checked;
saveTasks(tasks);
renderTasks();
});

const label = document.createElement('label');
label.htmlFor = checkboxId;
label.classList.add('visually-hidden');
label.textContent = `Select task: ${task.text}`;

checkboxWrapper.appendChild(checkbox);
checkboxWrapper.appendChild(label);

const details = document.createElement('div');
details.classList.add('task-details');

const text = document.createElement('span');
text.classList.add('task-text');
text.textContent = task.text;
Expand All @@ -281,13 +329,14 @@ <h2> To-Do List 🧠</h2>
details.appendChild(text);
details.appendChild(time);

taskLeft.appendChild(checkbox);
taskLeft.appendChild(checkboxWrapper);
taskLeft.appendChild(details);

// Delete button
const deleteBtn = document.createElement('button');
deleteBtn.type = 'button';
deleteBtn.classList.add('delete-btn');
deleteBtn.innerHTML = '🗑️';
deleteBtn.setAttribute('aria-label', `Delete task: ${task.text}`);
deleteBtn.addEventListener('click', () => {
const updated = tasks.filter(t => t.id !== task.id);
saveTasks(updated);
Expand All @@ -298,31 +347,51 @@ <h2> To-Do List 🧠</h2>
li.appendChild(deleteBtn);
taskList.appendChild(li);
});

updateSelectAllButtonText();
}

// Select/Deselect All
function toggleSelectAll() {
const tasks = getTasks();
if (tasks.length === 0) return;

const allSelected = tasks.every(t => t.selected);
tasks.forEach(t => {
t.selected = !allSelected;
t.completed = !allSelected;
});
saveTasks(tasks);
renderTasks();
selectAllBtn.textContent = allSelected ? 'Select All' : 'Deselect All';
}

// Delete Selected
function deleteSelectedTasks() {
let tasks = getTasks();
const selected = tasks.filter(t => t.selected);
if (selected.length === 0) {
const tasks = getTasks();
const selectedTasks = tasks.filter(t => t.selected);

if (selectedTasks.length === 0) {
alert('No tasks selected for deletion.');
return;
}
tasks = tasks.filter(t => !t.selected);
saveTasks(tasks);
renderTasks();

if (confirm(`Are you sure you want to delete ${selectedTasks.length} task(s)?`)) {
const updatedTasks = tasks.filter(t => !t.selected);
saveTasks(updatedTasks);
renderTasks();
}
}

// Update Select All Button Text
function updateSelectAllButtonText() {
const tasks = getTasks();
if (tasks.length === 0) {
selectAllBtn.textContent = 'Select All';
return;
}
const allSelected = tasks.every(t => t.selected);
selectAllBtn.textContent = allSelected ? 'Deselect All' : 'Select All';
}
</script>
</body>
</html>
</html>
Loading
Loading