Formulir tanpa aturan isian akan terus mengirim data yang tidak lengkap, lalu membebani server untuk memeriksa ulang semuanya. HTML native menyediakan lapisan pemeriksaan pertama yang berjalan sebelum data meninggalkan browser: kita menuliskan aturan sebagai atribut pada tiap kontrol, dan browser menegakkannya secara otomatis lengkap dengan pesan kesalahan miliknya. Bagian kedua proyek ini menambahkan atribut validasi pada struktur dari Bagian 1, tanpa mengubah satu pun label maupun kelompoknya.
Pemetaan Atribut per Kolom #
Sebelum membaca filenya, perhatikan aturan yang kita tetapkan untuk setiap isian:
| Kolom | Atribut | Aturan yang ditegakkan |
|---|---|---|
| Nama lengkap | required, minlength="3", maxlength="40", pattern="[A-Za-z .]+" | Wajib, 3-40 karakter, hanya huruf spasi dan titik |
| Tanggal lahir | required, min, max | Wajib, lahir antara 1950 dan 2010 |
| Kota domisili | required | Salah satu opsi harus dipilih |
| Kategori peserta | required pada radio pertama | Satu grup harus dipilih |
required + type="email" | Wajib dan berformat email | |
| Kata sandi | required, minlength="8" | Wajib, minimal 8 karakter |
| Persetujuan | required | Checkbox harus dicentang |
Dua catatan dari tabel di atas. Pertama, atribut required pada satu radio saja cukup untuk mewajibkan seluruh grup name="kategori" — validasi radio dinilai per grup, bukan per tombol. Kedua, maxlength mencegah ketikan berlebih sejak ketukan pertama, sedangkan minlength baru diperiksa saat pengiriman; keduanya melengkapi, bukan menggantikan.
File formulir-validasi.html #
Simpan file berikut sebagai formulir-validasi.html di folder bagian-2/:
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pendaftaran Seminar Web Komunitas</title>
</head>
<body>
<main>
<h1>Pendaftaran Seminar Web Komunitas</h1>
<p><img src="../assets/logo-acara.svg" alt="Logo Seminar Web Komunitas" width="96" height="96"></p>
<p>Isi formulir berikut untuk mengikuti acara pada Sabtu, 8 Maret 2025, di Gedung Belajar Kota.</p>
<form action="www.example.com/daftar" method="post">
<fieldset>
<legend>Data diri</legend>
<p>
<label for="nama">Nama lengkap</label>
<input type="text" id="nama" name="nama" autocomplete="name" required minlength="3" maxlength="40" pattern="[A-Za-z .]+" title="Hanya huruf, spasi, dan titik">
</p>
<p>
<label for="tanggal-lahir">Tanggal lahir</label>
<input type="date" id="tanggal-lahir" name="tanggal-lahir" autocomplete="bday" required min="1950-01-01" max="2010-12-31">
</p>
<p>
<label for="kota">Kota domisili</label>
<select id="kota" name="kota" autocomplete="address-level2" required>
<option value="">-- Pilih kota --</option>
<option value="bandung">Bandung</option>
<option value="jakarta">Jakarta</option>
<option value="surabaya">Surabaya</option>
<option value="yogyakarta">Yogyakarta</option>
</select>
</p>
</fieldset>
<fieldset>
<legend>Kategori peserta</legend>
<p>
<input type="radio" id="kategori-pelajar" name="kategori" value="pelajar" required>
<label for="kategori-pelajar">Pelajar</label>
</p>
<p>
<input type="radio" id="kategori-mahasiswa" name="kategori" value="mahasiswa">
<label for="kategori-mahasiswa">Mahasiswa</label>
</p>
<p>
<input type="radio" id="kategori-profesional" name="kategori" value="profesional">
<label for="kategori-profesional">Profesional</label>
</p>
</fieldset>
<fieldset>
<legend>Akun</legend>
<p>
<label for="email">Email</label>
<input type="email" id="email" name="email" autocomplete="email" required>
</p>
<p>
<label for="kata-sandi">Kata sandi</label>
<input type="password" id="kata-sandi" name="kata-sandi" autocomplete="new-password" required minlength="8">
</p>
</fieldset>
<p>
<input type="checkbox" id="persetujuan" name="persetujuan" value="setuju" required>
<label for="persetujuan">Saya menyetujui penggunaan data untuk keperluan acara ini</label>
</p>
<button type="submit">Kirim pendaftaran</button>
</form>
</main>
</body>
</html>Output yang Dihasilkan:
Saat tombol "Kirim pendaftaran" ditekan dengan kolom kosong:
- Browser menampilkan gelembung pesan pada kolom pertama yang tidak sah,
misalnya "Please fill out this field" (kalimat mengikuti bahasa browser)
- Data tidak dikirim dan halaman tetap terbuka
Saat nama diisi "Bu" lalu tombol ditekan:
- Gelembung pesan menyatakan isian terlalu pendek
Saat seluruh isian sah:
- Browser mengirim data ke alamat action dan berpindah sesuai responsnyaMari kita bedah atribut-atribut barunya:
required: kolom wajib. Bila kosong saat submit, browser memblokir pengiriman, memfokuskan kolom tersebut, dan menampilkan gelembung pesan bawaan.minlengthdanmaxlength: batas panjang karakter untuk kontrol teks. Pada kata sandi,minlength="8"menuntut minimal delapan karakter sebelum isian dianggap sah.pattern: aturan pola dengan ekspresi reguler. Nilai[A-Za-z .]+menerima huruf besar-kecil, spasi, dan titik; atributtitleyang menyertainya dijadikan teks saran browser ketika pola tidak terpenuhi.mindanmaxpadatype="date": rentang tanggal yang diterima. Isian di luar rentang — misalnya tahun 2030 — mendapat pesan kesalahan tanpa satu baris JavaScript pun.autocomplete: token yang menjelaskan maksud kolom bagi browser. Tokennamedanemailmemungkinkan pengisian otomatis dari data profil;new-passwordmenyatakan kolom ini untuk kata sandi baru sehingga pengelola sandi bisa menawarkannya;bdaydanaddress-level2menyatakan tanggal lahir serta kota. Bagian ini juga kenyamanan aksesibilitas: banyak pembaca layar membaca maksud kolom dari token ini.type="email": selain menampilkan keyboard khusus di perangkat sentuh, jenis ini memicu pemeriksaan format — isian tanpa tanda@ditolak.
Pemeriksaan native berjalan pada momen submit: browser menandai kontrol tidak sah satu per satu, menghentikan pengiriman pada yang pertama, dan tidak membuat permintaan jaringan sama sekali. Atribut novalidate yang terpasang pada elemen form mematikan perilaku ini seluruhnya — kita belum memakainya di sini, tetapi Bagian 4 memasangnya saat JavaScript mengambil alih penyajian pesan.
Langkah Pemeriksaan #
Tuntaskan Bagian ini dengan urutan berikut:
- Buka
formulir-validasi.htmldi browser, tekan tombol kirim dengan formulir kosong, dan amati gelembung pesan pada kolom nama. Isi nama dengan “Bu”, tekan kirim lagi, dan amati pesan panjang minimal. - Uji pola nama dengan mengisi angka, lalu uji tanggal lahir di luar rentang (misalnya 2030-01-01) untuk melihat pesan rentang.
- Jalankan
../tests/cek-struktur.htmldan centang seluruh butir kelompok Validasi atribut.
Seluruh aturan kini bertumpu pada pesan bawaan browser yang kalimat dan posisinya di luar kendali kita. Bagian 3 memberi formulir pakaian yang rapi, sebelum Bagian 4 mengambil alih pesan kesalahan dengan JavaScript.
Referensi resmi untuk pendalaman:
- MDN Web Docs — Validasi constraint HTML
- MDN Web Docs — Elemen input
- MDN Web Docs — Atribut autocomplete
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
formulir-validasi.html
Unduh berkas<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pendaftaran Seminar Web Komunitas</title>
</head>
<body>
<main>
<h1>Pendaftaran Seminar Web Komunitas</h1>
<p><img src="../assets/logo-acara.svg" alt="Logo Seminar Web Komunitas" width="96" height="96"></p>
<p>Isi formulir berikut untuk mengikuti acara pada Sabtu, 8 Maret 2025, di Gedung Belajar Kota.</p>
<form action="www.example.com/daftar" method="post">
<fieldset>
<legend>Data diri</legend>
<p>
<label for="nama">Nama lengkap</label>
<input type="text" id="nama" name="nama" autocomplete="name" required minlength="3" maxlength="40" pattern="[A-Za-z .]+" title="Hanya huruf, spasi, dan titik">
</p>
<p>
<label for="tanggal-lahir">Tanggal lahir</label>
<input type="date" id="tanggal-lahir" name="tanggal-lahir" autocomplete="bday" required min="1950-01-01" max="2010-12-31">
</p>
<p>
<label for="kota">Kota domisili</label>
<select id="kota" name="kota" autocomplete="address-level2" required>
<option value="">-- Pilih kota --</option>
<option value="bandung">Bandung</option>
<option value="jakarta">Jakarta</option>
<option value="surabaya">Surabaya</option>
<option value="yogyakarta">Yogyakarta</option>
</select>
</p>
</fieldset>
<fieldset>
<legend>Kategori peserta</legend>
<p>
<input type="radio" id="kategori-pelajar" name="kategori" value="pelajar" required>
<label for="kategori-pelajar">Pelajar</label>
</p>
<p>
<input type="radio" id="kategori-mahasiswa" name="kategori" value="mahasiswa">
<label for="kategori-mahasiswa">Mahasiswa</label>
</p>
<p>
<input type="radio" id="kategori-profesional" name="kategori" value="profesional">
<label for="kategori-profesional">Profesional</label>
</p>
</fieldset>
<fieldset>
<legend>Akun</legend>
<p>
<label for="email">Email</label>
<input type="email" id="email" name="email" autocomplete="email" required>
</p>
<p>
<label for="kata-sandi">Kata sandi</label>
<input type="password" id="kata-sandi" name="kata-sandi" autocomplete="new-password" required minlength="8">
</p>
</fieldset>
<p>
<input type="checkbox" id="persetujuan" name="persetujuan" value="setuju" required>
<label for="persetujuan">Saya menyetujui penggunaan data untuk keperluan acara ini</label>
</p>
<button type="submit">Kirim pendaftaran</button>
</form>
</main>
</body>
</html>