[Go to site: main page, start]

0% found this document useful (0 votes)
30 views34 pages

JavaScript Basics: 28 Coding Exercises

Uploaded by

lakilan1994
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views34 pages

JavaScript Basics: 28 Coding Exercises

Uploaded by

lakilan1994
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

1.

Sum of Two Numbers


Objective: Variables, number conversion, output​
Ask the user for two numbers and display their sum.
const num1 = Number(prompt("Enter first number:"));
const num2 = Number(prompt("Enter second number:"));
alert("The sum is: " + (num1 + num2));

Why it works:​
prompt() returns a string, so Number() converts it. The numbers are added, and the
result is shown with alert().

2. Even or Odd?
Objective: Conditionals, modulo operator
const value = Number(prompt("Enter a number:"));
if (value % 2 === 0) [Link]("Even");
else [Link]("Odd");

Why it works: % 2 gives the remainder—0 means even.

3. Countdown
Objective: Loops, backwards iteration
const n = Number(prompt("Enter a number:"));
for (let i = n; i >= 1; i--) {
[Link](i);
}

Why it works:​
A for loop counts down until it reaches 1.

4. Maximum of an Array
Objective: Arrays, tracking max values
const nums = [3, 17, 9, 42, 5];
let max = nums[0];

for (let i = 1; i < [Link]; i++) {


if (nums[i] > max) max = nums[i];

Get more Apps Script Content at [Link] by Laurence Svekis


}

[Link](max);

5. Greeting Function
Objective: Defining and calling functions
function greet(name) {
[Link]("Hello, " + name);
}

greet("Lars");

6. Change Page Text (DOM)


Objective: DOM selection & modification
const heading = [Link]("title");
[Link] = "Updated via JavaScript!";

7. Button Click Counter


Objective: Events, state management
let count = 0;
[Link]("click", () => {
count++;
[Link] = count;
});

8. Shopping Cart Total


Objective: Objects, arrays, totals
const cart = [
{ name: "Book", price: 12.99 },
{ name: "Headphones", price: 29.99 }
];

Get more Apps Script Content at [Link] by Laurence Svekis


let total = 0;
for (const item of cart) total += [Link];
[Link](total);

9. Convert Celsius to Fahrenheit (map)


Objective: Higher-order functions
const c = [0, 10, 20];
const f = [Link](n => n * 9/5 + 32);
[Link](f);

10. Simple Timer


Objective: setInterval, clearInterval
let secs = 0;
const timer = setInterval(() => {
[Link](secs++);
if (secs > 10) clearInterval(timer);
}, 1000);

💡 Exercises 11–20 — Intermediate


JavaScript & DOM Skills
11. Reverse a String
Objective: Strings, loops
const input = prompt("Enter a word:");
let reversed = "";

for (let i = [Link] - 1; i >= 0; i--) {


reversed += input[i];
}

[Link](reversed);

Get more Apps Script Content at [Link] by Laurence Svekis


12. Word Counter
Objective: Split, trim, whitespace handling
const text = prompt("Enter text:").trim();
const words = text ? [Link](/\s+/) : [];
[Link]([Link]);

13. Number Guessing Game


Objective: Random numbers, loops, conditionals
const secret = [Link]([Link]() * 20) + 1;
let guess;

while (guess !== secret) {


guess = Number(prompt("Guess the number:"));
if (guess < secret) alert("Too low");
else if (guess > secret) alert("Too high");
else alert("Correct!");
}

14. Filter Even Numbers (filter)


Objective: Array filtering
const nums = [1, 4, 7, 10];
const evens = [Link](n => n % 2 === 0);
[Link](evens);

15. Sum with reduce


Objective: Functional patterns
const nums = [5, 10, 15];
const total = [Link]((acc, n) => acc + n, 0);
[Link](total);

16. Unique Values with Set

Get more Apps Script Content at [Link] by Laurence Svekis


Objective: Set, deduplicating arrays
const vals = [1, 2, 2, 4, 4];
const unique = [...new Set(vals)];
[Link](unique);

17. Generate List Items (DOM)


Objective: Create & insert elements
const tasks = ["Learn JS", "Practice DOM"];
const ul = [Link]("taskList");

[Link](t => {
const li = [Link]("li");
[Link] = t;
[Link](li);
});

18. Show / Hide Toggle


Objective: [Link]
[Link]("click", () => {
[Link]("hidden");
});

