DOM: Menangani Form
Siklus lengkap form modern: membaca nilai input/checkbox/radio, submit tanpa reload dengan preventDefault, validasi bertahap (HTML bawaan + JS khusus), menampilkan pesan error, dan reset form.
Kenapa Form Butuh Penanganan Khusus?
Form adalah jembatan utama data user masuk ke aplikasi: pendaftaran, login, checkout, komentar. Secara default, browser mengirim form dengan me-RELOAD halaman, cara kuno yang menghancurkan semua state JavaScript. Aplikasi modern mencegat proses itu: baca nilainya dengan JS, validasi dulu, lalu kirim via fetch tanpa reload. Modul ini mengajarkan seluruh siklusnya.
Membaca Nilai dari Berbagai Input
Setiap jenis input dibaca dengan cara sedikit berbeda:
const nama = document.getElementById("nama").value; // teks: string
const umur = Number(document.getElementById("umur").value); // angka: konversi!
const setuju = document.getElementById("setuju").checked; // checkbox: boolean
const area = document.getElementById("alamat").value; // textarea: .value juga
// radio: cari yang sedang terpilih (bisa null kalau belum ada yang dipilih!)
const jk = document.querySelector('input[name="jk"]:checked');
console.log(jk ? jk.value : "belum dipilih");
// select multiple: kumpulkan semua yang terpilih
const hobi = [...document.getElementById("hobi").selectedOptions]
.map(o => o.value);Contoh sederhana memakai playground modul ini (ada <form id="form"> dengan input nama):
const form = document.getElementById("form");
form.addEventListener("submit", (e) => {
e.preventDefault();
const nama = document.getElementById("nama").value.trim();
document.getElementById("pesan").textContent =
nama.length < 3 ? "Nama terlalu pendek!" : "Halo, " + nama;
});.trim() hampir selalu dipakai untuk input teks agar spasi di ujung tidak lolos validasi.
Submit Tanpa Reload
form.addEventListener("submit", (e) => {
e.preventDefault(); // WAJIB: batalkan reload bawaan browser
const nama = document.getElementById("nama").value.trim();
if (nama.length < 3) {
tampilkanError("Nama minimal 3 karakter");
return; // berhenti, jangan lanjut kirim
}
kirimKeServer({ nama }); // fetch() di modul berikutnya
form.reset(); // kembalikan ke kondisi awal
});Pasang listener di event submit milik <form>, bukan click milik tombol. Kenapa? Karena user bisa men-submit dengan menekan Enter di dalam input, dan itu tidak memicu klik tombol. Listener submit menangkap SEMUA cara pengiriman.
Validasi Bertahap: HTML + JS
Jangan tulis semua validasi dengan JS dari nol. HTML punya validasi bawaan yang gratis dan accessible:
<input type="email" required minlength="3" maxlength="50">
<input type="number" min="1" max="100">Strategi berlapis yang dipakai aplikasi nyata:
- HTML menangani yang dasar: wajib isi, format email, panjang min/maks. Browser menampilkan pesan otomatis.
- JS menangani aturan khusus: "password dan konfirmasi harus sama", "username belum dipakai" (cek ke server).
Contoh realistis: validasi konfirmasi password plus pesan error custom.
const form = document.getElementById("form");
const pass = document.getElementById("pass");
const konfirmasi = document.getElementById("konfirmasi");
const pesan = document.getElementById("pesan");
form.addEventListener("submit", (e) => {
e.preventDefault();
pesan.textContent = "";
pesan.className = "";
if (pass.value.length < 8) {
pesan.textContent = "Password minimal 8 karakter";
pesan.classList.add("error");
pass.focus(); // arahkan kursor ke field bermasalah, UX yang baik
return;
}
if (pass.value !== konfirmasi.value) {
pesan.textContent = "Konfirmasi password tidak sama";
pesan.classList.add("error");
konfirmasi.focus();
return;
}
pesan.textContent = "Pendaftaran berhasil!";
pesan.classList.add("ok");
form.reset();
});Pola "kumpulkan error, tampilkan satu per satu, fokuskan field bermasalah" adalah standar UX form yang baik.
Jebakan Umum
- Validasi HANYA di JavaScript lalu mengira data aman. User bisa membuka console dan mem-bypass semuanya. Validasi JS itu untuk UX (umpan balik instan); keamanan WAJIB diulang di server.
- Lupa
e.preventDefault(): halaman reload, data yang diketik hilang, dan kamu bingung kenapa "kode tidak jalan". - Membaca
.valuecheckbox (me-return "on") padahal butuh.checked(boolean). form.reset()mengembalikan ke nilai DEFAULT (atributvaluedi HTML), bukan mengosongkan total. Untuk kosong total, set manual tiap input.- Tidak menangani kasus radio belum dipilih:
querySelector('input[name="jk"]:checked')bisa null, pakai optional chaining?.value.
Ringkasan
Siklus form modern: cegah reload dengan e.preventDefault() di listener submit, baca nilai (.value untuk teks, .checked untuk checkbox, radio via :checked), validasi berlapis (HTML untuk dasar, JS untuk aturan khusus), tampilkan pesan error yang jelas dan fokuskan field bermasalah, lalu form.reset() setelah sukses. Dan ingat: validasi browser hanya untuk kenyamanan, validasi server yang menjaga keamanan.
export default function App(): JSX.Element { return <h1>Hello world</h1> }
Tantangan
Form Pendaftaran
Di form yang ada, tambahkan validasi: nama tidak boleh kosong dan email harus mengandung "@". Tampilkan pesan error/sukses di #pesan. Reset form jika sukses. Validasi form adalah gerbang setiap alur pendaftaran, login, dan checkout di aplikasi nyata: pesan error yang jelas menentukan apakah user jadi mendaftar atau pergi.
<!doctype html> <html> <head> <meta charset="utf-8" /> </head> <body> <h1>Halo JS</h1> <p>Buka console preview untuk melihat output.</p> <script src="index.js"></script> </body> </html>