Section Form Validation mengajarkan validasi bawaan browser: atribut required, minlength, dan pattern memeriksa isian secara otomatis, lengkap dengan gelembung pesan dari browser. Pesan bawaan itu tepat, tetapi kalimat dan tempatnya di luar kendali kita, sementara desain halaman sering menuntut pesan yang serasi di posisi tertentu. JavaScript melengkapi celah ini: kita memegang event submit, membaca alasan kegagalan dari objek ValidityState, lalu menampilkan pesan kustom pada elemen sendiri. Chapter ini merangkum semuanya menjadi satu formulir kecil dengan pesan berbahasa sendiri.
Event submit dan preventDefault #
Saat pengunjung menekan tombol submit atau menekan Enter di dalam form, browser memicu event submit pada elemen form — bukan pada tombolnya. Tindakan bawaan event ini adalah mengirim data dan memuat ulang halaman, dan itulah yang perlu kita tunda selama validasi berjalan:
formulir.addEventListener("submit", function (event) {
event.preventDefault();
});Method preventDefault() pada objek event membatalkan tindakan bawaan, sehingga halaman tetap terbuka dan kode kita yang menentukan langkah berikutnya. Satu detail penting: browser menjalankan pemeriksaan native terlebih dahulu, dan bila isian tidak sah, event submit tidak terpicu sama sekali. Agar JS memegang kendali penuh, contoh di bawah memasang atribut novalidate pada form — pola yang dibahas pada chapter Validasi Browser.
checkValidity dan reportValidity #
Setiap elemen form menyediakan dua method pemeriksaan yang saling melengkapi. checkValidity() menguji isian terhadap seluruh aturan atributnya dan mengembalikan true atau false tanpa menampilkan apa pun — cocok ketika kita ingin menampilkan pesan kustom sendiri. reportValidity() melakukan pemeriksaan yang sama, tetapi ikut menampilkan gelembung pesan bawaan browser bila isian tidak sah; method ini praktis untuk pemeriksaan cepat tanpa penanganan pesan sendiri.
Properti ValidityState #
Ketika checkValidity() mengembalikan false, kita masih perlu tahu alasannya. Properti validity pada elemen memuat objek ValidityState yang beranggota boolean; masing-masing anggota menyatakan satu jenis pelanggaran:
| Properti | Bernilai true ketika |
|---|---|
valueMissing | Kolom dengan atribut required kosong |
tooShort | Panjang teks lebih pendek dari minlength |
patternMismatch | Nilai tidak cocok dengan pola pada atribut pattern |
typeMismatch | Nilai tidak sesuai jenis, misalnya email tanpa tanda @ |
Membaca anggota-anggota ini membuat pesan kita presisi: kolom kosong dan kolom terlalu pendek mendapat kalimat yang berbeda. ValidityState masih memiliki anggota lain untuk kasus angka dan tanggal, dan seluruhnya terdokumentasi pada tautan referensi di akhir chapter.
Contoh: Formulir dengan Pesan Kustom #
Kita bangun formulir undangan kecil dengan satu kolom nama panggilan yang wajib diisi minimal tiga karakter. File formulir-undangan.html menyediakan struktur dan dua tempat pesan:
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Formulir Undangan Komunitas</title>
<script src="formulir-undangan.js" defer></script>
<style>
.pesan-galat {
color: #b3261e;
}
</style>
</head>
<body>
<h1>Undangan Kopi Akhir Pekan</h1>
<form id="form-undangan" novalidate>
<label for="nama">Nama panggilan</label>
<input id="nama" name="nama" type="text" required minlength="3">
<p id="pesan-nama" class="pesan-galat" hidden></p>
<button type="submit">Kirim undangan</button>
</form>
<p id="pesan-sukses" hidden></p>
</body>
</html>Logika validasinya berada di file formulir-undangan.js:
const formulir = document.querySelector("#form-undangan");
const nama = document.querySelector("#nama");
const pesanNama = document.querySelector("#pesan-nama");
const pesanSukses = document.querySelector("#pesan-sukses");
formulir.addEventListener("submit", function (event) {
event.preventDefault();
pesanNama.hidden = true;
pesanSukses.hidden = true;
if (nama.checkValidity()) {
pesanSukses.textContent = "Terima kasih, " + nama.value + ". Sampai jumpa akhir pekan ini.";
pesanSukses.hidden = false;
return;
}
if (nama.validity.valueMissing) {
pesanNama.textContent = "Nama panggilan wajib diisi.";
} else if (nama.validity.tooShort) {
pesanNama.textContent = "Nama panggilan minimal tiga karakter.";
} else {
pesanNama.textContent = "Isian nama belum sesuai.";
}
pesanNama.hidden = false;
});Output yang Dihasilkan:
Saat kolom dibiarkan kosong lalu tombol ditekan:
- Teks merah "Nama panggilan wajib diisi." tampil di bawah kolom
Saat "Bu" diketik lalu tombol ditekan:
- Teks merah "Nama panggilan minimal tiga karakter." tampil
Saat "Budi" diketik lalu tombol ditekan:
- Kalimat "Terima kasih, Budi. Sampai jumpa akhir pekan ini." tampil
- Halaman tidak berpindahMari kita bedah alurnya:
- Baris 1-4 JS (
querySelector): kode memegang referensi form, kolom nama, dan dua wadah pesan. - Baris 6-9 JS (awal listener submit):
preventDefault()menahan pengiriman data, lalu kedua pesan disembunyikan lewat propertihiddenagar sisa pesan dari percobaan sebelumnya tidak tertinggal. - Baris 11-15 JS (pemeriksaan
checkValidity()): bila isian sah, kalimat sukses dirangkai dengan operator+, paragraf sukses ditampilkan, danreturnmengakhiri callback di situ. - Baris 17-23 JS (membaca ValidityState): bila isian tidak sah,
ifdanelse ifmenelusuri penyebabnya satu per satu —valueMissinguntuk kolom kosong,tooShortuntuk isian pendek — lalu menuliskan kalimat yang sesuai pada paragraf pesan. - Baris 24 JS (
pesanNama.hidden = false;): wadah pesan galat hanya ditampilkan setelah isinya pasti, sehingga tidak ada pesan kosong yang muncul.
Pesan kustom, ValidityState, dan event submit menutup daftar keterampilan section ini. Chapter berikutnya, yang sekaligus penutup section, menghitung apa yang telah kita kuasai dan memetakan arah belajar JavaScript selanjutnya.
Referensi resmi untuk pendalaman:
- MDN Web Docs — Event: submit
- MDN Web Docs — Event.preventDefault()
- MDN Web Docs — HTMLInputElement.checkValidity()
- MDN Web Docs — ValidityState
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
formulir-undangan.html
Unduh berkas<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Formulir Undangan Komunitas</title>
<script src="formulir-undangan.js" defer></script>
<style>
.pesan-galat {
color: #b3261e;
}
</style>
</head>
<body>
<h1>Undangan Kopi Akhir Pekan</h1>
<form id="form-undangan" novalidate>
<label for="nama">Nama panggilan</label>
<input id="nama" name="nama" type="text" required minlength="3">
<p id="pesan-nama" class="pesan-galat" hidden></p>
<button type="submit">Kirim undangan</button>
</form>
<p id="pesan-sukses" hidden></p>
</body>
</html>
formulir-undangan.js
Unduh berkasconst formulir = document.querySelector("#form-undangan");
const nama = document.querySelector("#nama");
const pesanNama = document.querySelector("#pesan-nama");
const pesanSukses = document.querySelector("#pesan-sukses");
formulir.addEventListener("submit", function (event) {
event.preventDefault();
pesanNama.hidden = true;
pesanSukses.hidden = true;
if (nama.checkValidity()) {
pesanSukses.textContent = "Terima kasih, " + nama.value + ". Sampai jumpa akhir pekan ini.";
pesanSukses.hidden = false;
return;
}
if (nama.validity.valueMissing) {
pesanNama.textContent = "Nama panggilan wajib diisi.";
} else if (nama.validity.tooShort) {
pesanNama.textContent = "Nama panggilan minimal tiga karakter.";
} else {
pesanNama.textContent = "Isian nama belum sesuai.";
}
pesanNama.hidden = false;
});