19. Simple Form Validation


Objective: submit event, preventing submission
[Link]("submit", e => {
[Link]();
if (![Link] || ![Link]) {
[Link] = "Fill in all fields.";
} else {
[Link] = "Success!";
}
});

Get more Apps Script Content at [Link] by Laurence Svekis


20. Persistent Click Counter (localStorage)
Objective: Saving data in the browser
let total = Number([Link]("count")) || 0;
[Link] = total;

[Link]("click", () => {
total++;
[Link] = total;
[Link]("count", total);
});

21) FizzBuzz (Loops + Conditionals) — Console


Goal: Print numbers 1–100. For multiples of 3 print “Fizz”, multiples of 5 print “Buzz”,
both → “FizzBuzz”.
for (let i = 1; i <= 100; i++) {
if (i % 15 === 0) {
[Link]("FizzBuzz");
} else if (i % 3 === 0) {
[Link]("Fizz");
} else if (i % 5 === 0) {
[Link]("Buzz");
} else {
[Link](i);
}
}

Explanation
●​ % checks divisibility via remainder.​

●​ Check 15 first so numbers like 30 don’t get caught by the 3 check early.​

●​ else prints the number when no rule applies.​

Get more Apps Script Content at [Link] by Laurence Svekis


22) Palindrome Checker (Strings) — Console
Goal: Check if a word reads the same forward and backward.
function isPalindrome(word) {
const cleaned = [Link]().replace(/[^a-z0-9]/g, "");
const reversed = [Link]("").reverse().join("");
return cleaned === reversed;
}

[Link](isPalindrome("Racecar")); // true
[Link](isPalindrome("hello")); // false
[Link](isPalindrome("A man, a plan!"));// true-ish based on
cleaning

Explanation
●​ toLowerCase() makes comparison case-insensitive.​

●​ replace(/[^a-z0-9]/g, "") removes non-alphanumeric characters.​

●​ split("") → array of chars, reverse(), then join("") back to a string.​

23) Factorial (Loops) — Console


Goal: Compute n! (e.g., 5! = 120).
function factorial(n) {
if (![Link](n) || n < 0) return null;

let result = 1;
for (let i = 2; i <= n; i++) {
result *= i;
}
return result;
}

[Link](factorial(5)); // 120
[Link](factorial(0)); // 1
[Link](factorial(-2)); // null

Get more Apps Script Content at [Link] by Laurence Svekis


Explanation
●​ Validates input (must be a non-negative integer).​

●​ Starts at 1 and multiplies by every number up to n.​

●​ 0! is defined as 1, which this code naturally produces.​

24) Fibonacci Sequence (Array) — Console


Goal: Generate the first n Fibonacci numbers.
function fibonacci(n) {
if (![Link](n) || n <= 0) return [];
if (n === 1) return [0];

const seq = [0, 1];


while ([Link] < n) {
const next = seq[[Link] - 1] + seq[[Link] - 2];
[Link](next);
}
return seq;
}

[Link](fibonacci(10));

Explanation
●​ Starts with [0, 1].​

●​ Each next value is the sum of the last two.​

●​ Uses while until the array reaches length n.​

25) Count Character Frequency (Objects) — Console


Goal: Count how many times each character appears in a string.
function charFrequency(text) {
const freq = {};

Get more Apps Script Content at [Link] by Laurence Svekis


for (const ch of text) {
freq[ch] = (freq[ch] || 0) + 1;
}
return freq;
}

[Link](charFrequency("banana"));

Explanation
●​ freq is an object where keys are characters.​

●​ freq[ch] || 0 defaults to 0 if the key doesn’t exist.​

●​ Adds 1 for each occurrence.​

26) Sort Numbers Without .sort() (Algorithm) —


Console
Goal: Sort an array ascending using Bubble Sort.
function bubbleSort(arr) {
const a = [...arr]; // copy so we don’t mutate input
for (let i = 0; i < [Link] - 1; i++) {
for (let j = 0; j < [Link] - 1 - i; j++) {
if (a[j] > a[j + 1]) {
[a[j], a[j + 1]] = [a[j + 1], a[j]]; // swap
}
}
}
return a;
}

[Link](bubbleSort([5, 3, 8, 1, 2]));

Explanation
●​ Outer loop controls passes.​

Get more Apps Script Content at [Link] by Laurence Svekis


●​ Inner loop compares adjacent pairs and swaps if out of order.​

