Type-Specific Fields
Personal Catalogue: PHP & MySQL
Chapter 4 · Type-Specific Fields
Chapter 3's add/edit forms already work, but they show one generic "Creator" label and one generic "Format detail" label no matter which item type is selected — technically correct, since those are the real column names, but not very honest to the person actually filling the form in. A CD's "creator" is really its artist; a DVD's is really its director. This chapter makes the same single form feel type-aware without touching the database schema at all.
| Column | Book | CD | DVD / Blu-ray |
|---|---|---|---|
creator | Author | Artist | Director |
format_detail | Hardcover / paperback | Single / album | Region code |
The Core Idea: Data-Driven Labels, Not a Fork in the Form
A tempting but wrong approach here is to build a genuinely separate form for each item
type — a "book form," a "CD form," a "DVD form" — each with its own field names. That
would mean four times the markup to maintain, and four separate branches of PHP to
validate and insert. Since the underlying items table is deliberately
shared (Chapter 2), the form should stay shared too: one set of inputs, with their
labels — not their names, not their database columns — changing based
on whatever item_type_id is currently selected.
That's a job for a small amount of vanilla JavaScript running in the browser, driven by
a plain lookup object built once from the same item_types data the form
already renders its dropdown from.
Building the Label Map
Rather than hard-coding the label text in JavaScript (where it could drift out of sync
with the item types actually stored in the database), the label map is generated
server-side, from PHP, as a small inline <script> block that runs
once when the page loads:
json_encode() turns a plain PHP associative array into a real JavaScript
object literal — this is the same real technique PHP Intermediate Chapter 7 covers for
turning PHP data into JSON generally, just used here to hand a small config object to a
page's own inline script rather than to an API response.
Wiring the Dropdown to the Labels
The item-type <select> already exists from Chapter 3. Two small
changes make it drive the labels: giving the <select> and the two
label elements real id attributes, and each <option> a
data-name attribute holding the real item_types.name value
('book', 'cd', and so on) — not the numeric id, since that's
what the label maps above are keyed by:
And the script that actually reacts to a change:
creatorLabels[typeName] ?? 'Creator' matters for one real edge case: the
blank -- choose -- option has no data-name at all, so
typeName is undefined, and a lookup on undefined
correctly misses every key in the object. Without the ?? fallback, the label
would read the literal text "undefined:" until a real type is picked — a small but
genuinely confusing bug if it isn't guarded against.
This Is Cosmetic, Not Validation
Relabeling a text input doesn't change what can actually be typed into it — nothing stops someone from selecting "book" and then typing "Region 2" into what's now labeled "Binding" anyway. This chapter's own JavaScript is a genuine usability improvement, not a data-integrity mechanism, and it must never be treated as one.
add_item.php with a tool like curl, bypassing the form
(and its labels) entirely. Every real validation rule — "Title is required," "please
choose an item type" — must stay enforced in the PHP that actually runs the
INSERT/UPDATE, exactly as Chapter 3 already does it, regardless
of what the browser's own UI happens to show.
A Small, Genuinely Type-Specific Validation Rule
One place type does matter server-side: release_year. A book or CD's real
release year is reasonably bounded — nothing published before, say, 1400 belongs in this
catalogue — but the exact sensible range differs slightly by type in a way that's not
worth over-engineering. A single, deliberately loose sanity check catches genuine typos
(a four-digit year with a stray extra digit, or an obviously impossible future date)
without needing a separate rule per item type:
The + 1 allows for an item releasing next calendar year (a pre-order),
while still catching an obvious typo like 29026.
Hands-On Exercises
Add the data-name attributes, the two label elements, and the JavaScript from this chapter to your own add_item.php. Confirm switching the dropdown between "book," "cd," and "dvd" correctly updates both labels without a page reload.
Add the same label-switching script to edit_item.php, and confirm that opening the edit form for an existing DVD shows "Director" and "Region code" correctly pre-labeled on page load, before any dropdown change happens.
Add the release_year sanity check from this chapter to add_item.php's own validation, then confirm submitting a year of 29026 is correctly rejected with an error message, while 2027 (next year) is correctly accepted.
Chapter 4 Quick Reference
- One shared form — labels change per type via JavaScript; database columns and field names stay the same
- Label maps — built server-side with
json_encode()so they can never drift from the realitem_typesdata data-name— each option carries the real type name, since the label maps are keyed by name, not by numeric id- Cosmetic vs. validation — relabeling never replaces server-side checks; every real rule still lives in the PHP that runs the query
release_yearsanity check — one loose, shared range rule rather than four separate per-type rules- Next chapter: Tags — attaching, managing, and filtering by tag on books