Form mengumpulkan masukan pengguna, dan JavaScript mengambil alih penanganannya lewat event submit yang dipancarkan elemen <form> ketika tombol kirim ditekan. Topik ini membaca nilai setiap isian dari properti value, menghentikan pemuatan ulang halaman dengan preventDefault(), lalu memeriksa isi form secara manual dan menampilkan pesan error langsung di halaman. Pemeriksaan bawaan browser lewat atribut required dan properti validitas juga disinggung sebagai pelengkap pembahasan.
Event submit dan preventDefault#
Event submit dipancarkan oleh <form>, bukan oleh tombolnya, sehingga listener dipasang pada elemen form dan tombol cukup bertipe submit. Secara bawaan, pengiriman form membuat browser mengirim data dan memuat ulang halaman, kebiasaan yang menghapus seluruh hasil kerja JavaScript. Metode event.preventDefault() di awal handler membatalkan aksi bawaan itu, sehingga halaman tetap hidup dan data dapat diperiksa lebih dahulu.
// tidak-dijalankan
const form = document.querySelector("#form-daftar");
form.addEventListener("submit", (event) => {
event.preventDefault();
console.log("Form diperiksa, halaman tidak dimuat ulang");
});Pola kerjanya selalu berurutan, yaitu tangkap event, batalkan perilaku bawaan, baca nilai isian, lalu putuskan tindak lanjutnya. Selama handler berjalan, event.target menunjuk form yang dikirim, sehingga isian di dalamnya juga dapat dicari lewat querySelector dari form itu. Semua langkah berjalan di browser tanpa pengiriman ke mana pun, sehingga umpan baliknya terasa seketika bagi pengguna.
Membaca nilai isian dengan value#
Setiap elemen isian menyimpan datanya di properti value, dan isian teks mengembalikan string apa pun yang diketik pengguna, termasuk yang tampak kosong berupa string "". Nilai itu dibaca dengan memilih elemennya terlebih dahulu, sama seperti elemen lain pada pohon DOM. Metode trim() membuang spasi di kedua ujung string, berguna agar isian yang hanya berisi spasi tidak lolos dianggap terisi.
// tidak-dijalankan
const nama = document.querySelector("#nama").value.trim();
const email = document.querySelector("#email").value.trim();
console.log("Nama terbaca: \"" + nama + "\"");
console.log("Email terbaca: \"" + email + "\"");Perhatikan bahwa isian angka pun tiba sebagai string. Konversi dengan Number() diperlukan bila nilainya akan dihitung, dan pemeriksaan kekosongan cukup membandingkan dengan string kosong. Isian selain teks mengikuti pola yang sama dengan sedikit perbedaan. Elemen select mengembalikan opsi terpilih melalui value, sedangkan checkbox dibaca dari properti checked yang bernilai boolean. Setelah data terpakai, form.reset() mengosongkan seluruh isian sekaligus dan mengembalikan form ke keadaan awalnya.
Validasi manual dan pesan error di halaman#
Pemeriksaan manual berupa deretan kondisi sederhana yang dijalankan berurutan pada handler submit. Setiap kondisi yang gagal menampilkan satu pesan pada elemen keterangan, lalu handler berhenti dengan return agar hanya satu masalah dilaporkan pada satu waktu. Pesan ditulis lewat textContent, sehingga teks pesan yang menyertakan potongan isian pengguna tidak pernah dijalankan sebagai markup.
// tidak-dijalankan
if (nama === "") {
pesan.textContent = "Nama wajib diisi.";
return;
}
if (!email.includes("@")) {
pesan.textContent = "Format email belum benar.";
return;
}
pesan.textContent = "Terdaftar: " + nama + " (" + email + ")";Di sisi lain, browser sudah menyediakan lapisan pertama berupa atribut HTML seperti required, type="email", dan minlength. Ketika atribut itu terpasang, form tidak akan terkirim selama isian melanggarnya, dan keadaannya dapat dibaca lewat properti validitas seperti input.validity.valid beserta input.checkValidity(). Validasi manual tetap berguna untuk aturan yang tidak tercakup atribut, misalnya dua isian yang harus cocok.
Untuk umpan balik yang lebih cepat, pemeriksaan yang sama dapat dipasang pada event input milik setiap isian. Pesan kecocokan diperbarui pada setiap ketukan tombol, jauh sebelum tombol kirim ditekan, dan pengguna tidak perlu menebak apa yang masih kurang. Kedua titik pemasangan ini saling melengkapi, event input untuk panduan saat mengetik, dan submit untuk pemeriksaan akhir sebelum data dianggap sah.
Demo berikut menerapkan seluruh pola ini pada form pendaftaran piket dengan dua isian, nama dan email. Kirim form dengan isian kosong, lalu dengan email tanpa @, dan akhirnya dengan isian yang sah, sambil mengamati pesan yang berganti warna pada panel keterangan. Ketiga keadaan itu memperlihatkan alur lengkapnya, yaitu ditolak oleh aturan pertama, ditolak oleh aturan kedua, lalu lolos dan form dikosongkan kembali.
Kode sumber demo
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Demo validasi form</title>
<style>
body { font-family: "Segoe UI", Arial, sans-serif; margin: 14px; font-size: 14px; color: #1f2937; }
label { display: block; margin-top: 8px; font-weight: 600; }
input { padding: 6px 8px; margin-top: 4px; width: 220px; }
button { padding: 6px 14px; margin-top: 12px; cursor: pointer; }
#pesan { margin-top: 12px; padding: 10px; border-radius: 8px; min-height: 20px; max-width: 340px; background: #eef2ff; border: 1px solid #4338ca; }
#pesan.gagal { background: #fee2e2; border-color: #b91c1c; }
#pesan.sukses { background: #dcfce7; border-color: #15803d; }
</style>
</head>
<body>
<form id="form-daftar">
<label for="nama">Nama</label>
<input id="nama" type="text" autocomplete="off">
<label for="email">Email</label>
<input id="email" type="text" autocomplete="off">
<br>
<button type="submit">Daftar piket</button>
</form>
<div id="pesan">Kirim form untuk melihat hasil validasinya.</div>
<script src="index.js"></script>
<script>
// Demo form: preventDefault, pembacaan value, dan pesan validasi di halaman.
const form = document.querySelector("#form-daftar");
const pesan = document.querySelector("#pesan");
form.addEventListener("submit", (event) => {
event.preventDefault();
const nama = document.querySelector("#nama").value.trim();
const email = document.querySelector("#email").value.trim();
if (nama === "") {
pesan.textContent = "Nama wajib diisi.";
pesan.className = "gagal";
return;
}
if (!email.includes("@")) {
pesan.textContent = "Format email belum benar, tanda @ tidak ditemukan.";
pesan.className = "gagal";
return;
}
pesan.textContent = "Terdaftar: " + nama + " (" + email + ")";
pesan.className = "sukses";
form.reset();
});
</script>
<script>
// Demo form: preventDefault, pembacaan value, dan pesan validasi di halaman.
const form = document.querySelector("#form-daftar");
const pesan = document.querySelector("#pesan");
form.addEventListener("submit", (event) => {
event.preventDefault();
const nama = document.querySelector("#nama").value.trim();
const email = document.querySelector("#email").value.trim();
if (nama === "") {
pesan.textContent = "Nama wajib diisi.";
pesan.className = "gagal";
return;
}
if (!email.includes("@")) {
pesan.textContent = "Format email belum benar, tanda @ tidak ditemukan.";
pesan.className = "gagal";
return;
}
pesan.textContent = "Terdaftar: " + nama + " (" + email + ")";
pesan.className = "sukses";
form.reset();
});
</script></body>
</html>Kesalahan umum#
- Memasang listener submit pada tombol, bukan pada form. Tombol tidak memancarkan event
submit, sehingga handler tidak pernah berjalan dan halaman tetap dimuat ulang. Listener dipasang pada elemen<form>, sedangkan tombol cukup bertipesubmit. - Membandingkan isian tanpa membersihkannya. Spasi yang tidak terlihat membuat
nama === ""bernilai salah meski isian kosong, dan data yang tampak sah justru lolos. Panggiltrim()pada setiap nilai sebelum dibandingkan. - Menampilkan pesan baru tanpa menata ulang pesan lama. Isian yang sah pada percobaan berikutnya tetap menampilkan peringatan merah dari percobaan sebelumnya karena elemen pesan tidak pernah ditulis ulang. Setiap jalur hasil wajib memperbarui elemen pesan beserta class warnanya, termasuk jalur yang berhasil.
Ringkasan#
- Event
submitdipasang pada elemen<form>, danevent.preventDefault()di awal handler mencegah halaman dimuat ulang. - Nilai tiap isian dibaca dari properti
valuesebagai string, dibersihkan dengantrim(), dan dikonversi denganNumber()bila akan dihitung. - Validasi manual berupa deretan kondisi berurutan yang menampilkan pesan lewat
textContentlalu berhenti denganreturnpada masalah pertama. - Atribut seperti
requireddan properti validitas membentuk lapisan pertama dari browser, sedangkan aturan khusus ditangani JavaScript.
Referensi#
- HTMLFormElement: submit event — MDN
— penanganan event submit dan peran
preventDefault. - Event: preventDefault() — MDN — pembatalan aksi bawaan browser pada sebuah event.
- Client-side form validation — MDN — atribut kendala dan properti validitas pada isian form.