Form adalah percakapan: halaman bertanya, pengunjung menjawab. Bayangin resepsionis homestay yang mencatat data tamu. Resepsionis yang baik bertanya satu per satu dengan pertanyaan yang jelas, gak menanyakan hal yang gak perlu, menunggu tamu selesai bicara, dan kalau nomornya kurang satu angka, dia bilang bagian mana yang kurang dan cara membetulkannya. Dia gak memotong di tengah kalimat dengan "salah!".
🧪 Tebakan cepat: Pak Hadi mengetik nomor WhatsApp-nya di form pesan Bu Sri:
0812-3456-7890. Begitu dia menekan angka 0 yang pertama, kolomnya langsung merah dengan tulisan "Input tidak valid". Ada dua kesalahan di situ. Apa saja? Jawabannya ada di bagian "Validasi: kapan muncul, apa isinya".
Minta yang perlu saja
Tanggal dan jumlah malam sudah dipilih di kartu kamar. Untuk memesan, Bu Sri cuma butuh tiga hal:
| Kolom | Kenapa perlu | Wajib? |
|---|---|---|
| Nama lengkap | supaya Bu Sri tahu siapa yang datang | ya |
| Nomor WhatsApp | konfirmasi dan arah jalan dikirim lewat WhatsApp | ya |
| bukti pesanan, kalau tamu mau | opsional, ditulis "(opsional)" |
Tiap kolom tambahan adalah satu pertanyaan lagi yang bisa membuat orang berhenti. Kalau sebuah form terpaksa panjang, misalnya formulir pendaftaran dengan 12 kolom, periksa dulu tiap kolom: perlu sekarang, atau bisa ditanyakan nanti? Lalu pecah jadi beberapa langkah, dan langkah pertama cuma berisi yang benar-benar wajib.
Label di atas, satu kolom
- Label di atas kolomnya. Di HP gak ada tempat di samping. Studi eye-tracking Matteo Penzo (2006) mencatat mata pindah dari label di atas ke kolomnya dalam sekitar 50 ms, sedangkan dari label rata kiri di samping kolom sekitar 500 ms.
- Satu kolom ke bawah. Mata bergerak lurus dari atas ke bawah. Dua kolom berdampingan membuat mata zigzag, dan kolom di kanan gampang terlewat.
- Placeholder bukan label. Placeholder hilang begitu tamu mulai mengetik, dan warnanya biasanya abu muda seperti
#9CA3AF(2,54:1, gagal kontras). Pakai placeholder cuma untuk contoh, atau tulis contohnya sebagai teks bantuan di bawah kolom.
Label dihubungkan ke kolomnya lewat for yang sama persis dengan id kolom. Hubungan ini yang membuat klik di label memindahkan fokus ke kolom, dan pembaca layar menyebut "Nomor WhatsApp" saat kolomnya difokus.
Di latihan nanti, form-nya punya input id="name" dan id="email" tanpa label. Tambahkan <label for="name">Nama</label> dan <label for="email">Email</label>, ubah input email jadi type="email", dan beri required di kedua input.
Tipe input dan autocomplete
<form class="booking" novalidate>
<label for="nama">Nama lengkap</label>
<input id="nama" name="nama" type="text" autocomplete="name" required>
<label for="wa">Nomor WhatsApp</label>
<input id="wa" name="wa" type="tel" autocomplete="tel" required aria-describedby="wa-help wa-error">
<p id="wa-help" class="help">Contoh: 0812 3456 7890 atau +62 812 3456 7890</p>
<p id="wa-error" class="error" hidden></p>
<label for="email">Email (opsional)</label>
<input id="email" name="email" type="email" autocomplete="email">
<button type="submit">Pesan kamar, bayar di tempat</button>
</form>
type="tel"memunculkan papan angka telepon di HP.type="email"memunculkan papan dengan tombol @, dan browser ikut mengecek ada tanda @ atau gak.autocomplete="name","tel","email"memberi tahu browser isi kolomnya, jadi data yang tersimpan di HP tamu bisa diisi dengan satu ketukan. Untuk kolom tentang diri pengguna, ini diminta WCAG 1.3.5 (Identify Input Purpose).requiredmenandai kolom wajib.novalidatedi<form>mematikan pesan bawaan browser, karena pesannya kita tulis sendiri.aria-describedbymenyambungkan contoh dan pesan error ke kolomnya, jadi pembaca layar ikut membacakannya.- Jangan pakai
type="number"untuk nomor HP. Di uji kami, Chromium dan WebKit diam-diam membuang spasi dan tanda + saat diketik, Firefox mengosongkan nilainya, dan sebagai angka, 0 di depan hilang:81234567890. type="tel"sendiri gak mengecek apa-apa: "abc" pun dianggap valid. Pengecekan formatnya tugas kita.
Validasi: kapan muncul, apa isinya
Kapan. Luke Wroblewski menguji 22 orang di 2009: form dengan validasi langsung di tiap kolom menaikkan tingkat berhasil 22%, menurunkan kesalahan 22%, dan mempercepat pengisian 42% dibanding form yang baru mengecek setelah dikirim. Waktu terbaiknya setelah tamu meninggalkan kolom (on blur). Pesan yang muncul sejak huruf pertama membuat orang kesal ("belum selesai ngetik sudah merah"), dan pesan yang baru muncul setelah tombol kirim ditekan memaksa tamu mencari ke atas lagi.
Apa isinya. Pesan error harus bilang apa yang salah dan cara membetulkannya (WCAG 3.3.1 dan 3.3.3), dalam teks, bukan cuma warna. Nomor WhatsApp diterima dalam bentuk 08... dan +62 8...:
function phoneProblem(raw) {
const value = raw.trim();
if (value === "") return "Isi nomor WhatsApp, supaya Bu Sri bisa mengirim konfirmasi.";
if (!/^\+?[0-9\s.\-]+$/.test(value)) return "Nomor cuma boleh berisi angka, spasi, titik, tanda hubung, dan + di depan.";
let digits = value.replace(/\D/g, ""); // buang spasi, titik, tanda hubung, dan +
if (digits.startsWith("620")) return "Setelah +62, angka 0 dihapus: tulis +62 812 3456 7890.";
if (digits.startsWith("62")) digits = "0" + digits.slice(2); // 62812... jadi 0812...
if (!digits.startsWith("08")) return "Nomor HP diawali 08 atau +62 8, contohnya 0812 3456 7890.";
if (digits.length < 10 || digits.length > 13) return `Nomor ini ${digits.length} digit. Nomor HP diawali 08 dan panjangnya 10 sampai 13 digit.`;
return ""; // kosong artinya gak ada masalah
}
const wa = document.querySelector("#wa");
const error = document.querySelector("#wa-error");
function check() {
const problem = phoneProblem(wa.value);
error.textContent = problem;
error.hidden = problem === "";
wa.setAttribute("aria-invalid", problem === "" ? "false" : "true");
}
wa.addEventListener("blur", check); // pertama kali: setelah keluar kolom
wa.addEventListener("input", () => { if (!error.hidden) check(); }); // setelah error tampil: cek tiap ketikan
| Diketik Pak Hadi | Hasil |
|---|---|
0812-3456-7890 |
diterima, 12 digit |
+62 812 3456 7890 |
diterima, jadi 0812... |
0812 345 |
"Nomor ini 7 digit. Nomor HP diawali 08 dan panjangnya 10 sampai 13 digit." |
+62 0812 3456 7890 |
"Setelah +62, angka 0 dihapus: tulis +62 812 3456 7890." |
021 5551234 |
"Nomor HP diawali 08 atau +62 8, contohnya 0812 3456 7890." |
blurterjadi saat fokus meninggalkan kolom. Error pertama muncul di situ.- Setelah error tampil,
inputmengecek ulang di tiap ketikan, jadi pesannya hilang begitu nomornya benar. Tamu langsung tahu perbaikannya berhasil. - Tampilkan errornya dengan merah
#b91c1c(6,47:1) ditambah ikon dan teks.
Jadi jawaban tebakannya: pesannya muncul terlalu cepat (sebelum Pak Hadi selesai mengetik, padahal nomornya benar), dan isinya gak membantu ("Input tidak valid" gak bilang cara membetulkannya). Itu jawaban tebakannya.
⚠️ Jebakan yang sering ketemu
- Placeholder sebagai label. Hilang saat mengetik, dan kontrasnya rendah. Pakai
<label for>yang menunjukidkolom. fordanidyang gak sama.for="mail"denganid="email": hubungannya putus tanpa pesan error apa pun. Latihan mengecek tiapformenunjukidyang benar-benar ada.type="text"untuk email dan nomor HP. Papan ketik di HP jadi huruf biasa. Pakaitype="email"dantype="tel".- Error sejak huruf pertama, atau baru setelah kirim. Tampilkan setelah keluar kolom, lalu hilangkan begitu sudah benar.
- "Input tidak valid". Sebutkan masalahnya dan contoh yang benar.
TL;DR: Minta yang perlu saja; form panjang dipecah jadi beberapa langkah dengan yang wajib di langkah pertama. Satu kolom, label di atas (<label for> sama persis dengan id kolomnya), placeholder bukan label. Pakai type="tel", type="email", dan autocomplete (name, tel, email, WCAG 1.3.5); jangan type="number" untuk nomor HP. Tandai kolom wajib dengan required. Validasi muncul setelah tamu meninggalkan kolom (on blur), lalu dicek ulang tiap ketikan sampai benar; pesannya bilang apa yang salah dan cara membetulkannya (WCAG 3.3.1, 3.3.3), dengan teks dan ikon, bukan cuma merah. Nomor WhatsApp diterima sebagai 08... atau +62 8..., 10 sampai 13 digit.