Unit 2 home
FSWD · MERN LAB 4 · EX.4 UI23PC511CS · LAB 10 PARTS · 120 MIN
LAB 4 · P 1/10PGDN NEXT · PGUP BACK

PART 1 · OPENER · 2 MIN

Your order form gets a reader.

Labs 1–3 built poshtik-campus/: three pages, the order form on menu.html, and an 81-line style.css. Today the folder gets a fifth file, script.js. It holds three dishes as data, and when a button is clicked it reads everything a customer typed into the form.

R-23 SYLLABUS · FSWD LAB · PROGRAMMING EXERCISE 4

“Validation of Static Website using JavaScript.”

Exercise 4 takes two labs. This is part 1.

Validation is three jobs: read a field, decide if the value is acceptable, tell the user. You can't check a value until you can read it, so today is reading. Lab 5 does the deciding and telling.

Choose const or let for every value, and know why
Model a dish as an object, and a menu as an array of objects
Read any form field with getElementById(...).value on a click
Prove it worked in the real Console, then commit and push

Two hours, ten parts

#PARTMINENDS AT
1Opener20:02
2Prelab theory — five questions110:13
3Model answers and self-mark60:19
4Prelab coding drills — four tiny pages280:47
5Walkthrough and project setup90:56
6Exercise 1 — the menu becomes data181:14
7Exercise 1 solution and output81:22
8Exercise 2 — a button that reads the order211:43
9Exercise 2 solution and output81:51
10Debrief, commit and push92:00
TOTAL1202:00
Start the clock in the top bar now.

It runs once for the whole session. If a part runs long, take the time from the next drill, never from an exercise.

PART 2 · PRELAB THEORY · 11 MIN

Five questions. Pen first.

Q1–Q3 come with hints. Q4 and Q5 you answer alone. Write each answer in your notebook before you press its reveal button.

Q1 · GUIDED

Your menu card says Ragi Sangati Bowl · Rs. 55. The customer can change the quantity. Which value gets const and which gets let?

  • Ask of each value: will this box ever be pointed at a new value later?
  • What does the browser do if a const is re-assigned?
write yours first
  • The price gets const because it never changes while the page is open. The quantity gets let because the customer changes it.
  • Re-assigning a const throws TypeError: Assignment to constant variable. and the script stops on that line.
  • Habit: start with const, and switch to let only when some line re-assigns the value.
Q2 · GUIDED

Why store one dish as an object instead of four separate variables? Write the object for the Ragi Sangati Bowl.

  • Braces around the whole thing, key: value pairs, a comma between pairs.
  • Which of name, category, price and isMillet need quotes?
write yours first
  • An object keeps a dish's facts together. With four loose variables, a second dish means four more names, and they drift apart.
  • { name: "Ragi Sangati Bowl", category: "Bowl", price: 55, isMillet: true }
  • Text needs quotes. Numbers and true/false don't. dish.price reads one fact. A key that was never written gives undefined, not an error.
Q3 · GUIDED

What is the difference between document.getElementById("cust-name") and document.getElementById("cust-name").value?

  • One gives you the box, the other gives you what's inside it.
  • What comes back if the id is spelt wrong?
write yours first
  • The first returns the element, the input box itself. .value returns the text typed into it.
  • If no element has that id, getElementById returns null. Reading null.value throws Cannot read properties of null (reading 'value').
  • The id is written bare: "cust-name", with no # like in CSS.
Q4 · ON YOUR OWN

Why does <script src="script.js"></script> go just before </body> and not inside <head>?

write yours first
  • The browser reads the page top to bottom and runs a script as soon as it reaches the tag.
  • In <head>, the script runs before the form exists, so every getElementById returns null.
  • Just before </body>, every element above it already exists.
Q5 · ON YOUR OWN

A customer types 5 into <input type="number" id="qty">. Your code runs let howMany = qtyBox.value;. What do typeof howMany and howMany + 1 give, and why?

