Elemen form, atribut validasi, dan label yang ramah pembaca layar sudah kita kenal satu per satu di Section Forms, Form Validation, dan Accessibility. Kini saatnya merangkai semuanya menjadi satu halaman yang memakai ketiganya sekaligus: survei kepuasan pelanggan untuk warung masakan rumahan fiktif Dapur Siti. Satu berkas index.html memuat tiga kelompok pertanyaan — identitas responden, kebiasaan berkunjung, dan umpan balik bebas — dengan lima belas kontrol yang seluruhnya berlabel.
Proyek ini melatih keterampilan yang jarang terlatih lewat potongan kecil: mengirim data dengan method yang tepat, menimbang radio lawan checkbox lawan select untuk tiap pertanyaan, menahan pengiriman lewat required, min/max, dan minlength tanpa satu baris JavaScript, serta menjaga urutan fokus keyboard tetap logis dari kolom pertama sampai tombol kirim — rangkuman pola dari chapter Membuat Form Lengkap dan Label dan Instruksi Form.
Perilaku yang Diharapkan #
Sebelum menulis kode, mari kita tetapkan dulu hasil akhirnya. Halaman yang selesai menampilkan:
- header ringkas: nama warung, tujuan survei, dan estimasi waktu 5 menit,
- judul dan pengantar survei, dengan catatan privasi kecil di bawah form,
- form dengan tiga kelompok: Identitas (nama, email, usia), Kebiasaan berkunjung (frekuensi berkunjung, menu favorit, sumber informasi), dan Umpan balik (saran bebas, persetujuan dihubungi),
- tombol Kirim Survei di ujung form.
Perilaku khasnya berbeda dari proyek-proyek sebelumnya yang hanya menampilkan isi. Tekan Kirim Survei saat form masih kosong — browser menahan pengiriman, memfokuskan kolom pertama yang bermasalah, dan menampilkan pesan bawaan. Isi seluruh kolom dengan sah — data terkirim ke alamat action yang dituju. Untuk melihat semuanya, cukup buka berkas index.html di browser: tanpa server, tanpa alat tambahan, tanpa folder assets/ — proyek ini murni satu berkas.
Tahapan Pengerjaan #
Proyek dikerjakan dalam lima bagian berurutan. Setiap bagian menghasilkan halaman yang tetap bisa diperiksa di browser:
- Struktur form — menyusun kerangka:
headlengkap,headerberisi estimasi waktu,formdenganactiondanmethod="post", serta tigafieldsetkosong siap diisi. - Identitas responden — mengisi kelompok pertama: nama, email, dan usia dengan
autocompleteserta rentangmin/max. - Pertanyaan dan pilihan — mengisi kelompok kedua: radio frekuensi berkunjung, checkbox menu favorit, dan
selectber-optgroup. - Validasi input — mengisi kelompok ketiga sekaligus meninjau atribut validasi seluruh form, menguji tiga skenario galat, dan mengenal kapan
formnovalidatedibutuhkan. - Aksesibilitas form — meninjau label,
fieldset, urutan fokus, dan pesan galat dari sisi pengguna keyboard serta pembaca layar.
Mulailah dari Bagian 1 dan ikuti urutannya karena setiap bagian dibangun di atas struktur bagian sebelumnya.
Kode Sumber Lengkap #
Berkas index.html berikut memuat keseluruhan hasil lima bagian di atas — 97 baris, tiga fieldset, lima belas kontrol berlabel. Gunakan tombol unduh pada header code block untuk menyimpannya, lalu buka langsung di browser:
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Survei Kepuasan — Dapur Siti</title>
<meta name="description" content="Survei kepuasan pelanggan Dapur Siti: lima menit untuk menceritakan kunjungan Anda, dari frekuensi berkunjung sampai saran perbaikan.">
</head>
<body>
<header>
<p><strong>Dapur Siti</strong> — warung masakan rumahan</p>
<p><small>Survei kepuasan pelanggan, kurang lebih 5 menit</small></p>
</header>
<main>
<h1>Survei Kepuasan Pelanggan</h1>
<p>Terima kasih sudah makan di Dapur Siti. Lima menit waktu Anda membantu kami menentukan menu pekan depan dan memperbaiki layanan. Sebagian kolom wajib diisi; browser akan menandai kolom yang terlewat saat tombol kirim ditekan.</p>
<form action="https://example.com/survei" method="post">
<fieldset>
<legend>Identitas</legend>
<label for="nama">Nama lengkap</label>
<input type="text" id="nama" name="nama" required autocomplete="name">
<label for="email">Alamat email</label>
<input type="email" id="email" name="email" required autocomplete="email">
<label for="usia">Usia (tahun)</label>
<input type="number" id="usia" name="usia" min="13" max="100" required>
</fieldset>
<fieldset>
<legend>Kebiasaan berkunjung</legend>
<p>Berapa sering Anda makan di Dapur Siti?</p>
<label>
<input type="radio" name="frekuensi" value="setiap-pekan" required>
Hampir setiap pekan
</label>
<label>
<input type="radio" name="frekuensi" value="beberapa-sebulan">
Dua sampai tiga kali sebulan
</label>
<label>
<input type="radio" name="frekuensi" value="sebulan-sekali">
Sekali sebulan atau lebih jarang
</label>
<label>
<input type="radio" name="frekuensi" value="pertama-kali">
Ini kunjungan pertama saya
</label>
<p>Menu mana yang paling Anda sukai? Boleh memilih lebih dari satu.</p>
<label>
<input type="checkbox" name="menu[]" value="nasi-goreng">
Nasi goreng kampung
</label>
<label>
<input type="checkbox" name="menu[]" value="ayam-bakar">
Ayam bakar madu
</label>
<label>
<input type="checkbox" name="menu[]" value="sayur-asem">
Sayur asem
</label>
<label>
<input type="checkbox" name="menu[]" value="gulai-patin">
Gulai ikan patin
</label>
<label>
<input type="checkbox" name="menu[]" value="pisang-goreng">
Pisang goreng keju
</label>
<label for="sumber">Dari mana Anda pertama kali mendengar Dapur Siti?</label>
<select id="sumber" name="sumber">
<option value="" disabled selected>Pilih salah satu</option>
<optgroup label="Dari orang sekitar">
<option value="teman">Rekomendasi teman</option>
<option value="keluarga">Rekomendasi keluarga</option>
<option value="rekan-kerja">Ajakan rekan kerja</option>
</optgroup>
<optgroup label="Dari internet">
<option value="media-sosial">Media sosial Dapur Siti</option>
<option value="ulasan-daring">Ulasan daring</option>
<option value="mesin-pencari">Mesin pencari</option>
</optgroup>
</select>
</fieldset>
<fieldset>
<legend>Umpan balik</legend>
<label for="saran">Saran dan kesan Anda</label>
<textarea id="saran" name="saran" rows="5" minlength="20" maxlength="500"></textarea>
<label>
<input type="checkbox" name="dihubungi" value="ya">
Saya bersedia dihubungi untuk tindak lanjut survei ini
</label>
<input type="hidden" name="versi" value="1.0">
</fieldset>
<button type="submit">Kirim Survei</button>
</form>
<p><small>Data survei hanya dipakai untuk memperbaiki layanan Dapur Siti, tidak dibagikan ke pihak lain, dan tidak dipakai untuk kiriman promosi.</small></p>
</main>
</body>
</html>Hasil yang dijanjikan bagian Perilaku yang Diharapkan bisa dicoba langsung di sini — dan perilakunya memang berbeda dari proyek-proyek sebelumnya. Kirim kosong dan lihat penahannya: tekan tombol Kirim Survei tanpa mengisi satu kolom pun, browser menahan pengiriman, memfokuskan kolom Nama lengkap, lalu menampilkan pesan bawaannya. Perbaiki kolom itu dan tekan lagi — penahan berikutnya menunggu di kolom sesudahnya:
Submit sah pada demo berpindah di dalam iframe: data terkirim ke https://example.com/survei, lalu iframe dikosongkan karena domain contoh menolak ditampilkan di dalam frame — muat ulang halaman ini untuk mengulang demonya. Pada berkas tersimpan yang dibuka langsung, respons domain contoh tampil penuh di jendela browser.
Peta besar berkasnya terbaca dari tiga fieldset-nya. Mari kita bedah per blok:
- Blok
head(baris 1-8): doctype,lang="id", charset, viewport,title, danmeta description— pola metadata yang sama dengan proyek-proyek sebelumnya. - Blok
header(baris 10-13): nama warung dan jenis usaha dalam satu paragraf; baris kedua menyebut tujuan survei beserta estimasi waktunya. - Blok pembuka
main(baris 14-16): satuh1dan paragraf pengantar yang menyebut durasi serta kolom wajib — instruksi sebelum pengguna mengisi apa pun. - Blok
formdan fieldset Identitas (baris 17-26):actionfiktif denganmethod="post", lalu tiga kontrol identitas berlabelfor/id,required, danautocomplete. - Blok fieldset Kebiasaan berkunjung (baris 27-81): tiga jenis pilihan — empat radio segrup
name="frekuensi", lima checkboxname="menu[]", danselectber-optgroupdengan opsi placeholder. - Blok fieldset Umpan balik dan tombol (baris 82-92):
textareaberbatas panjang, checkbox persetujuan,inputtersembunyiversi, ditutupbutton type="submit". - Blok catatan privasi dan penutup (baris 93-97): penutup
form, paragraf kecil di bawahnya, lalu penutupmain,body, danhtml.
Lima bagian berikut membedah berkas ini tahap demi tahap. Setiap part menampilkan potongan yang identik dengan bagiannya pada berkas di atas, sehingga hasil mengetik ulang kita bisa diperiksa baris demi baris.
Siapkan elemen form, action, dan kerangka fieldset survei.
Buka → # Identitas RespondenBangun bagian identitas: nama, email, dan usia dengan label yang benar.
Buka → # Pertanyaan dan PilihanSusun pertanyaan survei memakai radio, checkbox, dan textarea.
Buka → # Validasi InputTerapkan required, pattern, dan batasan nilai pada seluruh masukan.
Buka → # Aksesibilitas FormPastikan form ramah keyboard dan pembaca layar dari awal.
Buka →