Today your site starts listening
The order form — your site starts collecting information.
Until today, poshtik-campus/ could only talk: it showed pages, and visitors read them. Today you put every form control to work: your own menu.html — exactly as Lab 1 left it — gains a real order form — name, phone, dish, quantity, notes, submit. And because this folder is a Git repository now, today ends with the commit-and-push ritual Lab 1 promised you.
“Creation of Static Web Site using HTML Forms.”
Walk out of this lab able to…
An order form is pure typing — labels, inputs, buttons. No photos, no asset pack. Your two tools are the ones you already own: VS Code and your browser. (The dish photos join the project in a later lab, after CSS makes a proper home for them.) Behind because you missed Lab 1 or changed machines? First choice, always: git clone your own repo. Only for a genuine emergency — no push, excused absence, instructor informed — the Lab-2 rescue pack restores Lab 1's exact exit state: README-FIRST.txt · index.html · menu.html · about.html. How to use it: ① read the README top to bottom; ② put the three .html files into a new Desktop\poshtik-campus\ folder; ③ click the whole nav triangle in the browser (Home ⇄ Menu ⇄ About — zero error pages); ④ run the README's three git commands (one honest "caught up here" commit) and push. It restores files, not skills — fswd_lab_01.html still owes you its practice in Learning Mode this week.
Which input type for a phone number field?
Your order form will ask for a phone number, so the canteen can call when the food is ready. Which type= do you reach for — and why is the obvious-looking answer not the best one?
A phone number is made of digits, so number feels right — but it treats the value as maths: it adds little up/down spinner arrows, and it refuses a leading zero or a +91. Nobody ever adds 1 to a phone number. Wrong tool, politely declined.
tel says what the value is — a telephone number. It accepts +, spaces and leading zeros, and on a phone it opens the number keypad instead of the full keyboard. Small kindness, right meaning.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Poshtik Campus — Menu</title></head><body> <form> <!-- the phone field --> <input type="tel" id="cust-phone" name="cust-phone"> </form></body></html>Pick the type by meaning, not by what the characters look like. Digits you calculate with take number (quantity!). Digits you dial take tel. Text with an @ shape takes email. The table of input types is exactly this decision, written out.
Write a label and its input — properly paired.
Every input on today's form gets a <label>. The pairing runs on two attributes that must carry the same value — write the pair for a "Your name" field.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Poshtik Campus — Menu</title></head><body> <form> <label for="cust-name">Your name</label> <input type="text" id="cust-name" name="cust-name"> </form></body></html>for="cust-name" on the label, id="cust-name" on the input. Same value, spelled the same, or the handshake simply doesn't happen (and nothing warns you — the click test is your check).
name="cust-name" is what the data will be called when the form is sent. The label pair is for humans; name is for the data. Three attributes, three jobs — today's form uses all three on every field.
How do two radio buttons become one choice?
Your form offers dishes as radio buttons — pick one. What single attribute makes separate buttons behave as one group, where choosing one lets go of the other?
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Poshtik Campus — Menu</title></head><body> <form> <input type="radio" id="d-idli" name="dish" value="ragi-idli"> <input type="radio" id="d-dosa" name="dish" value="ragi-dosa"> <!-- same name="dish" -> one group, one pick --> </form></body></html>Give each radio a different name and every button becomes its own little group of one — you can select all of them at once. Easy to spot, easy to fix: one shared name, different values, different ids (each label still needs its own id to hold hands with).
Two questions, answered by you first. Then the sheet.
Guided is over. Answer these two on paper before the gate below opens — both are moves the build will ask of you within the hour.
Q4. The order form needs a quantity field: how many plates, from 1 to 10. Write the complete input line (with its label), choosing the type that fits counting.
Q5. A friend's form has a "Place order" button written as <button>Place order</button> outside the <form> element, and clicking it does nothing. In one sentence: why, and where should it live?
Both answers written? Only then.
<label for="qty">Quantity</label><input type="number" id="qty" name="qty" min="1" max="10" value="1">A submit button only submits the form it lives inside. Standing outside the <form>…</form> tags, it belongs to no form, so a click has nothing to send. Move it inside, just before </form>, and it wakes up. (Compare Q1–Q3: in forms, where a tag sits matters as much as what it says.)
- Q4 used
type="number"withminandmax, plus a paired label — full marks. Chosetel? Re-read Q1: dial vs count. Quantity is counted. - Q5 said "outside the form means it belongs to no form" in some wording — full marks. The fix is always placement, not more attributes.
A complete page: skeleton, a little CSS, one labelled input.
Four tiny finger-warmers before the real build — each one rehearses a move today's form uses at full scale. No marks, no gate: the answer sits right below, because a warm-up you can't check isn't a warm-up. Type it first, then look.
The program: in a scratch file called form-warmup-1.html (in your fswd-practice\ sandbox — never the repo), write a complete page: doctype, <html>, a <head> with charset, title and a small <style> block, then a <body> holding one <form> with a single labelled text input asking for the visitor's name. Nothing else — but nothing skipped either: this is the host file every later warm-up assumes.
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <title>Form warm-up 1</title> <style> body { font-family: Arial, sans-serif; padding: 24px; } label { display: block; margin-bottom: 6px; } </style> </head> <body> <form> <label for="vname">Your name</label> <input type="text" id="vname" name="visitor"> </form> </body></html>display: block rule from your <style> block doing its job.Today's order form is this exact pattern, five times over — five labels, five inputs, five handshakes. If your fingers typed this pair without thinking, the real build is happy repetition. And because you typed the whole file here — skeleton and style block included — warm-ups 2, 3 and 4 can show you just the <form>: paste each one into this host page and it runs.
A radio group of three options.
Q3's shared-name rule, now typed with your own hands: three dishes, one name, one possible pick.
The program: in form-warmup-2.html, a form offers three dishes — Ragi Idli, Pesarattu, Millet Shake — as radio buttons. Each button gets its own label. Prove one-pick behaviour in the browser before you look down.
<form> <p>Pick your dish:</p> <input type="radio" id="d1" name="dish" value="ragi-idli"> <label for="d1">Ragi Idli</label> <input type="radio" id="d2" name="dish" value="pesarattu"> <label for="d2">Pesarattu</label> <input type="radio" id="d3" name="dish" value="millet-shake"> <label for="d3">Millet Shake</label> </form>The order form's dish-picker is this group, grown to five dishes. Also worth noticing: with radios, the label usually comes after the button — that's the layout your eye expects on every real website.
A select dropdown with three options.
Radios show every option at once; a <select> folds them into one neat box. Today's form uses it for the pickup time — this warm-up is that control at practice scale.
The program: in form-warmup-3.html, a labelled dropdown asks "When will you pick up?" with three choices: 11:00, 13:00, 17:00. Remember the shape: <select> is the box, each <option> a row inside it.
<form> <label for="pickup">When will you pick up?</label> <select id="pickup" name="pickup-time"> <option value="11:00">11:00 — short break</option> <option value="13:00">13:00 — lunch</option> <option value="17:00">17:00 — after labs</option> </select> </form>Notice the label pairs with the <select> itself, never with an option — one handshake for the whole box. And the visible text ("13:00 — lunch") can be friendlier than the tidy value that gets sent. Two layers, two audiences — the same human/data split as Q2.
A submit button — and watching where the data goes.
The last warm-up answers the question every student asks next: "when I press the button… what actually happens?" You'll see the answer appear in the address bar, character by character.
The program: in form-warmup-4.html, one text input named snack and a submit button. Save, open, type chikki into the box, press the button — then read the address bar.
<form> <label for="snack">Favourite snack</label> <input type="text" id="snack" name="snack"> <button type="submit">Send</button> </form>Nowhere, yet — and that's the honest, correct answer for Unit 1. The browser packed your data into the address (that ?name=value tail) and delivered it back to the same page, because we gave the form no destination. In Unit 4, a server will stand at the other end and catch it. Today's form is a postbox with the letter written perfectly — the postal service arrives later in the course.
Open poshtik-campus. Today nothing new is created — something grows.
Lab 1 ended with three files pushed to GitHub. Today you create zero new files: the whole session happens inside menu.html, which gains a form. That's what a real project feels like — files change more often than they appear.
File menu, Open Folder, pick poshtik-campus. The Explorer should show index.html, menu.html, about.html — exactly as Lab 1 left them.
Press Ctrl+End to jump to the bottom of the file. Walk up past </html>, </body> and the nav list until you reach the comment <!-- site navigation -->. The line just above it is the closing </ul> of the dish list (line 22 in Lab 1's 29-line file). Click at the end of that </ul> line, press Enter to open a fresh line, and that is where today's form begins — after the ten dishes, before the site navigation. After the food, the ordering.
Double-click it in your file manager, or right-click and Open with Live Server if you have it. Keep editor and browser side by side: type, save, reload, watch.
poshtik-campus — the same repo from Lab 1menu.html — edited, not created</ul> (line 22), before <!-- site navigation --> — the form becomes lines 23 to 58 if your file matches Lab 1's 29-line solution; the nav moves down to lines 59 to 63 and the file ends at line 65<ul>, inside the nav <ul>, or after </body> — content outside body is invisible or invalid</ul>; cut the form and re-place it.No problem — clone your own repo and you're exactly where everyone else is: git clone https://github.com/<your-username>/poshtik-campus.git. That one command is why we pushed last week. Never pushed and genuinely stuck? Part 1's note links the Lab-2 rescue pack (Lab 1's exact three files + a README that walks you through setup step by step) — ask your instructor first.
The canteen wants orders. Build the form that takes them.
Poshtik Campus's counter queue is too long at 1 pm. The owner wants students to order from their phones. You have every ingredient: four warm-ups, five prelab answers, and the whole form toolbox. Build it yourself first — the gate stays shut until you've tried.
Requirements — the order form in menu.html:
- A Your name text field —
idandnamebothcust-name. - A Phone number field with the right type —
idandnamebothcust-phone. - A Pick your dish group of ten radio buttons — the same ten dishes as your list, Jonna Rotte Wrap to Millet Protein Shake — all sharing
name="dish", each one wrapped inside its own label. - A Quantity number field, 1–10 —
idandnamebothqty. - A Notes for the kitchen multi-line box —
idandnamebothnotes. - A Place order submit button.
- Every field labelled with a working click-test.
- The whole thing inside one <form>, under an Order Here heading.
Type it, save it, reload — then click every label and press the button. The address bar should grow a ?cust-name=…&cust-phone=… tail.
poshtik-campus\menu.html — this one file only. index.html and about.html are not touched today, and you create no new file.</html>, </body>, the nav list, then the comment <!-- site navigation -->. The line just above that comment is the dish list's closing </ul> — line 22 of Lab 1's 29-line file. Click at the end of that </ul> line and press Enter.<!-- order form -->, the <h2>Order Here</h2> heading and the whole <form> … </form> block go on those fresh lines — after the dish list's </ul>, before <!-- site navigation -->. They become lines 23 to 58; the nav slides down to lines 59 to 63 and the file now ends at line 65. Every one of the eight requirements lives inside that single form element. After the food, the ordering.<ul> or the nav <ul> (a form is not a list item). Never after </body> — the browser either ignores it or silently moves it. Never open a second <form>: one form, every control inside it.</ul> — cut the block and re-place it. Now press Place order: if the address bar grows ?cust-name=…&cust-phone=…, your name attributes are right."Add the order form to menu.html".SAMPLE OUTPUT — YOUR FINISHED FORM MUST RENDER (AND BEHAVE) LIKE THIS
?cust-name=…&cust-phone=…&dish=…&qty=…¬es=… tail in the address bar above. Your build must do the same.Built and clicked through? Only then.
menu.html grows its form — lines 23 to 58.
Compare with yours move by move. Different wording in labels is fine; different structure (a missing shared name, an unpaired label) is the thing to fix.
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Poshtik Campus — Menu</title> </head> <body> <h1>Our Menu</h1> <p>Ten dishes, every one of them poshtik.</p> <ul> <li>Jonna Rotte Wrap</li> <li>Sajja Roti Wrap</li> <li>Ragi Sangati Bowl</li> <li>Ragi Idli Bowl</li> <li>Pesarattu with Sprouts</li> <li>Ulava Charu Protein Bowl</li> <li>Gongura Sprouts Salad</li> <li>Sprouts Moong Chilla</li> <li>Paneer Protein Bowl</li> <li>Millet Protein Shake</li> </ul> <!-- order form --> <h2>Order Here</h2> <form> <p> <label for="cust-name">Your name</label><br> <input type="text" id="cust-name" name="cust-name"> </p> <p> <label for="cust-phone">Phone number</label><br> <input type="tel" id="cust-phone" name="cust-phone"> </p> <fieldset> <legend>Pick your dish</legend> <label><input type="radio" name="dish" value="jonna-rotte-wrap"> Jonna Rotte Wrap</label><br> <label><input type="radio" name="dish" value="sajja-roti-wrap"> Sajja Roti Wrap</label><br> <label><input type="radio" name="dish" value="ragi-sangati-bowl"> Ragi Sangati Bowl</label><br> <label><input type="radio" name="dish" value="ragi-idli-bowl"> Ragi Idli Bowl</label><br> <label><input type="radio" name="dish" value="pesarattu-with-sprouts"> Pesarattu with Sprouts</label><br> <label><input type="radio" name="dish" value="ulava-charu-protein-bowl"> Ulava Charu Protein Bowl</label><br> <label><input type="radio" name="dish" value="gongura-sprouts-salad"> Gongura Sprouts Salad</label><br> <label><input type="radio" name="dish" value="sprouts-moong-chilla"> Sprouts Moong Chilla</label><br> <label><input type="radio" name="dish" value="paneer-protein-bowl"> Paneer Protein Bowl</label><br> <label><input type="radio" name="dish" value="millet-protein-shake"> Millet Protein Shake</label> </fieldset> <p> <label for="qty">Quantity</label><br> <input type="number" id="qty" name="qty" min="1" max="10" value="1"> </p> <p> <label for="notes">Notes for the kitchen</label><br> <textarea id="notes" name="notes" rows="3" cols="40"></textarea> </p> <p> <button type="submit">Place order</button> </p> </form> <!-- site navigation --> <ul> <li><a href="index.html">Home</a></li> <li><a href="about.html">About us</a></li> </ul> </body></html>- The click test: click each label's text — focus must jump into its control (or tick its radio). One dead label = one missing/mismatched
for/idpair. - The radio test: picking Sajja Roti Wrap must un-pick Jonna Rotte Wrap. If two can be selected at once, their
name=values differ somewhere. - The submit test: pressing Place order must reload with a
?cust-name=…&cust-phone=…&dish=…&qty=…¬es=…tail. A missing key means that control has noname. - The meaning test: phone uses
tel(dialled), quantity usesnumberwithmin/max(counted). Swapped? Re-read Part 2.
git add .git commit -m "Add order form to menu"git pushaction attribute — on purpose.
With no destination given, the browser sends the data back to the same page — which is exactly right for Unit 1: we can see the data in the address bar without needing a server. When Unit 4 arrives, one attribute (action="…") points this same form at a real server. The form won't change shape; only its destination will.
When you pressed Place order and the address bar grew that ?cust-name=Ravi&dish=ragi-idli-bowl tail, your browser didn't just "send data" — it sent a GET request. GET is one of exactly five verbs the whole web runs on. Every button on every website you have ever used — Swiggy, WhatsApp Web, your college portal — speaks one of these five. You already used one today, so meet the other four now, gently.
Think of a server as the canteen counter. There are only five things you ever do at a counter — and the web named all five. Your form just did the first one:
Ask for something — read the menu. Changes nothing. Your ?snack=chikki tail today WAS a GET.
Hand in something NEW — place an order the counter hasn't seen before. Creates a new record.
Swap the WHOLE order for a fresh one — “forget my old slip, here is the complete new slip.”
Fix ONE detail, keep the rest — “same order, but make it 2 plates.” A small touch-up, not a replacement.
Remove it — the counter tears up your slip. The record is gone.
That's the whole preview — five verbs, one canteen counter. Nothing to memorise today: plain HTML forms can only speak GET and POST; the other three arrive when JavaScript and Express.js join in Unit 4–5, where every verb gets its full treatment. From today onwards, whenever a page “sends” anything, ask yourself: which of the five verbs was that?
PYQ · Part 3 · Q11(a) · 4+4 marks — the form you just built, in exam clothes.
An eight-mark form question, minutes after you built a real form. The exam calls it a household survey; your muscles know it as the order form with different labels. Watch how the same five moves earn all eight marks.
Q11(a). Design an HTML form for a household survey (like the Samagra Kutumba survey) that collects: head of family name, phone number, number of family members, house type (own / rented / other — only one selectable), and any remarks. Use appropriate input types and labels. [4+4M]
Ans. — structure first (4M), then the code (4M), then deeper than the marks ↓
Choose each control by meaning (this earns the first 4M). Name takes type="text" (free words) · Phone takes type="tel" (dialled, not counted) · Family members takes type="number" with min="1" (counted) · House type takes three type="radio" sharing name="housetype" (only one may be chosen) · Remarks takes <textarea> (multi-line).✓ 2
State the two rules that make it a *correct* form: every control gets a <label for="…"> paired to its id, and every control gets a name so its value travels on submit — no name = silently dropped data. Writing these two sentences before the code signals understanding, not memory.✓ 2
<form> <label for="head">Head of family</label> <input type="text" id="head" name="head"> <label for="phone">Phone</label> <input type="tel" id="phone" name="phone"> <label for="members">Family members</label> <input type="number" id="members" name="members" min="1"> </form>
<fieldset> <legend>House type</legend> <input type="radio" id="own" name="housetype" value="own"> <label for="own">Own</label> <input type="radio" id="rented" name="housetype" value="rented"> <label for="rented">Rented</label> <input type="radio" id="other" name="housetype" value="other"> <label for="other">Other</label> </fieldset> <label for="remarks">Remarks</label> <textarea id="remarks" name="remarks" rows="3"></textarea> <button type="submit">Submit survey</button>
Not paper-only: directly below this sheet the complete survey.html builds LIVE — every line pressed in one by one, a real working form beside it, output growing in sync.
✓ 2The line that separates an 8 from a 6: "All three house-type radios share name="housetype", which is what makes them one exclusive group — fieldset is only the visual box; the shared name is the behaviour." That's your Q3 prelab answer, earning exam marks the same afternoon.✓
Beyond the marks — why the examiner chose a survey. Every government or business form is the same five decisions wearing different labels: free text, constrained text, counted number, exclusive choice, long prose. Master the mapping once and every future form — exam or production — is a re-skin. The exam isn't testing tags; it's testing whether you classify data before typing.✚ depth
Marks anatomy: 4M for correct choice of controls with labels justified by meaning · 4M for working code with the radio group correctly shared. Most lost mark in real scripts: three radios with three different names. You tested exactly that bug today — in your own browser, on purpose.
Exam answers in this course are never paper-only. Here is survey.html as a complete file — full skeleton, every line pressed in one by one — with its live output beside it. Type it in your fswd-practice\ sandbox (exam practice never enters the poshtik-campus repo) and it behaves exactly like this preview: labels click, one house type at a time, and Submit grows the data tail.
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Samagra Kutumba Survey</title></head><body> <h1>Household Survey</h1> <form> <p> <label for="head">Head of family</label> <input type="text" id="head" name="head"> </p> <p> <label for="phone">Phone</label> <input type="tel" id="phone" name="phone"> </p> <p> <label for="members">Family members</label> <input type="number" id="members" name="members" min="1"> </p> <fieldset> <legend>House type</legend> <input type="radio" id="own" name="housetype" value="own"> <label for="own">Own</label> <input type="radio" id="rented" name="housetype" value="rented"> <label for="rented">Rented</label> <input type="radio" id="other" name="housetype" value="other"> <label for="other">Other</label> </fieldset> <p> <label for="remarks">Remarks</label> <textarea id="remarks" name="remarks" rows="3"></textarea> </p> <button type="submit">Submit survey</button> </form></body></html>Household Survey
Same three files — one of them just learned to listen.
No new files today, and that's the point worth saying out loud: the repo's shape is stable while its capability grows. That's what most weeks of real development look like.
Two commits: "First version of Poshtik Campus site", then "Add order form to menu". Anyone reading the history sees the site grow feature by feature. By Lab 12 this list reads like a course diary written in code.
The site as it stands tonight — the real files, running.
Not a drawing of your work: a browser loading the three actual files in your folder. Open menu.html below and the form is your form — click a label and focus jumps, pick one dish and the other un-picks, press Place order and the address bar inside the frame grows its ?cust-name=…&dish=… tail. Every behaviour you were told to test, testable right here.
?cust-name=…&cust-phone=…&dish=…&qty=…¬es=…; ④ note the page is still unstyled — correct, because CSS is Lab 3. Structure works before it looks good.Your site can now ask a question and carry the answer.
Say each of these out loud — hesitation marks your revision list.
menu.html as a save point and push it to GitHub.git statusfirst — it should reportmodified: menu.htmland nothing else.git add ., thengit commitwith a message that says what grew:"Add order form to menu".- Plain
git push— no-uneeded; Lab 1's first push already linked the branches.
menu.html.student@lab-12:~/poshtik-campus$ git status modified: menu.htmlstudent@lab-12:~/poshtik-campus$ git add .student@lab-12:~/poshtik-campus$ git commit -m "Add order form to menu"[main 4f9c2b1] Add order form to menu 1 file changed, 30 insertions(+)student@lab-12:~/poshtik-campus$ git pushTo https://github.com/you/poshtik-campus.git a1d3e07..4f9c2b1 main -> mainAdd one more field to the order form: type="time" named pickup, labelled "Pick up at". Submit and find pickup=… in the address bar. Commit it: "Add pickup time to order form".
Write the Q11(a) survey form once on paper, from memory, timed at 12 minutes. Then type it and run the click test. Paper first — the exam hall has no autocomplete.
Sit with this puzzle before Lab 3: "how would you make all three dish names green without touching the HTML?" Lab 3's stylesheet answers it in its very first rule.
Two sentences: (1) Why must the three dish radios share one name? (2) After pressing Place order, where exactly does the typed data appear — and why there and not on a server?
Your site now has structure, pages, a table and a form — all wearing the browser's plain default clothes. Lab 3 adds style.css beside these three pages: one rule, and every dish changes colour at once. The makeover begins.