write yours first
  • "string" and "51".
  • .value is always a string, even from type="number". When one side of + is a string, + joins text instead of adding.
  • Number(howMany) + 1 gives 6. That fix belongs to Lab 5. Today you only see the trap.

PART 3 · MODEL ANSWERS AND SELF-MARK · 6 MIN

Mark your five answers.

One mark per question. Give yourself the mark only if your answer contains the key idea below. The last column shows which drill covers each question.

QKEY IDEA FOR THE MARKPRACTISED IN
1Price is const (never changes), quantity is let (changes). Re-assigning a const throws a TypeError.Drill 1
2An object keeps one dish's facts together. Braces, key: value, commas between pairs, quotes only on text.Drill 2
3getElementById gives the element (or null). .value gives the typed text.Drill 4
4Scripts run when the browser reaches them. At the end of <body>, the form already exists.Part 5
5.value is a string, so "5" + 1 is "51".Drill 4
Scored 3 or less?

Circle each question you missed and do its drill slowly in Part 4. Every idea in this table comes back in Exercise 1 or 2.

PART 4 · PRELAB CODING DRILLS · 28 MIN

Four drills, four tiny pages.

Build these in a practice folder, Desktop\fswd-practice\lab-04\, not in poshtik-campus. Each drill is one HTML file with its script inside it. Open it in the browser, press F12, and compare the Console with the expected output before you unlock the solution. Give each drill about seven minutes.

DRILL 1const and letPRACTISES → EXERCISE 1
PROBLEM

In drill-1.html, store the price 55 with const and the quantity 1 with let. Print both, change the quantity to 3 and print it, then set the price to 60 and try to print one more line.

INPUT

None.

EXPECTED OUTPUT

Two normal lines, then a red TypeError. The last console.log never prints.

THE ONE IDEA

The browser enforces const. Re-assigning one stops the script on that exact line.

fswd-practice\lab-04\drill-1.html · 27 linesONE LINE PER PRESS
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>Drill 1 · const and let</title>
6</head>
7<body>
8 <h1>Drill 1 · const and let</h1>
9 <p>Press F12 and open the Console.</p>
10
11 <script src="../console-tee.js"></script>
12 <script>
13 // A price never changes while the page is open: const.
14 const price = 55;
15 // A quantity changes when the customer edits it: let.
16 let quantity = 1;
17 console.log("price:", price, "quantity:", quantity);
18
19 quantity = 3;
20 console.log("quantity is now:", quantity);
21
22 // Re-pointing a const stops the script right here.
23 price = 60;
24 console.log("this line never runs");
25 </script>
26</body>
27</html>
drill-1.html RUNNING · ITS OWN CONSOLE BELOW
drill-1.html
CONSOLE · F12
Waiting for the page to load…
Line 23 throws the error, so line 24 never runs. Delete line 23 and the last line would print.
DRILL 2One dish as an objectPRACTISES → EXERCISE 1
PROBLEM

Build const dish for the Ragi Sangati Bowl with four keys: name, category, price, isMillet. Print dish.name, dish.price, the whole dish, and dish.spice.

INPUT

"Ragi Sangati Bowl" · "Bowl" · 55 · true, from the card on your menu page.

EXPECTED OUTPUT

The name, then 55, then the whole object on one line, then undefined.

THE ONE IDEA

The dot reads one fact. A missing key gives undefined without any error, so a misspelt key fails silently.

