Assignments
Based on Day 30: JavaScript Project - To-Do List Application
Below are some assignments based
on the To-Do List application that was created in the lecture notes. These
assignments will help solidify the concepts of DOM manipulation, event
handling, local storage, arrays, and functions in
JavaScript.
Assignment
1: Add Task Validation
Objective:
Implement validation to ensure that the input field cannot be empty when the
user adds a task.
Steps:
1. Open your
script.js file where the task addition functionality is implemented.
2. Modify the
addTask function to check if the input field is empty.
3. If the
input field is empty, show an alert message prompting the user to enter a task.
Solution:
javascript
Copy code
//
Function to add a new task with validation
function addTask()
{
const taskText = taskInput.value.trim(); // Get the input value and remove any
surrounding whitespaces
if (taskText === "") {
alert("Please enter a task!"); // Show alert if input is empty
return;
// Exit the function if no task is entered
}
// If task is valid, add it to the tasks
array
tasks.push({ text: taskText, completed: false
});
taskInput.value = ""; // Clear the input field after adding the
task
saveTasks(); // Save updated tasks array to local storage
renderTasks(); // Re-render tasks list
}
Explanation:
- The .trim()
method is used to remove any leading or trailing spaces in the task input.
- An if
statement checks if the input is empty. If true, it shows an alert to the
user and exits the function without adding a task.
- If
the input is valid, the task is added to the tasks array, saved to local
storage, and the task list is re-rendered.
Assignment
2: Edit Task Functionality
Objective:
Implement a feature where users can edit an existing task by clicking on it.
Steps:
1. Modify
the renderTasks function to allow users to click on a task to edit it.
2. When a
task is clicked, the task's text should be editable. After editing, the task
should update in the list.
Solution:
javascript
Copy code
//
Function to render tasks with editable text
function renderTasks()
{
taskList.innerHTML = ""; // Clear the current task list before
re-rendering
tasks.forEach((task, index) => {
const
li = document.createElement("li");
li.classList.toggle("completed",
task.completed);
const taskText = document.createElement("span");
taskText.textContent = task.text;
taskText.addEventListener("click",
() => editTask(index, taskText));
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.classList.add("delete-btn");
deleteButton.addEventListener("click",
() => deleteTask(index));
li.appendChild(taskText);
li.appendChild(deleteButton);
taskList.appendChild(li);
});
}
//
Function to edit a task
function editTask(index,
taskTextElement) {
const newTaskText = prompt("Edit your
task:", taskTextElement.textContent);
// Ask user for new task text
if (newTaskText !== null &&
newTaskText.trim() !== "") {
tasks[index].text = newTaskText; // Update the task text in the array
saveTasks(); // Save the updated tasks to local storage
renderTasks(); // Re-render the task list
} else if (newTaskText === "") {
alert("Task cannot be empty!"); // If the user leaves the prompt empty
}
}
Explanation:
- In renderTasks(),
the taskText is made clickable, and when clicked, it triggers the editTask
function.
- The editTask
function uses prompt() to allow users to edit the task text.
- After
editing, the task's text is updated in the tasks array, and the task list
is re-rendered.
Assignment
3: Mark Task as Completed
Objective:
Implement the feature to mark a task as completed by clicking on it. When a
task is marked as completed, it should have a strikethrough effect.
Steps:
1. Modify
the renderTasks function to allow users to toggle the completion state of a
task.
2. When a
task is clicked, toggle its completion status. Update the UI and save the
changes.
Solution:
javascript
Copy code
//
Function to toggle task completion
function toggleComplete(index)
{
tasks[index].completed = !tasks[index].completed; // Toggle the completion state of the task
saveTasks(); // Save the updated tasks to local storage
renderTasks(); // Re-render the task list to reflect changes
}
// Modify
the renderTasks function to apply a strikethrough when completed
function renderTasks()
{
taskList.innerHTML = ""; // Clear the current task list before
re-rendering
tasks.forEach((task, index) => {
const li = document.createElement("li");
li.classList.toggle("completed",
task.completed); // Apply 'completed'
class if the task is completed
const taskText = document.createElement("span");
taskText.textContent = task.text;
taskText.addEventListener("click",
() => toggleComplete(index)); //
Toggle completion when clicked
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.classList.add("delete-btn");
deleteButton.addEventListener("click",
() => deleteTask(index));
li.appendChild(taskText);
li.appendChild(deleteButton);
taskList.appendChild(li);
});
}
Explanation:
- The toggleComplete
function updates the completed property of the task in the array.
- The renderTasks
function checks if a task is completed by applying the completed class,
which strikes through the text in the UI.
Assignment
4: Clear All Tasks Button
Objective: Create a
button that allows users to clear all tasks from the list and local storage.
Steps:
1. Add a
button in the HTML to clear all tasks.
2. Implement
the logic in JavaScript to remove all tasks from the tasks array and local
storage.
Solution:
HTML (Add the "Clear All
Tasks" button):
html
Copy code
<button
id="clear-all">Clear All Tasks</button>
JavaScript (Add the clear
functionality):
javascript
Copy code
// Get
the "Clear All Tasks" button
const
clearAllButton = document.getElementById("clear-all");
//
Function to clear all tasks
function clearAllTasks()
{
tasks = [];
// Empty the tasks array
saveTasks(); // Save the empty tasks array to local
storage
renderTasks(); // Re-render the task list (it will be empty
now)
}
// Event
listener for the "Clear All Tasks" button
clearAllButton.addEventListener("click",
clearAllTasks);
Explanation:
- The clearAllTasks
function clears the entire tasks array, updates the local storage, and
re-renders the task list (which will now be empty).
- An
event listener is added to the "Clear All Tasks" button to
trigger this function when clicked.
Assignment
5: Sort Tasks by Completion
Objective:
Implement a feature to sort tasks by completion status so that completed tasks
always appear at the bottom.
Steps:
1. Modify
the renderTasks function to first display incomplete tasks and then completed
tasks.
2. Use the sort()
method to sort the tasks based on their completion status.
Solution:
javascript
Copy code
//
Function to render tasks with sorting
function renderTasks()
{
taskList.innerHTML = ""; // Clear the current task list before
re-rendering
// Sort tasks: Incomplete tasks first, then
completed tasks
tasks.sort((a, b) => a.completed - b.completed);
tasks.forEach((task, index) => {
const li = document.createElement("li");
li.classList.toggle("completed",
task.completed); // Apply 'completed'
class if the task is completed
const taskText = document.createElement("span");
taskText.textContent = task.text;
taskText.addEventListener("click",
() => toggleComplete(index)); //
Toggle completion when clicked
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.classList.add("delete-btn");
deleteButton.addEventListener("click",
() => deleteTask(index));
li.appendChild(taskText);
li.appendChild(deleteButton);
taskList.appendChild(li);
});
}
Explanation:
- The tasks.sort()
method is used to sort tasks based on their completed status. Incomplete
tasks are shown first, followed by completed ones.
- This
sorting ensures that the task list is always organized with incomplete
tasks at the top.
These assignments help solidify
various concepts related to DOM manipulation, local storage, and event handling
in JavaScript. As you complete these exercises, you'll enhance your
understanding and gain more experience in building interactive web
applications.
4o mini
You said:
more
ChatGPT
said:
ChatGPT
Here are additional assignments with
step-by-step solutions for the JavaScript To-Do List Application
project:
Assignment
6: Persist Tasks in Local Storage on Reload
Objective: Ensure
that tasks persist even after the page is reloaded by retrieving the tasks from
local storage.
Steps:
1. Modify
the JavaScript to check if tasks exist in local storage when the page
loads.
2. If tasks
exist, retrieve and display them on the page.
Solution:
JavaScript:
javascript
Copy code
// Load
tasks from local storage on page load
function loadTasks()
{
const savedTasks = localStorage.getItem("tasks");
if (savedTasks) {
tasks = JSON.parse(savedTasks); // Parse tasks from local storage
} else {
tasks = []; // If no tasks are found, start with an empty
array
}
renderTasks(); // Render the tasks
}
//
Function to save tasks to local storage
function saveTasks()
{
localStorage.setItem("tasks", JSON.stringify(tasks)); // Save tasks array as a JSON string
}
// Call
loadTasks when the page loads
window.addEventListener("load",
loadTasks);
Explanation:
- The loadTasks
function is responsible for checking whether tasks exist in local
storage. If they do, it parses them back into the tasks array.
- The saveTasks
function stores the tasks array in local storage as a JSON string
whenever the tasks are updated.
- The loadTasks
function is called when the page is loaded, ensuring the tasks are loaded
from local storage.
Assignment
7: Task Due Date
Objective: Add a due
date for each task. The user should be able to set a due date for a task
when adding it.
Steps:
1. Add an
input field for the user to enter a due date when creating a task.
2. Display
the due date with the task.
3. Store the
due date in the tasks array and local storage.
Solution:
HTML:
html
Copy code
<input
type="date" id="task-due-date" />
<button
id="add-task-btn">Add Task</button>
JavaScript:
javascript
Copy code
// Get
the due date input field
const
taskDueDateInput = document.getElementById("task-due-date");
// Modify
the addTask function to include due date
function addTask()
{
const taskText = taskInput.value.trim();
const dueDate = taskDueDateInput.value; // Get the due date from input
if (taskText === "") {
alert("Please enter a task!");
return;
}
const newTask = {
text: taskText,
completed: false,
dueDate: dueDate // Add due date to the task object
};
tasks.push(newTask);
taskInput.value = ""; // Clear the task input
taskDueDateInput.value = ""; // Clear the due date input
saveTasks();
renderTasks();
}
// Modify
the renderTasks function to display the due date
function renderTasks()
{
taskList.innerHTML = "";
tasks.forEach((task, index) => {
const li = document.createElement("li");
li.classList.toggle("completed",
task.completed);
const taskText = document.createElement("span");
taskText.textContent = task.text;
const dueDateText = document.createElement("span");
dueDateText.textContent = ` Due: ${task.dueDate}`; // Display due date
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.addEventListener("click",
() => deleteTask(index));
li.appendChild(taskText);
li.appendChild(dueDateText); // Append due date to the task
li.appendChild(deleteButton);
taskList.appendChild(li);
});
}
Explanation:
- The
HTML includes an input field to capture the due date of each task.
- The addTask
function captures the due date from the input and includes it in the task
object.
- The renderTasks
function displays the due date alongside the task text.
Assignment
8: Filter Tasks by Status
Objective: Create a
filter to view tasks based on their completion status (all, completed, or
active).
Steps:
1. Add
filter buttons to the UI (All, Active, Completed).
2. Implement
logic to filter tasks when the user clicks a filter button.
Solution:
HTML:
html
Copy code
<button
id="filter-all">All</button>
<button
id="filter-active">Active</button>
<button
id="filter-completed">Completed</button>
JavaScript:
javascript
Copy code
// Get
filter buttons
const
filterAllButton = document.getElementById("filter-all");
const
filterActiveButton = document.getElementById("filter-active");
const
filterCompletedButton = document.getElementById("filter-completed");
let
filterStatus = "all"; //
Default filter to show all tasks
//
Function to filter tasks based on status
function filterTasks()
{
let filteredTasks = tasks;
if (filterStatus === "active") {
filteredTasks = tasks.filter(task =>
!task.completed);
} else if (filterStatus === "completed")
{
filteredTasks = tasks.filter(task =>
task.completed);
}
taskList.innerHTML = "";
filteredTasks.forEach((task, index) => {
const li = document.createElement("li");
li.classList.toggle("completed",
task.completed);
const taskText = document.createElement("span");
taskText.textContent = task.text;
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.addEventListener("click",
() => deleteTask(index));
li.appendChild(taskText);
li.appendChild(deleteButton);
taskList.appendChild(li);
});
}
// Event
listeners for filter buttons
filterAllButton.addEventListener("click",
() => {
filterStatus = "all";
filterTasks();
});
filterActiveButton.addEventListener("click",
() => {
filterStatus = "active";
filterTasks();
});
filterCompletedButton.addEventListener("click",
() => {
filterStatus = "completed";
filterTasks();
});
Explanation:
- Three
buttons are added for filtering tasks: All, Active, and Completed.
- Based
on the filter selected by the user, the tasks are filtered by their completed
status.
- The filterTasks
function renders the appropriate tasks based on the selected filter.
Assignment
9: Highlight Overdue Tasks
Objective:
Highlight tasks that are overdue (i.e., their due date has passed).
Steps:
1. Modify
the renderTasks function to check if a task is overdue.
2. Highlight
overdue tasks by applying a special class.
Solution:
CSS:
css
Copy code
.overdue
{
color: red;
font-weight: bold;
}
JavaScript:
javascript
Copy code
//
Function to check if a task is overdue
function isOverdue(dueDate)
{
const currentDate = new Date();
const taskDueDate = new Date(dueDate);
return taskDueDate < currentDate;
}
// Modify
the renderTasks function to highlight overdue tasks
function renderTasks()
{
taskList.innerHTML = "";
tasks.forEach((task, index) => {
const li = document.createElement("li");
li.classList.toggle("completed",
task.completed);
const taskText = document.createElement("span");
taskText.textContent = task.text;
const
dueDateText = document.createElement("span");
dueDateText.textContent = ` Due: ${task.dueDate}`;
// Highlight overdue tasks
if (task.dueDate && isOverdue(task.dueDate))
{
taskText.classList.add("overdue");
}
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.addEventListener("click",
() => deleteTask(index));
li.appendChild(taskText);
li.appendChild(dueDateText);
li.appendChild(deleteButton);
taskList.appendChild(li);
});
}
Explanation:
- The isOverdue
function compares the task's due date with the current date to determine
if it is overdue.
- The renderTasks
function applies the .overdue class to the task text if the task is
overdue.
Assignment
10: Confirmation Before Deleting a Task
Objective: Before
deleting a task, ask the user for confirmation.
Steps:
1. Modify
the delete button's event listener to display a confirmation prompt before
deleting a task.
Solution:
javascript
Copy code
// Modify
the deleteTask function to ask for confirmation before deleting
function deleteTask(index)
{
const confirmDelete = confirm("Are you
sure you want to delete this task?");
if (confirmDelete) {
tasks.splice(index, 1); // Remove task from the array
saveTasks(); // Save updated tasks to local storage
renderTasks(); // Re-render the task list
}
}
Explanation:
- The deleteTask
function now asks for confirmation using the confirm() method.
- If
the user confirms, the task is deleted; otherwise, no action is taken.
These additional assignments will
help further enhance your JavaScript skills and provide a deeper understanding
of working with local storage, DOM manipulation, and event
handling.
4o mini
You said:
more
ChatGPT
said:
ChatGPT
Here are more assignments with
step-by-step solutions for your JavaScript To-Do List Application
project:
Assignment
11: Mark All Tasks as Completed
Objective: Add
functionality to mark all tasks as completed with a single button click.
Steps:
1. Add a
button that, when clicked, marks all tasks as completed.
2. Update
the completed status of all tasks in the array.
3. Re-render
the task list and save the updated tasks to local storage.
Solution:
HTML:
html
Copy code
<button
id="mark-all-completed">Mark All as Completed</button>
JavaScript:
javascript
Copy code
// Get
the "Mark All as Completed" button
const
markAllCompletedButton = document.getElementById("mark-all-completed");
//
Function to mark all tasks as completed
function markAllCompleted()
{
tasks.forEach(task => task.completed = true); // Mark each task as completed
saveTasks(); // Save the updated tasks
renderTasks(); // Re-render the task list
}
// Event
listener for the "Mark All as Completed" button
markAllCompletedButton.addEventListener("click",
markAllCompleted);
Explanation:
- The markAllCompleted
function loops through each task in the tasks array and sets the completed
property to true.
- The
tasks are then saved to local storage, and the task list is
re-rendered to reflect the changes.
Assignment
12: Edit Task
Objective: Allow
the user to edit the text of an existing task.
Steps:
1. Add an edit
button next to each task.
2. When the
edit button is clicked, allow the user to change the task's text.
3. Update
the task in the tasks array and save it to local storage.
Solution:
JavaScript:
javascript
Copy code
// Modify
the renderTasks function to include an "Edit" button
function renderTasks()
{
taskList.innerHTML = "";
tasks.forEach((task, index) => {
const li = document.createElement("li");
li.classList.toggle("completed",
task.completed);
const taskText = document.createElement("span");
taskText.textContent = task.text;
//
Create an edit button
const editButton = document.createElement("button");
editButton.textContent = "Edit";
editButton.addEventListener("click",
() => editTask(index));
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.addEventListener("click",
() => deleteTask(index));
li.appendChild(taskText);
li.appendChild(editButton); // Add edit button to the task
li.appendChild(deleteButton);
taskList.appendChild(li);
});
}
//
Function to edit a task
function editTask(index)
{
const newText = prompt("Edit your
task:", tasks[index].text);
if (newText !== null && newText.trim()
!== "") {
tasks[index].text = newText; // Update task text
saveTasks(); // Save the updated tasks
renderTasks(); // Re-render the task list
}
}
Explanation:
- The renderTasks
function now includes an edit button next to each task.
- When
the edit button is clicked, the editTask function is called,
allowing the user to change the task text.
- The
updated task is saved to local storage, and the task list is
re-rendered.
Assignment
13: Display Task Count
Objective: Display
the count of active and completed tasks at the top of the task list.
Steps:
1. Calculate
the number of active and completed tasks.
2. Display
the task counts dynamically at the top of the task list.
Solution:
HTML:
html
Copy code
<div id="task-count">
<span id="active-count"></span>
Active | <span id="completed-count"></span> Completed
</div>
JavaScript:
javascript
Copy code
//
Function to update the task count
function updateTaskCount()
{
const activeCount = tasks.filter(task =>
!task.completed).length;
const completedCount = tasks.filter(task
=> task.completed).length;
document.getElementById("active-count").textContent
= activeCount;
document.getElementById("completed-count").textContent
= completedCount;
}
// Call
updateTaskCount after each render
function renderTasks()
{
taskList.innerHTML = "";
tasks.forEach((task, index) => {
const li = document.createElement("li");
li.classList.toggle("completed",
task.completed);
const taskText = document.createElement("span");
taskText.textContent = task.text;
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.addEventListener("click",
() => deleteTask(index));
li.appendChild(taskText);
li.appendChild(deleteButton);
taskList.appendChild(li);
});
// Update task count after rendering the
tasks
updateTaskCount();
}
Explanation:
- The updateTaskCount
function calculates the number of active and completed tasks using the filter()
method.
- The
task counts are displayed in the task-count div, which is updated every
time the tasks are re-rendered.
Assignment
14: Due Date Sorting
Objective: Sort
tasks by their due date, with the earliest due dates appearing first.
Steps:
1. When
adding a task, allow the user to enter a due date.
2. Sort the
tasks by the due date before rendering them.
Solution:
JavaScript:
javascript
Copy code
//
Function to sort tasks by due date
function sortTasksByDueDate()
{
tasks.sort((task1, task2) => {
const date1 = new Date(task1.dueDate);
const date2 = new Date(task2.dueDate);
return date1 - date2;
});
}
// Modify
the addTask function to include sorting
function addTask()
{
const taskText = taskInput.value.trim();
const dueDate = taskDueDateInput.value;
if (taskText === "") {
alert("Please enter a task!");
return;
}
const newTask = {
text: taskText,
completed: false,
dueDate: dueDate
};
tasks.push(newTask);
taskInput.value = "";
taskDueDateInput.value = "";
sortTasksByDueDate(); // Sort tasks by due date
saveTasks();
renderTasks();
}
Explanation:
- The sortTasksByDueDate
function sorts the tasks based on the dueDate property.
- The
tasks are sorted before they are saved and rendered.
Assignment
15: Task Search Feature
Objective:
Implement a search feature to find tasks by their text.
Steps:
1. Add a
search input field.
2. When the
user types in the search input, filter the tasks based on their text.
Solution:
HTML:
html
Copy code
<input
type="text" id="search-input" placeholder="Search
tasks" />
JavaScript:
javascript
Copy code
// Get
the search input field
const
searchInput = document.getElementById("search-input");
//
Function to filter tasks by search query
function searchTasks()
{
const query = searchInput.value.toLowerCase();
const filteredTasks = tasks.filter(task
=> task.text.toLowerCase().includes(query));
taskList.innerHTML = ""; // Clear the task list
filteredTasks.forEach((task, index) => {
const li = document.createElement("li");
li.classList.toggle("completed",
task.completed);
const taskText = document.createElement("span");
taskText.textContent = task.text;
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.addEventListener("click",
() => deleteTask(index));
li.appendChild(taskText);
li.appendChild(deleteButton);
taskList.appendChild(li);
});
}
// Event
listener for search input
searchInput.addEventListener("input",
searchTasks);
Explanation:
- The searchTasks
function filters the tasks by comparing the text of each task to the
search query.
- The
task list is dynamically updated based on the search input, showing only
tasks that match the query.
Assignment
16: Task Priority
Objective: Allow
users to set a priority for each task (High, Medium, Low).
Steps:
1. Add a
select input to allow users to choose a priority level when creating a task.
2. Display
the priority next to the task and use colors to differentiate the priority
levels.
Solution:
HTML:
html
Copy code
<select
id="task-priority">
<option value="low">Low</option>
<option value="medium">Medium</option>
<option value="high">High</option>
</select>
JavaScript:
javascript
Copy code
// Modify
the addTask function to include priority
function addTask()
{
const taskText = taskInput.value.trim();
const dueDate = taskDueDateInput.value;
const priority = document.getElementById("task-priority").value;
if (taskText === "") {
alert("Please enter a task!");
return;
}
const newTask = {
text: taskText,
completed: false,
dueDate: dueDate,
priority: priority // Include priority
};
tasks.push(newTask);
taskInput.value = "";
taskDueDateInput.value = "";
document.getElementById("task-priority").value
= "low"; // Reset priority
saveTasks();
renderTasks();
}
// Modify
the renderTasks function to display priority
function renderTasks()
{
taskList.innerHTML = "";
tasks.forEach((task, index) => {
const li = document.createElement("li");
li.classList.toggle("completed",
task.completed);
const taskText = document.createElement("span");
taskText.textContent = task.text;
// Create a priority label
const priorityLabel = document.createElement("span");
priorityLabel.textContent = task.priority;
priorityLabel.classList.add(task.priority); // Add class based on priority
const deleteButton = document.createElement("button");
deleteButton.textContent = "Delete";
deleteButton.addEventListener("click",
() => deleteTask(index));
li.appendChild(taskText);
li.appendChild(priorityLabel); // Add priority label
li.appendChild(deleteButton);
taskList.appendChild(li);
});
}
Explanation:
- The addTask
function now includes a priority property.
- The renderTasks
function displays the priority next to each task, and a different color
class is applied based on the priority level.
These assignments cover important
features like task editing, sorting, searching, and setting priorities. Each
solution builds on core JavaScript concepts and helps reinforce your
understanding of how to create a dynamic and interactive task management
application.