●​ - i optimization: after each pass, the largest value is already at the end.​

27) Remove Duplicates Manually (No Set) — Console


Goal: Return unique values in order.
function uniqueValues(arr) {
const result = [];
for (const item of arr) {
if (![Link](item)) {
[Link](item);
}
}
return result;
}

[Link](uniqueValues([1, 2, 2, 3, 1, 4]));

Explanation
●​ Uses [Link](item) to check if already added.​

●​ Preserves first-seen order.​

●​ Not the fastest for huge arrays, but perfect for learning.​

28) Flatten One Level of Nested Arrays — Console


Goal: Turn [1,[2,3],[4],5] into [1,2,3,4,5].
function flattenOneLevel(arr) {
const out = [];
for (const item of arr) {
if ([Link](item)) [Link](...item);
else [Link](item);
}
return out;

Get more Apps Script Content at [Link] by Laurence Svekis


}

[Link](flattenOneLevel([1, [2, 3], [4], 5]));

Explanation
●​ [Link] detects nested arrays.​

●​ ...item spreads array elements into out.​

●​ Only flattens one level (by design).​

29) Group Items by Property — Console


Goal: Group objects by category.
function groupBy(arr, key) {
const grouped = {};
for (const obj of arr) {
const k = obj[key];
if (!grouped[k]) grouped[k] = [];
grouped[k].push(obj);
}
return grouped;
}

const products = [
{ name: "Apple", category: "Fruit" },
{ name: "Carrot", category: "Veg" },
{ name: "Banana", category: "Fruit" },
];

[Link](groupBy(products, "category"));

Explanation
●​ Uses an object of arrays.​

●​ Each unique key (like "Fruit") becomes a bucket.​

Get more Apps Script Content at [Link] by Laurence Svekis


●​ Push each item into the correct bucket.​

30) Safe JSON Parse (Try/Catch) — Console


Goal: Parse JSON without crashing your program.
function safeJsonParse(str) {
try {
return { ok: true, data: [Link](str) };
} catch (err) {
return { ok: false, error: [Link] };
}
}

[Link](safeJsonParse('{"a":1}'));
[Link](safeJsonParse("{bad json}"));

Explanation
●​ [Link] throws if the string isn’t valid JSON.​

●​ try/catch prevents the error from stopping execution.​

●​ Returns a consistent result object.​

31) Debounce (Functions + Timers) — Console/Browser


Goal: Only run a function after the user “stops” triggering it for X ms.
function debounce(fn, delayMs) {
let timerId;

return function (...args) {


clearTimeout(timerId);
timerId = setTimeout(() => fn(...args), delayMs);
};
}

// Example:

Get more Apps Script Content at [Link] by Laurence Svekis


const debouncedLog = debounce((msg) => [Link](msg), 500);
debouncedLog("A");
debouncedLog("B");
debouncedLog("C"); // only "C" logs after 500ms

Explanation
●​ A closure keeps timerId between calls.​

●​ Each call clears the previous timeout and sets a new one.​

●​ Only the final call survives long enough to run.​

32) Throttle (Functions + Timers) — Console/Browser


Goal: Run a function at most once every X ms.
function throttle(fn, intervalMs) {
let lastTime = 0;

return function (...args) {


const now = [Link]();
if (now - lastTime >= intervalMs) {
lastTime = now;
fn(...args);
}
};
}

// Example:
const throttledLog = throttle(() => [Link]("tick"), 1000);
setInterval(() => throttledLog(), 100); // logs about once per
second

Explanation
●​ lastTime tracks the last allowed execution time.​

●​ If not enough time passed, calls are ignored.​

Get more Apps Script Content at [Link] by Laurence Svekis


●​ Useful for scroll/resize events.​

33) Build a URL Query String — Console


Goal: Convert an object to ?key=value&....
function toQueryString(params) {
const parts = [];
for (const key in params) {
const value = encodeURIComponent(params[key]);
[Link](`${encodeURIComponent(key)}=${value}`);
}
return [Link] ? "?" + [Link]("&") : "";
}

[Link](toQueryString({ q: "js exercises", page: 2 }));

Explanation
●​ encodeURIComponent makes values safe for URLs.​

●​ parts becomes an array of key=value pairs.​

●​ Joins them with & and adds a leading ?.​

34) Deep Clone Simple JSON Objects — Console