fswd-practice\lab-04\drill-2.html · 28 linesONE LINE PER PRESS
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>Drill 2 · one dish as an object</title>
6</head>
7<body>
8 <h1>Drill 2 · one dish as an object</h1>
9 <p>Press F12 and open the Console.</p>
10
11 <script src="../console-tee.js"></script>
12 <script>
13 // Four facts about one dish, fastened together.
14 const dish = {
15 name: "Ragi Sangati Bowl",
16 category: "Bowl",
17 price: 55,
18 isMillet: true
19 };
20
21 console.log(dish.name);
22 console.log(dish.price);
23 console.log(dish);
24 // A key that was never written gives undefined, not an error.
25 console.log(dish.spice);
26 </script>
27</body>
28</html>
drill-2.html RUNNING · ITS OWN CONSOLE BELOW
drill-2.html
CONSOLE · F12
Waiting for the page to load…
Four prints, four lines. The last one is undefined, because line 25 asks for a key the object doesn't have.
DRILL 3A list of dishes and a loopPRACTISES → EXERCISE 1
PROBLEM

Make const specials, an array of three objects, each with name and price. Use a for loop from i = 0 while i < 3 to print each name, the word "costs" and its price. Then print "specials listed:" and 3.

INPUT

Ragi Idli Bowl 50 · Pesarattu with Sprouts 55 · Millet Protein Shake 40, prices from your menu cards.

EXPECTED OUTPUT

Ragi Idli Bowl costs 50, then one line each for the other two dishes, then specials listed: 3.

THE ONE IDEA

specials[i] is a whole dish and specials[i].name reaches inside it. Counting starts at 0.

fswd-practice\lab-04\drill-3.html · 27 linesONE LINE PER PRESS
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>Drill 3 · a list of dishes</title>
6</head>
7<body>
8 <h1>Drill 3 · a list of dishes</h1>
9 <p>Press F12 and open the Console.</p>
10
11 <script src="../console-tee.js"></script>
12 <script>
13 // Square brackets hold the list; braces hold each dish.
14 const specials = [
15 { name: "Ragi Idli Bowl", price: 50 },
16 { name: "Pesarattu with Sprouts", price: 55 },
17 { name: "Millet Protein Shake", price: 40 }
18 ];
19
20 // i takes the values 0, 1, 2: one trip per dish.
21 for (let i = 0; i < 3; i = i + 1) {
22 console.log(specials[i].name, "costs", specials[i].price);
23 }
24 console.log("specials listed:", 3);
25 </script>
26</body>
27</html>
drill-3.html RUNNING · ITS OWN CONSOLE BELOW
drill-3.html
CONSOLE · F12
Waiting for the page to load…
Line 22 runs three times, with i equal to 0, 1 and 2. Exercise 1 uses the same loop shape with whole dish objects.
DRILL 4Read a box on clickPRACTISES → EXERCISE 2
PROBLEM

Add a number input with id="plates" and value="5", and a type="button" button with id="count-btn". On click, read the box's .value and print it, its typeof, and the value plus 1.

INPUT

Whatever is in the box when you click. It starts at 5.

EXPECTED OUTPUT

Nothing when the page loads. After a click: plates: 5, typeof plates: string, plates + 1 gives: 51.

THE ONE IDEA

Code inside the listener runs on the click, not when the page loads. .value is always a string.

fswd-practice\lab-04\drill-4.html · 30 linesONE LINE PER PRESS
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>Drill 4 · read a box on click</title>
6</head>
7<body>
8 <h1>Drill 4 · read a box on click</h1>
9 <p>
10 <label for="plates">Plates</label>
11 <input type="number" id="plates" value="5">
12 <button type="button" id="count-btn">Count plates</button>
13 </p>
14
15 <script src="../console-tee.js"></script>
16 <script>
17 const countBtn = document.getElementById("count-btn");
18
19 countBtn.addEventListener("click", function () {
20 // getElementById gives the box; .value gives what is inside it.
21 const platesBox = document.getElementById("plates");
22 let plates = platesBox.value;
23
24 console.log("plates:", plates);
25 console.log("typeof plates:", typeof plates);
26 console.log("plates + 1 gives:", plates + 1);
27 });
28 </script>
29</body>
30</html>
drill-4.html RUNNING · CLICK THE BUTTON IN THE FRAME
drill-4.html
CONSOLE · F12
Waiting for the page to load…
The Console stays empty until you press Count plates. Change the box to 7 and press again: plates + 1 gives: 71.

