SECTION 1
Historical Context & Motivation
Long before smartphones and sleek apps, people managed tasks with pen and paper. As computers entered everyday life, programmers realized that a simple to-do list was one of the most practical programs you could build. It touches every fundamental programming skill — storing data, accepting input, making decisions, and repeating actions. The to-do list has become the "Hello, World" of interactive applications because it forces you to combine multiple concepts into a single, working product.
1960s • Command-Line Interfaces Emerge
1995 • JavaScript Is Born
2000s • Arrays Become the Go-To Data Structure
2010s–Now • To-Do Apps as a Learning Standard
So why build a to-do list? Because it answers a fundamental question: How do I write a program that keeps running, responds to user choices, and stores changing data? By the end of this lesson, you will have the skills to answer that question with working JavaScript code.
SECTION 2
Core Principles & Definitions
Building a menu-based to-do list requires four core programming ideas working together. Understanding each one individually makes it much easier to see how they combine into a complete program.
Arrays as Data Storage
Menu-Driven Input
prompt() to collect input and if/else (or switch) to route it.The Program Loop
CRUD Operations
KEY TAKEAWAY
SECTION 3
Visual Explanation — Program Flow
Before writing code, it helps to see how all the pieces fit together. The diagram below shows the flow of a menu-based to-do list from start to finish. Notice how the loop brings the program back to the menu after every action.
The key insight from this diagram is the cyclic nature of the program. Unlike a simple script that runs top-to-bottom and stops, a menu-driven program uses a loop to return to the starting point after every action. This pattern is extremely common — video games, ATMs, and even restaurant kiosks all follow the same basic structure.
SECTION 4
How It Works — The Key JavaScript Methods
JavaScript provides built-in array methods that make adding and removing tasks straightforward. Let's look at the three essential operations our to-do list needs, along with the input/output functions that drive the menu.
Adding a Task — push()
The push() method appends a new element to the end of an array. When the user types a task name, we capture it with prompt() and pass it into tasks.push(newTask). The array grows by one element, and the new task sits at the highest index.
PUSH OPERATION
Before: tasks = ["Study JS"]. After push: the array length increases by 1, and the new item occupies index 1.
Removing a Task — splice()
The splice() method removes (and optionally replaces) elements at a specific index. The syntax is array.splice(startIndex, deleteCount). For our to-do list, tasks.splice(index, 1) removes exactly one task at the given position. All elements after it shift down to fill the gap.
SPLICE OPERATION
Before: tasks = ["Study JS", "Buy groceries"]. After splice(0, 1): the element at index 0 is removed. "Buy groceries" shifts from index 1 to index 0.
Displaying Tasks — Looping with for
To display all tasks, we iterate through the array using a for loop. On each iteration, we print the index number (plus one, so humans see 1-based numbering) and the task string. If the array is empty, we print a friendly message like "No tasks yet!" instead.
Collecting User Input — prompt() and alert()
The prompt() function opens a dialog box and returns whatever the user types as a string. The alert() function displays a message to the user. Together, these two functions handle all communication between the program and the user in a browser environment. Keep in mind that prompt() always returns a string, so if you need a number (like a task index), you must convert it using Number() or parseInt().
SECTION 5
Detailed Breakdown — Code Architecture
Now let's see how all the pieces fit together in actual code. The diagram below shows the complete structure of our to-do list program, highlighting how each section maps to the concepts we've discussed.
Notice the nesting: the if/else if chain lives inside the while loop, and each branch contains its own logic. This layered structure is called nesting, and it is completely normal in menu-driven programs. Indentation is your best friend for keeping track of which block you're inside.
Common Pitfall
prompt() returns a string, not a number. If the user types "2" and you compare it with === to the number 2, the condition will be false. Always compare to string literals like "2", or convert the input using Number(choice).SECTION 6
Worked Example — Building the Complete Program
Let's walk through building the full to-do list program step by step. Each step adds a new capability, and by the end, you'll have a fully functioning interactive application.
Building a Menu-Based To-Do List
- 1
Step 1 — Declare the Array and Flag
Start by creating an empty array to store tasks and a boolean variable to control the loop.let tasks = [];creates an empty array.let running = true;sets a flag that the while loop will check each cycle.let tasks = []; let running = true; - 2
Step 2 — Create the While Loop and Menu Prompt
Wrap all logic inwhile (running) { ... }. Inside the loop, useprompt()to display the menu and capture the user's choice. Use\nto put each option on a new line.while (running) { let choice = prompt("To-Do List Menu:\n1. Add Task\n2. Remove Task\n3. Display Tasks\n4. Quit"); - 3
Step 3 — Implement the Add Action
When the user enters "1", prompt them for a task name and push it onto the array. Then confirm the addition withalert().if (choice === "1") { let task = prompt("Enter a new task:"); tasks.push(task); alert('"' + task + '" has been added!'); } - 4
Step 4 — Implement the Remove Action
When the user enters "2", first display the tasks so they can see the numbers, then ask which number to remove. Convert the input to a number, subtract 1 (because we show 1-based numbering but arrays are 0-based), and validate the index before callingsplice().} else if (choice === "2") { if (tasks.length === 0) { alert("No tasks to remove!"); } else { let list = ""; for (let i = 0; i < tasks.length; i++) { list += (i + 1) + ". " + tasks[i] + "\n"; } let num = Number(prompt("Which task number?\n" + list)); if (num >= 1 && num <= tasks.length) { let removed = tasks.splice(num - 1, 1); alert('"' + removed[0] + '" removed!'); } else { alert("Invalid number."); } } } - 5
Step 5 — Implement Display and Quit
For display, loop through the array and build a string, then show it withalert(). For quit, setrunning = falseso the while loop ends on the next check. Add a finalelseclause for invalid inputs.} else if (choice === "3") { if (tasks.length === 0) { alert("No tasks yet!"); } else { let list = "Your Tasks:\n"; for (let i = 0; i < tasks.length; i++) { list += (i + 1) + ". " + tasks[i] + "\n"; } alert(list); } } else if (choice === "4") { running = false; alert("Goodbye!"); } else { alert("Please enter 1, 2, 3, or 4."); } } // end while
PUTTING IT ALL TOGETHER
<script> tags, and you'll have a working to-do list.SECTION 7
Strengths, Limitations & Alternatives
Our prompt/alert-based to-do list is an excellent learning tool, but it has trade-offs compared to other approaches. Understanding these helps you appreciate what you've built and what comes next.
| Aspect | Strengths | Limitations |
|---|---|---|
| User Interface | Works in any browser with zero setup. No HTML or CSS required. | Prompt/alert dialogs are clunky and block the page. You can't see the list and the menu at the same time. |
| Data Persistence | Simple array storage is easy to understand and debug. | All tasks vanish when you refresh the page. There is no save mechanism. |
| Scalability | Great for small lists. Array operations are fast for dozens of items. | No categories, priorities, or due dates. Hard to extend without restructuring. |
| Error Handling | Basic validation (checking index range) is straightforward to add. | If the user clicks Cancel on a prompt, it returns null, which could cause bugs if not handled. |
Comparison of strengths and limitations of the prompt/alert to-do list approach.
THE BIGGER PICTURE
prompt() with fancy input fields and swap the array for a database. The logic underneath is the same.SECTION 8
Connection to Advanced Concepts
The menu-driven to-do list you've built is a stepping stone to far more powerful applications. The table below compares what you've done here with what you'll encounter as you continue learning JavaScript and web development.
| This Lesson | Next Level |
|---|---|
prompt() and alert() for I/O | HTML forms with <input> elements and DOM manipulation for a real web page UI. |
| Array of strings | Array of objects — each task stores a name, priority, due date, and completion status. |
| Data lost on refresh | localStorage to save tasks in the browser, or a back-end database for permanent storage. |
if/else if chain | Event listeners (addEventListener) that respond to button clicks, replacing the menu loop entirely. |
| Procedural code in one file | Functions, modules, or even frameworks like React that organize code into reusable components. |
How today's concepts evolve into professional-grade tools.
The most important lesson here is that the core logic never changes. Whether you're using prompt boxes or a React interface, your program still needs to store data, accept input, decide what to do with it, and update the display. Mastering this pattern now gives you a head start on everything that follows.
SECTION 9
Practice Problems
Question 1: CONCEPTUAL
while loop instead of just running the code from top to bottom? What would happen without the loop?Show answer
while loop keeps the program alive so the user can perform multiple actions (add several tasks, display them, remove some, etc.). Without the loop, the program would show the menu once, process one choice, and then end. The user would have to reload the page every time they wanted to do something else. The loop creates the repeating cycle that makes the program truly interactive.Question 2: BASIC CALCULATION
tasks = ["Math HW", "Read Ch. 5", "Laundry"]. The user wants to remove "Read Ch. 5". They see it listed as item 2 in the display. Write the exact splice() call that removes it, and state what the array looks like afterward.Show answer
tasks.splice(1, 1). The first argument (1) is the starting index, and the second argument (1) is how many elements to remove. After this call, the array becomes ["Math HW", "Laundry"]. Notice that "Laundry" automatically shifted from index 2 to index 1.Question 3: INTERMEDIATE
Show answer
Number(). Then check: if (num >= 1 && num <= tasks.length). If true, call tasks.splice(num - 1, 1). In the else branch, use alert("Invalid task number. Please try again."). You should also handle the case where the array is empty by checking tasks.length === 0 before prompting, and alerting "No tasks to remove!" if true. This prevents the user from seeing an empty list.Question 4: APPLIED
Show answer
else if (choice === "5") branch. Inside it, the simplest approach is tasks = []; which reassigns the variable to a brand-new empty array. An alternative is tasks.length = 0; which empties the existing array in place. Both work, but tasks = [] is more readable for beginners. You'd also update the menu prompt to include "5. Clear All" and confirm the action with alert("All tasks cleared!"). Don't forget to move the quit option to "6" or adjust accordingly.Question 5: CRITICAL THINKING
Show answer
{ name: "Math HW", done: false }. The add action would become tasks.push({ name: userInput, done: false }). The display action would loop through the array and show each task's name with a checkmark or empty box, for example: "✓ Math HW" vs "☐ Read Ch. 5". You'd check tasks[i].done to decide which symbol to show. A new menu option "Mark as done" would prompt the user for a task number, then set tasks[num - 1].done = true. This shift from an array of strings to an array of objects is a key step toward building more realistic applications.SUMMARY
Lesson Summary
Summary
In this lesson, you built a complete menu-based to-do list using JavaScript. The program stores tasks in an array, uses prompt() and alert() for user interaction, and keeps running through a while loop controlled by a boolean flag. You learned three essential array operations: push() to add tasks, splice() to remove them by index, and a for loop to display them all.
This project demonstrated the CRUD pattern (Create, Read, Delete) that powers virtually every data-driven application. You also practiced input validation by checking array bounds before removing a task, and you handled the string vs. number distinction that trips up many beginners. Moving forward, you can upgrade this project with HTML interfaces, localStorage for persistence, and object-based tasks with completion status — all building on the exact same logic you mastered today.