Goal: Copy nested JSON-safe objects without shared references.
function deepCloneJson(obj) {
return [Link]([Link](obj));
}

const original = { a: 1, b: { c: 2 } };
const clone = deepCloneJson(original);
clone.b.c = 999;

[Link](original.b.c); // 2
[Link](clone.b.c); // 999

Get more Apps Script Content at [Link] by Laurence Svekis


Explanation
●​ [Link] converts to a string.​

●​ [Link] creates a brand new structure.​

●​ Limitation: won’t preserve functions, Dates, Maps, etc. (fine for learning + JSON
data).​

35) Validate Email (Basic Regex) — Console


Goal: Basic email format check.
function isEmail(str) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str);
}

[Link](isEmail("test@[Link]")); // true
[Link](isEmail("bad@email")); // false

Explanation
●​ This regex checks:​

○​ something before @​

○​ something after @​

○​ at least one dot section​

●​ Not “perfect” for every valid email ever, but solid for beginner validation.​

Exercises 36–50 (DOM + Practical Web


Skills)
For these, use this HTML template once, then swap scripts per exercise:
<!doctype html>
<html>

Get more Apps Script Content at [Link] by Laurence Svekis


<head>
<meta charset="utf-8" />
<title>JS Exercises</title>
<style>
body { font-family: Arial, sans-serif; padding: 16px; }
.hidden { display: none; }
.error { color: #b00020; }
.ok { color: #0a7a0a; }
.box { padding: 12px; border: 1px solid #ddd;
border-radius: 8px; margin: 12px 0; }
</style>
</head>
<body>
<div id="app"></div>
<script src="[Link]"></script>
</body>
</html>

36) Live Character Counter — DOM


Goal: Count characters as the user types.
[Link]
[Link]("app").innerHTML = `
<div class="box">
<h2>Live Character Counter</h2>
<textarea id="txt" rows="4" cols="40" placeholder="Type
here..."></textarea>
<p>Characters: <span id="count">0</span></p>
</div>
`;

const txt = [Link]("txt");


const count = [Link]("count");

[Link]("input", () => {
[Link] = [Link];

Get more Apps Script Content at [Link] by Laurence Svekis


});

Explanation
●​ input event fires on every change (typing, paste, delete).​

●​ [Link] gives current character count.​

●​ Updates the DOM span instantly.​

37) To-Do List Add Items — DOM


Goal: Add items to a list from an input field.
[Link]("app").innerHTML = `
<div class="box">
<h2>To-Do List</h2>
<input id="taskInput" placeholder="New task" />
<button id="addBtn">Add</button>
<ul id="list"></ul>
</div>
`;

const input = [Link]("taskInput");


const addBtn = [Link]("addBtn");
const list = [Link]("list");

[Link]("click", () => {
const text = [Link]();
if (!text) return;

const li = [Link]("li");
[Link] = text;
[Link](li);

[Link] = "";
[Link]();
});

Get more Apps Script Content at [Link] by Laurence Svekis


Explanation
●​ trim() prevents empty/space-only tasks.​

●​ createElement("li") creates new list items.​

●​ Resetting and focusing improves user experience.​

38) To-Do Remove Items (Event Delegation) — DOM


Goal: Click a list item to remove it.
[Link]("app").innerHTML = `
<div class="box">
<h2>Click-to-Remove List</h2>
<input id="taskInput" placeholder="New item" />
<button id="addBtn">Add</button>
<ul id="list"></ul>
<p><em>Tip: click an item to remove it.</em></p>
</div>
`;

const input = [Link]("taskInput");


const addBtn = [Link]("addBtn");
const list = [Link]("list");

[Link]("click", () => {
const text = [Link]();
if (!text) return;

const li = [Link]("li");
[Link] = text;
[Link](li);

[Link] = "";
});

Get more Apps Script Content at [Link] by Laurence Svekis


// Event delegation: one listener on the parent <ul>
[Link]("click", (e) => {
if ([Link] === "LI") {
[Link]();
}
});

Explanation
●​ Instead of adding a click handler to every <li>, we add one to the <ul>.​

●​ [Link] is the clicked element.​

●​ .remove() deletes it from the DOM.​

39) Tabs UI (Switch Sections) — DOM