PART 5 · WALKTHROUGH AND PROJECT SETUP · 9 MIN

Back to poshtik-campus. One new file.

Close the practice folder. From here on, everything goes into the real project, the same folder under Git that Lab 3 finished.

Three checks before you start.

The folder holds index.html, menu.html, about.html, style.css and images/. There's no script.js yet. style.css is 81 lines. git log --oneline shows Style the menu order form at the top, which is Lab 3's last commit.

Folder behind? Catch up in this order.

1. If you ever pushed, git clone your own repo. Your own work is better than any pack. 2. If only a style rule is missing, retype it from Lab 3. 3. If the folder is really gone, ask your instructor first, then use the catch-up pack. It restores Lab 3's finished site exactly: three pages, the 81-line stylesheet, the logo and all ten dish photos. Read README-FIRST.txt inside it before copying anything.

The pack also includes script-reference.js, the finished code for today. Build your own first and compare afterwards.

Single files: README-FIRST.txt · index.html · menu.html · about.html · style.css · script-reference.js · logo. The ten dish photos are only in the ZIP.

1
Open the real folder

Desktop\poshtik-campus\, the one with .git inside. If the path says fswd-practice, you're in the wrong folder.

2
Create script.js beside style.css

In Notepad, save with the name typed as "script.js", quotes included, and Save as type: All Files. In File Explorer turn on View → File name extensions and make sure it isn't script.js.txt.

3
Add the script tag to menu.html

One line, placed exactly as the box below shows.

4
Test the connection

Put console.log("script.js is connected"); in script.js, save, reload menu.html, press F12. If the line appears, the file is connected. You'll delete this test line in Part 7.

5
Save, then reload

Ctrl+S in the editor, then F5 in the browser, every time. The browser only runs what you've saved.

WHERE EXACTLY THE SCRIPT TAG GOES
FILEposhtik-campus\menu.html only. index.html and about.html have no form, so they don't need it.
FINDPress Ctrl+End. Just above </body> is the <footer> block Lab 3 gave this page, ending in </footer>.
INSERTAfter </footer> and before </body>, type <script src="script.js"></script>. The comment above it is optional.
NEVERNever inside <head> and never above the <form>, or every getElementById returns null.
CHECKThe script tag is the last thing before </body>. Reload, press F12, and the test line from step 4 is there.
menu.html · lines 139–155, the end of the fileONE LINE PER PRESS
139 </main>
140
141 <footer>
142 <p>&copy; 2026 Poshtik Campus &middot; orders@poshtikcampus.in</p>
143 </footer>
144
145 <!-- COURSE-WEBSITE ONLY, not on your disk: forwards this page's real console
146 output to the panel beside the frame. It prints nothing of its own.
147 Loaded FIRST so it is listening before script.js runs. -->
148 <script src="console-tee.js"></script>
149
150 <!-- LAB 4, STEP 1: the LAST line before </body>. Placed here so every
151 form element above already exists when the script runs. -->
152 <script src="script.js"></script>
153
154</body>
155</html>
Skip lines 145–148.

Those four lines exist only in the copy of menu.html that runs on this page. They pass its console output to the black panels you'll see in Parts 7 and 9. Your file doesn't have them, so in your file line 152's script tag sits a few lines after </footer>.

PART 6 · GRADED · EXERCISE 1 · 18 MIN

Exercise 1 · The menu becomes data.

No code is given in this part. You already have every piece from Drills 1–3. Write it in your real script.js.

EXERCISE 1 · MPS-01 · MODEL THE MENU AS OBJECTS
START
Delete the test line from Part 5. Begin script.js with a short comment saying what the file is.
BUILD
A const named poshtikMenu: an array of three dish objects, each with exactly these keys: name, category, price, isMillet.
DATA
  • "Jonna Rotte Wrap" · "Wrap" · 60 · true
  • "Paneer Protein Bowl" · "Bowl" · 80 · false
  • "Ragi Sangati Bowl" · "Bowl" · 55 · true
