Chapter 02 — Activity Guide

Build an Idea Capture Board

Learn DOM creation, drag-and-drop, and CRUD with localStorage — while building a visual thinking tool you'll use every day.

Why This Project?

Chapter 01 taught you how to save and update a single value in the browser. This chapter teaches you how to manage a collection of things — notes — each with its own data, position, and style. That shift from one item to many is one of the most important transitions in frontend development.

The example board is pre-loaded with real show-prep notes for Newscapes Live! — a working demonstration that this tool has a real use case beyond the classroom. Your job is to understand how it works, then make it your own.

Dynamic DOM Creation

Every sticky note is a piece of HTML built in JavaScript and inserted into the page at runtime — not written in the HTML file at all.

Drag-and-Drop API

Mouse events (mousedown, mousemove, mouseup) track where the user grabs a note and move it across the canvas in real time.

Array CRUD

The notes live in a JavaScript array. Create, read, update, and delete operations on that array — then saved to localStorage — are the pattern behind every data-driven app.

localStorage with Objects

Unlike Chapter 01 where you saved a single string, here you save an entire array of objects using JSON.stringify and JSON.parse.

JavaScript DOM Drag & Drop Arrays JSON localStorage GitHub Pages

The AI Angle for This Chapter

In Chapter 01, you described single behaviors to AI. Here, you're describing a system — multiple components (notes, canvas, toolbar) that interact with each other. AI can scaffold the system, but you have to understand how the pieces connect.

When building systems with AI, always start with the data model. If you can describe what a single note looks like as a JavaScript object — its id, color, text, position — you've done the hardest part of the prompt. Everything else is display logic built around that model.

“The data model is the skeleton. AI can build the body once you've drawn the bones.

Before prompting, define your note object in plain English:

If you can answer these four questions, you're ready to prompt.

Before You Build — Design the Data

Write out what a single note object would look like if you were storing it in JavaScript. Don't worry about the code syntax — just describe the fields:

  1. What's the minimum information a note needs to be recreated exactly after a page reload?
  2. How would you tell apart two notes that have the exact same text?
  3. If you wanted to filter notes by category later, what field would you add now?
  4. How does the canvas know to place a note at the same position it was dragged to — even after closing and reopening the browser?
  5. What should happen to the notes array when a user deletes a note? Walk through each step.

These questions define your data model. The code is just a translation of these answers into JavaScript.

Build It

Phase 1

Scaffold the canvas layout

Create chapters/02/index.html. The page needs a fixed nav bar, a toolbar row, and a full-screen canvas area below. This is a different layout than Chapter 01 — the canvas takes all remaining space.

Build a single HTML page with a dark background (#111). At the
top: a fixed nav bar with links to hub and activity guide. Below
it: a toolbar row with an "+ Add Note" button and 5 color swatches.
Below that: a full-height, full-width canvas div (position:relative,
overflow:hidden) where sticky notes will be placed. No frameworks.
Vanilla HTML, CSS, JavaScript only.
Phase 2

Define the note data model and render one note

Before writing any drag logic, get a single note rendering correctly. Define the object shape first, then ask AI to build the addNote(data) function that creates the DOM element and appends it to the canvas.

A note object has these fields: id (string), color (hex string),
text (string), tag (string), x (number), y (number).

Write an addNote(data) function that creates a div positioned
absolutely on the canvas at data.x, data.y. The note has a
colored header bar (using data.color) showing a label and a
delete button, and a body with a textarea for text and a small
editable tag line at the bottom. Clicking the delete button
removes the note from the DOM.
Phase 3

Add drag-and-drop

This is the most technically interesting phase. Drag behavior in vanilla JS uses three mouse events working together. Walk through the logic before prompting: mousedown records the grab offset, mousemove repositions the note, mouseup drops it and saves the new position.

Add drag-and-drop to each note. When the user mousedown on the
note header, record the offset between the mouse position and the
note's top-left corner. On mousemove (on the document, not just
the note), reposition the note to follow the cursor using that
offset. On mouseup, stop dragging and save the note's new x and y
position to the notes array. The note should not be draggable
by clicking on the textarea or the delete button.
Phase 4

CRUD + localStorage persistence

Now wire up the full data layer: the notes array, save/load from localStorage using JSON, and the color picker in the toolbar. This is the moment the board becomes a real tool — it remembers everything.

Maintain a `notes` array. The addNote function should push new
note objects into the array and call save(). The deleteNote
function should filter the note out and call save(). A save()
function stringifies the array to localStorage. A load()
function on page init reads it back, parses it, and calls
addNote for each entry — restoring the board exactly as left.
If localStorage is empty, load a set of 4-6 default example
notes positioned across the canvas.
Phase 5

Polish, brand it, and publish

Review the board as a first-time user would see it. Consider:

  • Is it clear what the color swatches do before you click one?
  • Does the board feel responsive — do notes drag smoothly without lag?
  • Is there a visual cue when the board is empty vs. populated?
  • Are delete actions easy to trigger accidentally? Should there be a confirmation?

Pre-load your own example notes — maybe show-prep items for a project, stream, or brand you're actually working on. Then push to GitHub Pages.

Concepts You Just Used

Find each of these patterns in your finished code. Understanding the location of a pattern in your own code is how you start to build a mental map of how apps are structured.

The gap between Chapter 01 and Chapter 02 is the gap between saving a value and saving a data structure. That gap is the entry point to understanding databases, APIs, and every app that manages more than one thing at a time.

Reflect

  1. What was the hardest part of describing the drag behavior to AI in plain language?
  2. How did defining the note object shape first change the quality of your prompts?
  3. What did AI get wrong the first time you asked for drag-and-drop? How did you correct it?
  4. Compare saving a single string (Ch 01) to saving an array of objects (Ch 02). What's fundamentally different?
  5. What would break in your board if you forgot the JSON.parse on load? Walk through it.

The drag-and-drop bug you fixed in this chapter is the kind of bug you'll recognize immediately in every project going forward. That's how expertise compounds.

Go Further

🔄 Export Board

Add a button that exports all notes as a formatted plain-text or markdown file the user can download or paste anywhere.

🔍 Filter by Color

Add a filter bar that shows only notes of a selected color. Use display:none to hide the rest.

📷 Snapshot

Use the html2canvas library to capture the board as a PNG the user can download or share.

🎪 Custom Labels

Let users rename the color category labels (Idea, Action, Research) and save those names to localStorage.

🔗 Share Link

Encode the notes array as a URL parameter so users can share a board state via a link.

👥 Multi-Board

Add a board selector that lets users maintain multiple named boards in localStorage — like tabs for different projects.

Up Next — Chapter 03

One-Click Invoice Generator

Build a form-driven invoice tool that assembles a formatted PDF from user input — no backend required. You'll learn form validation, template literals, and client-side PDF export.

Start Chapter 03 →