Goal: Click buttons to show different content panels.
[Link]("app").innerHTML = `
<div class="box">
<h2>Tabs</h2>
<button data-tab="one">Tab 1</button>
<button data-tab="two">Tab 2</button>
<button data-tab="three">Tab 3</button>

<div id="one" class="panel">Content for Tab 1</div>


<div id="two" class="panel hidden">Content for Tab 2</div>
<div id="three" class="panel hidden">Content for Tab 3</div>
</div>
`;

function showTab(id) {
[Link](".panel").forEach(p =>
[Link]("hidden"));
[Link](id).[Link]("hidden");
}

Get more Apps Script Content at [Link] by Laurence Svekis


[Link]("button[data-tab]").forEach(btn => {
[Link]("click", () => showTab([Link]));
});

Explanation
●​ Panels share class panel; we hide all, then reveal the chosen one.​

●​ [Link] reads data-tab="...".​

●​ This pattern scales to many tabs.​

40) Modal Popup (Open/Close) — DOM


Goal: Open a modal overlay and close it.
[Link]("app").innerHTML = `
<div class="box">
<h2>Modal</h2>
<button id="open">Open Modal</button>
</div>

<div id="overlay" class="hidden" style="


position:fixed; inset:0; background:rgba(0,0,0,.5);
display:flex; align-items:center; justify-content:center;">
<div style="background:#fff; padding:16px;
border-radius:10px; width:300px;">
<h3>Modal Title</h3>
<p>This is a simple modal.</p>
<button id="close">Close</button>
</div>
</div>
`;

const overlay = [Link]("overlay");

[Link]("open").addEventListener("click", () =>
{

Get more Apps Script Content at [Link] by Laurence Svekis


[Link]("hidden");
});

[Link]("close").addEventListener("click", () =>
{
[Link]("hidden");
});

// Close if user clicks outside the modal box


[Link]("click", (e) => {
if ([Link] === overlay) [Link]("hidden");
});

Explanation
●​ Overlay covers the screen and centers the modal content.​

●​ Clicking the overlay (not the inner box) closes it.​

●​ Uses .hidden to control visibility.​

41) Form Validation with Inline Errors — DOM


Goal: Validate name + email and show errors.
[Link]("app").innerHTML = `
<div class="box">
<h2>Signup</h2>
<form id="form">
<div>
<label>Name</label><br/>
<input id="name" />
<div id="nameErr" class="error"></div>
</div>
<div style="margin-top:8px;">
<label>Email</label><br/>
<input id="email" />
<div id="emailErr" class="error"></div>

Get more Apps Script Content at [Link] by Laurence Svekis


</div>
<button style="margin-top:10px;">Submit</button>
<p id="status"></p>
</form>
</div>
`;

const form = [Link]("form");


const nameEl = [Link]("name");
const emailEl = [Link]("email");
const nameErr = [Link]("nameErr");
const emailErr = [Link]("emailErr");
const status = [Link]("status");

function isEmail(str) {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(str);
}

[Link]("submit", (e) => {


[Link]();

[Link] = "";
[Link] = "";
[Link] = "";

const name = [Link]();


const email = [Link]();

let ok = true;

if ([Link] < 2) {
[Link] = "Name must be at least 2 characters.";
ok = false;
}
if (!isEmail(email)) {

Get more Apps Script Content at [Link] by Laurence Svekis


[Link] = "Please enter a valid email
address.";
ok = false;
}

[Link] = ok ? " ✅ Submitted (demo)!" : "❌ Fix


errors above.";
[Link] = ok ? "ok" : "error";
});

Explanation
●​ Prevents page reload via preventDefault().​

●​ Clears old errors each submit.​

●​ Uses ok flag to track validation results.​

●​ Provides immediate, targeted feedback.​

42) Theme Toggle (Dark/Light) — DOM


Goal: Switch page theme with a button.
[Link]("app").innerHTML = `
<div class="box">
<h2>Theme Toggle</h2>
<button id="toggle">Toggle Theme</button>
<p>Click the button to switch styles.</p>
</div>
`;

let dark = false;

[Link]("toggle").addEventListener("click", ()
=> {
dark = !dark;

Get more Apps Script Content at [Link] by Laurence Svekis


[Link] = dark ? "#111" : "#fff";
[Link] = dark ? "#fff" : "#111";
});

Explanation
●​ Tracks state with dark.​

●​ Updates inline styles on the body.​

●​ Simple pattern that can later be upgraded to CSS classes.​

43) Random Quote Generator (Array + DOM) — DOM