Check each price against the card on your own menu page. If they disagree, the page is right.
PRINT
A plain for loop with let i, running while i < 3, that prints poshtikMenu[i]. After the loop, print "dishes modelled:" and 3.
LIMIT
No .forEach, .map or .filter. Keep the 3 hard-coded for now.
DONE WHEN
Reloading menu.html prints three object lines and then dishes modelled: 3, with no red text. You haven't clicked anything yet.
Stuck for five minutes?

Go back to Drill 3's solution, not ahead to Part 7. The shape is the same, only now each item is a whole dish object.

PART 7 · SOLUTION AND OUTPUT · EXERCISE 1 · 8 MIN

Exercise 1, solved: lines 1–25 of script.js.

Compare line by line with what you wrote. Your comments can be different. The code can't.

Your own attempt first. It's what the evaluator marks.

WHERE EXACTLY THIS GOES
FILEposhtik-campus\script.js, not the practice folder and not script-reference.js.
FINDThe test line from Part 5, the only line in the file.
INSERTDelete it, then type lines 1–25 from the top of the file.
CHECKSave, reload menu.html, press F12. You see the four lines shown in the console panel beside the code.
poshtik-campus\script.js · lines 1–25ONE LINE PER PRESS
1/* script.js — Poshtik Campus · the 5th file, born in Lab 4.
2 This is the file you type in Lab 4, line for line.
3 Open menu.html, press F12, click Console. */
4
5/* ===== MPS-01 · the menu becomes DATA =====
6 Prices match the cards on the page above. If the object and the page
7 ever disagree, the page is right and the object is wrong. */
8const poshtikMenu = [
9 { name: "Jonna Rotte Wrap",
10 category: "Wrap",
11 price: 60, isMillet: true },
12 { name: "Paneer Protein Bowl",
13 category: "Bowl",
14 price: 80, isMillet: false },
15 { name: "Ragi Sangati Bowl",
16 category: "Bowl",
17 price: 55, isMillet: true }
18];
19
20// A plain for loop — no .forEach, no .map. The 3 is hard-coded ON
21// PURPOSE so you feel its limitation; poshtikMenu.length is homework 1.
22for (let i = 0; i < 3; i = i + 1) {
23 console.log(poshtikMenu[i]);
24}
25console.log("dishes modelled:", 3);
THE REAL menu.html + script.js · ITS OWN CONSOLE BELOW
menu.html
CONSOLE · F12 · PRINTED WHEN THE PAGE LOADS
Waiting for the page to load…
These four lines print as soon as the page loads, before anyone clicks. The prices in the console match the prices on the cards in the frame.
Four lines to be able to explain.

Line 8 is const because poshtikMenu is never pointed at a different array. Line 22 is let i because i changes on every trip. Line 23 prints a whole dish object. Line 25 runs once, after the loop ends.

The 3 on lines 22 and 25 is a weakness: add a fourth dish and it won't print. You'll fix that at home in Part 10.

PART 8 · GRADED · EXERCISE 2 · 21 MIN

Exercise 2 · A button that reads the order.

No code is given in this part. Two files change: menu.html gets one button, and script.js grows below line 25. Drill 4 is the small version of this.

EXERCISE 2 · MPS-02 · READ THE ORDER FORM ON CLICK
BUTTON
In menu.html, in the form's last <p>, after Place order, add a button with type="button", id="check-order" and the text Check my order.
FETCH
In script.js, fetch the button once into const checkBtn. Put everything else inside if (checkBtn) { … }, so the script never crashes on a page without that button.
LISTEN
Attach a "click" listener to checkBtn. Everything below runs inside it.
READ
  • Fetch these four boxes with getElementById: cust-name, cust-phone, qty, notes. Then read each one's .value into a let: customerName, phone, howMany, notes.
  • The dish is ten radios sharing name="dish", so there's no id. Get the checked one with document.querySelector("input[name='dish']:checked") into const picked. It is null when nothing is ticked, so set chosenDish to picked ? picked.value : "".