Goal: Show a random quote each click.
[Link]("app").innerHTML = `
<div class="box">
<h2>Random Quote</h2>
<button id="new">New Quote</button>
<p id="quote" style="margin-top:10px;"></p>
</div>
`;

const quotes = [
"Small steps, daily.",
"Make it work, then make it better.",
"Practice beats theory.",
"Debugging is learning in disguise."
];

const quoteEl = [Link]("quote");

function showRandomQuote() {
const idx = [Link]([Link]() * [Link]);
[Link] = quotes[idx];
}

Get more Apps Script Content at [Link] by Laurence Svekis


[Link]("new").addEventListener("click",
showRandomQuote);
showRandomQuote();

Explanation
●​ Random index: [Link]([Link]() * length).​

●​ Updates quote text.​

●​ Calls once at start so the page isn’t empty.​

44) Simple Stopwatch (Start/Stop/Reset) — DOM


Goal: Build a stopwatch with interval control.
[Link]("app").innerHTML = `
<div class="box">
<h2>Stopwatch</h2>
<h3 id="time">0.0</h3>
<button id="start">Start</button>
<button id="stop">Stop</button>
<button id="reset">Reset</button>
</div>
`;

const timeEl = [Link]("time");


let t = 0; // tenths of a second
let timerId = null;

function render() {
[Link] = (t / 10).toFixed(1);
}

[Link]("start").addEventListener("click", () =>
{
if (timerId !== null) return; // already running
timerId = setInterval(() => {

Get more Apps Script Content at [Link] by Laurence Svekis


t++;
render();
}, 100);
});

[Link]("stop").addEventListener("click", () =>
{
clearInterval(timerId);
timerId = null;
});

[Link]("reset").addEventListener("click", () =>
{
t = 0;
render();
});
render();

Explanation
●​ Uses tenths of seconds (100ms) for a smoother display.​

●​ Stores interval id in timerId so it can be stopped.​

●​ Prevents multiple intervals with the if (timerId !== null) guard.​

45) Countdown Timer (Input + Interval) — DOM


Goal: User enters seconds; countdown to 0.
[Link]("app").innerHTML = `
<div class="box">
<h2>Countdown</h2>
<input id="secs" type="number" min="1" placeholder="Seconds"
/>
<button id="go">Start</button>
<p id="out"></p>
</div>

Get more Apps Script Content at [Link] by Laurence Svekis


`;

const secsInput = [Link]("secs");


const out = [Link]("out");
let id = null;

[Link]("go").addEventListener("click", () => {
let remaining = Number([Link]);

if (![Link](remaining) || remaining <= 0) {


[Link] = "Enter a positive number.";
return;
}

clearInterval(id);
[Link] = `Remaining: ${remaining}s`;

id = setInterval(() => {
remaining--;
[Link] = `Remaining: ${remaining}s`;

if (remaining <= 0) {
clearInterval(id);
[Link] = " ✅ Done!";
}
}, 1000);
});

Explanation
●​ Validates input and converts to number.​

●​ Clears any existing countdown to avoid multiple timers.​

●​ Decrements once per second until 0, then stops interval.​

Get more Apps Script Content at [Link] by Laurence Svekis


46) LocalStorage Notes App — DOM + Storage
Goal: Save notes in the browser.
[Link]("app").innerHTML = `
<div class="box">
<h2>Notes (Saved in Browser)</h2>
<textarea id="note" rows="5" cols="40" placeholder="Write
notes..."></textarea>
<div>
<button id="save">Save</button>
<button id="clear">Clear</button>
</div>
<p id="msg"></p>
</div>
`;

const note = [Link]("note");


const msg = [Link]("msg");

[Link] = [Link]("notes") || "";

[Link]("save").addEventListener("click", () =>
{
[Link]("notes", [Link]);
[Link] = " ✅ Saved!";
[Link] = "ok";
});

[Link]("clear").addEventListener("click", () =>
{
[Link] = "";
[Link]("notes");
[Link] = " 🗑️ Cleared!";
[Link] = "";
});

Get more Apps Script Content at [Link] by Laurence Svekis


Explanation
●​ Loads saved notes on startup.​

●​ Saves text to localStorage under a key ("notes").​

●​ Clear removes both UI text and stored data.​

47) Simple Search Filter (List Filtering) — DOM


Goal: Filter visible items based on a search box.
[Link]("app").innerHTML = `
<div class="box">
<h2>Search Filter</h2>
<input id="search" placeholder="Search..." />
<ul id="items"></ul>
</div>
`;