PRINT
Use these labels, in this order: "customer name:", "phone:", "dish ordered:", "quantity:", "notes:". Then print "typeof quantity:" with typeof howMany, and "howMany + 1 gives:" with howMany + 1.
NOTICE
If the name is "", print "⚠ the name field is empty". If no dish was picked, print "⚠ no dish was picked". Don't block anything. That's Lab 5's job.
TEST
Enter the name Sravani, phone 9876543210, pick Ragi Sangati Bowl, set quantity 2, notes less spicy, then click. Reload and click again with nothing filled in.
DONE WHEN
The first click prints seven labelled lines ending in howMany + 1 gives: 21. The empty click also prints both ⚠ lines.
If the Console says Cannot read properties of null

An id in script.js doesn't match menu.html. Copy it character by character. cust-name is not custName.

PART 9 · SOLUTION AND OUTPUT · EXERCISE 2 · 8 MIN

Exercise 2, solved: one button and lines 27–76.

After this, your two files match the finished Lab 4 site line for line.

Click your own button at least once before you open this.

STEP 1 · WHERE EXACTLY THE BUTTON GOES
FILEposhtik-campus\menu.html, inside the order form from Lab 2.
FINDThe last <p> of the form, the one holding <button type="submit">Place order</button>, just above </form>.
INSERTA new line after Place order with the new button. The comment on line 134 is optional.
NEVERDon't delete Place order. Don't put the button outside </form>. Don't leave it as type="submit", or the page reloads and the Console clears.
CHECKReload: two seagreen buttons sit side by side at the bottom of the form.
poshtik-campus\menu.html · lines 132–137ONE LINE PER PRESS
132 <p>
133 <button type="submit">Place order</button>
134 <!-- LAB 4, STEP 2: the second button. type="button" so it never submits. -->
135 <button type="button" id="check-order">Check my order</button>
136 </p>
137 </form>
STEP 2 · WHERE EXACTLY THE READER GOES
FILEposhtik-campus\script.js, the same file, growing downward.
FINDLine 25, console.log("dishes modelled:", 3);.
INSERTLine 26 stays blank. Type lines 27–76 below it.
NEVERNever inside the for loop's braces, or the listener gets attached three times.
CHECKThe file ends at line 76 with }. Save, reload, fill the form, click Check my order.
poshtik-campus\script.js · lines 27–76ONE LINE PER PRESS
27/* ===== MPS-02 · read the order form on click =====
28 1 fetch the button · 2 say what to run when · 3 fetch each field then
29 read it · 4 print it. */
30
31// 1 — fetch the button once
32const checkBtn = document.getElementById("check-order");
33
34// Safety check: index.html and about.html have no form and no button.
35if (checkBtn) {
36
37 // 2 — say WHAT to run WHEN it is clicked
38 checkBtn.addEventListener("click", function () {
39
40 // 3 — getElementById hands you the BOX; .value hands you the
41 // CONTENTS. Two different steps, never one.
42 const nameBox = document.getElementById("cust-name");
43 const phoneBox = document.getElementById("cust-phone");
44 const qtyBox = document.getElementById("qty");
45 const notesBox = document.getElementById("notes");
46
47 let customerName = nameBox.value;
48 let phone = phoneBox.value;
49 let howMany = qtyBox.value;
50 let notes = notesBox.value;
51
52 // The radio group: only the CHECKED one is the answer.
53 const picked = document.querySelector("input[name='dish']:checked");
54 let chosenDish = picked ? picked.value : "";
55
56 // 4 — print it, each with a label so the output is readable
57 console.log("customer name:", customerName);
58 console.log("phone:", phone);
59 console.log("dish ordered:", chosenDish);
60 console.log("quantity:", howMany);
61 console.log("notes:", notes);
62
63 // .value is ALWAYS a string, even from type="number".
64 console.log("typeof quantity:", typeof howMany);
65 console.log("howMany + 1 gives:", howMany + 1);
66
67 // Lab 5's job is to REFUSE a bad order. Today we only notice.
68 if (customerName === "") {
69 console.log("\u26A0 the name field is empty");
70 }
71 if (chosenDish === "") {
72 console.log("\u26A0 no dish was picked");
73 }
74 });
75
76}
THE FINISHED LAB 4 SITE · ITS OWN CONSOLE BELOW
menu.html
CONSOLE · F12
Waiting for the page to load…
The four load-time lines from Exercise 1 appear first. Scroll the frame to Order Here, fill the form, and press Check my order. With quantity 1 you'll see howMany + 1 gives: 11. The dish prints as its value attribute, for example ragi-sangati-bowl, not the label beside the radio.
Four lines to be able to explain.