const data = ["JavaScript", "HTML", "CSS", "DOM", "Events",


"Arrays", "Objects"];
const ul = [Link]("items");
const search = [Link]("search");

function render(list) {
[Link] = "";
for (const item of list) {
const li = [Link]("li");
[Link] = item;
[Link](li);
}
}

[Link]("input", () => {
const q = [Link]().trim();
const filtered = [Link](x =>
[Link]().includes(q));

Get more Apps Script Content at [Link] by Laurence Svekis


render(filtered);
});

render(data);

Explanation
●​ Renders from an array to the DOM.​

●​ On each input:​

○​ Normalize query to lowercase.​

○​ Filter items by includes.​

○​ Re-render the list with matching results.​

48) Keyboard Shortcut (Ctrl/Cmd + K) — DOM


Goal: Open a “search” UI using keyboard shortcuts.
[Link]("app").innerHTML = `
<div class="box">
<h2>Keyboard Shortcut</h2>
<p>Press <strong>Ctrl+K</strong> (Windows) or
<strong>Cmd+K</strong> (Mac).</p>
<input id="search" class="hidden" placeholder="Type to
search..." />
</div>
`;

const search = [Link]("search");

[Link]("keydown", (e) => {


const isMac =
[Link]().includes("mac");
const combo = (isMac && [Link] && [Link]() ===
"k")

Get more Apps Script Content at [Link] by Laurence Svekis


|| (!isMac && [Link] && [Link]() ===
"k");

if (combo) {
[Link]();
[Link]("hidden");
[Link]();
}

if ([Link] === "Escape") {


[Link]("hidden");
[Link] = "";
}
});

Explanation
●​ Listens globally on document.​

●​ Detects Ctrl+K or Cmd+K.​

●​ preventDefault() stops browser’s default search behavior.​

●​ Escape hides and clears the input.​

49) Fetch JSON (Async/Await) — Browser


Goal: Load data from an API and display it.
[Link]("app").innerHTML = `
<div class="box">
<h2>Fetch Demo</h2>
<button id="load">Load Data</button>
<pre id="out" style="white-space:pre-wrap;"></pre>
</div>
`;

const out = [Link]("out");

Get more Apps Script Content at [Link] by Laurence Svekis


[Link]("load").addEventListener("click", async
() => {
[Link] = "Loading...";

try {
const res = await
fetch("[Link]
if (![Link]) throw new Error("HTTP " + [Link]);

const data = await [Link]();


[Link] = [Link](data, null, 2);
} catch (err) {
[Link] = "Error: " + [Link];
}
});

Explanation
●​ fetch(url) returns a Promise for the response.​

●​ await [Link]() parses response body as JSON.​

●​ try/catch handles network errors and failed status codes.​

●​ Displays formatted JSON using [Link](..., null, 2).​

50) Simple Pagination (Slice + Render) — DOM


Goal: Show items 5 at a time with Next/Prev.
[Link]("app").innerHTML = `
<div class="box">
<h2>Pagination</h2>
<ul id="list"></ul>
<button id="prev">Prev</button>
<button id="next">Next</button>
<p id="info"></p>

Get more Apps Script Content at [Link] by Laurence Svekis


</div>
`;

const items = [Link]({ length: 23 }, (_, i) => `Item ${i +


1}`);
const pageSize = 5;
let page = 0;

const list = [Link]("list");


const info = [Link]("info");

function render() {
[Link] = "";
const start = page * pageSize;
const pageItems = [Link](start, start + pageSize);

for (const it of pageItems) {


const li = [Link]("li");
[Link] = it;
[Link](li);
}

const totalPages = [Link]([Link] / pageSize);


[Link] = `Page ${page + 1} of ${totalPages}`;
}

[Link]("prev").addEventListener("click", () =>
{
page = [Link](0, page - 1);
render();
});

[Link]("next").addEventListener("click", () =>
{
const totalPages = [Link]([Link] / pageSize);

Get more Apps Script Content at [Link] by Laurence Svekis


page = [Link](totalPages - 1, page + 1);
render();
});

render();

Explanation
●​ slice(start, end) grabs only items for the current page.​

●​ page * pageSize computes where the page starts.​

●​ [Link] computes total pages.​

●​ Prev/Next clamp the page so it doesn’t go out of range.

Get more Apps Script Content at [Link] by Laurence Svekis

You might also like