Line 35: script.js only runs when a page loads it, and if that page had no button, checkBtn would be null. Line 38: the function is handed to the button and runs on each click, not at load. Lines 42–50: first fetch the box, then read its .value. Line 54: use the checked radio's value, or "" if nothing is ticked.

PART 10 · DEBRIEF · 9 MIN

Common mistakes, commit, and what comes next.

Most of these either crash with a clear message or fail silently. Learn to recognise both.

#WHAT YOU DIDWHAT YOU SEETHE FIX
1Typo in an id, like custNameCannot read properties of null (reading 'value')Copy the id exactly from menu.html. No #.
2Script tag inside <head>Clicking does nothing, or the same null errorMove the tag to just before </body>.
3Doing maths on .valuehowMany + 1 gives: 21Nothing is broken, it's a string. Number() comes in Lab 5.
4Re-assigning a constAssignment to constant variable.Use let for values that change.
5New button left as type="submit"Page reloads, Console clearstype="button"
6File saved as script.js.txtEmpty Console, no error at allSave as "script.js" with All Files, and check extensions.

What you can do now

Choose const or let and say why.
Write a dish as an object and a menu as an array of objects, and loop over it.
Read any form field with getElementById(...).value, and the checked radio with querySelector.
Run code on a click with addEventListener.
Explain why "5" + 1 is "51", and fix a null error in under a minute.

Commit and push

Open a terminal inside poshtik-campus\ and run these in order. Read every reply. git status should list menu.html as modified and script.js as new, and the commit should report 2 files changed.

Terminal · poshtik-campusONE COMMAND PER PRESS
1$ git status
2$ git add menu.html script.js
3$ git commit -m "Model menu as objects and read order form values"
4$ git push
5$ git log --oneline
If the push is refused

“rejected — fetch first”: run git pull, then push again. “authentication failed”: create a new token on GitHub, as in Lab 1. Never delete the folder to fix a push. Your commit history is part of what gets graded.

POSHTIK-CAMPUS · AFTER TODAY
poshtik-campus/
index.html unchanged
menu.html + one button, + the script tag
about.html unchanged
style.css unchanged, 81 lines
script.js NEW · 76 lines
images/ unchanged

Where this lab sits

← BUILT ONLab 2 built the form and its ids. Lab 3 styled it and gave every page its footer. Classes 13–16 taught the JavaScript you used today.
NEXT →Lab 5 finishes Exercise 4. The same script.js starts refusing bad orders: an empty name, a quantity of zero, letters in a phone number, each with a visible message.
At home · 15 minutes

Homework 1: on line 22, replace the 3 with poshtikMenu.length. Add a fourth dish from your menu page and check that it prints without changing the loop. Homework 2: write one sentence describing what a customer should see when they leave the name blank. Lab 5 starts from that sentence.