Belajar JavaScript - Form Validation dan Interaksi Pengguna
Episode 17 of 23

Belajar JavaScript - Form Validation dan Interaksi Pengguna

Episode ini membahas form dari dua sisi: validasi HTML5 bawaan yang cepat, dan validasi JavaScript custom untuk aturan yang lebih kompleks. Kalian juga belajar menampilkan pesan error yang jelas, validasi saat mengetik, dan memproses submit secara asynchronous.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Form adalah gerbang utama aplikasi web menerima data dari pengguna — dan sekaligus sumber paling banyak data kotor. Pengguna bisa mengirim string kosong, email tanpa @, atau angka di tempat teks. Validasi memastikan data yang masuk sesuai aturan, baik sebelum sampai ke server maupun sebelum diproses.

Episode 17 membahas validasi berlapis. Lapisan pertama adalah validasi HTML5 yang bawaan browser — cepat dan tanpa kode JavaScript. Lapisan kedua adalah validasi JavaScript custom untuk aturan yang tidak bisa diungkapkan HTML. Terakhir, kalian membangun feedback yang baik: pesan error yang jelas, validasi saat mengetik, dan submit yang diproses secara asynchronous.

Prinsip yang harus dipegang: validasi client-side untuk pengalaman pengguna, validasi server-side untuk keamanan. Keduanya wajib — yang satu tidak menggantikan yang lain.

Form dan Elemen Input

Struktur Form Dasar

Mulai dari struktur HTML yang benar. Elemen kunci: form, label yang terhubung dengan input, dan tipe input yang sesuai:

JSindex.html - form pendaftaran
<form id="form-daftar" novalidate>
  <label for="nama">Nama</label>
  <input type="text" id="nama" name="nama" required minlength="3" />
 
  <label for="email">Email</label>
  <input type="email" id="email" name="email" required />
 
  <button type="submit">Daftar</button>
  <p id="pesan-error" hidden></p>
</form>

<input type="email" memberitahu browser bahwa kolom ini harus berformat email. required menandai kolom wajib, minlength="3" membatasi panjang minimum. Atribut novalidate pada form sengaja dimatikan — supaya kalian bisa menerapkan validasi JavaScript dengan kontrol penuh. Elemen p dengan id pesan-error akan menampung feedback.

Validasi HTML5 Bawaan

Memanfaatkan Constraint Validation API

Bahkan tanpa novalidate, browser punya validasi HTML5 bawaan. Saat validasi gagal, event invalid dan property validity memberi informasi detail:

JSMenggunakan validity bawaan
const inputEmail = document.querySelector("#email");
 
inputEmail.addEventListener("input", () => {
  console.log("valid:", inputEmail.validity.valid);
  console.log("typeMismatch:", inputEmail.validity.typeMismatch);
  console.log("valueMissing:", inputEmail.validity.valueMissing);
});

inputEmail.validity.valid bernilai true saat input lolos semua aturan HTML5. validity.typeMismatch menandai format salah, validity.valueMissing menandai kolom wajib yang kosong. Saat form mencoba submit dan ada yang gagal, event invalid terpicu dan validationMessage berisi pesan bawaan browser — yang bisa kalian tampilkan sendiri tanpa popup bawaan.

Validasi JavaScript Custom

Aturan yang Tidak Bisa HTML Tangani

Aturan seperti "password harus mengandung angka" atau "konfirmasi harus sama dengan password" tidak bisa diungkapkan dengan atribut HTML. Ini pekerjaan JavaScript:

JSValidasi custom dengan fungsi
function validasiPassword(kataSandi, konfirmasi) {
  if (kataSandi.length < 8) {
    return "Password minimal 8 karakter";
  }
  if (!/[0-9]/.test(kataSandi)) {
    return "Password harus mengandung angka";
  }
  if (kataSandi !== konfirmasi) {
    return "Konfirmasi password tidak cocok";
  }
  return null;
}
 
console.log(validasiPassword("rahasia", "rahasia"));
console.log(validasiPassword("rahasia12", "rahasia12"));

validasiPassword mengembalikan string pesan error, atau null jika valid. Memisahkan aturan ke fungsi murni seperti ini memudahkan pengujian. null sebagai penanda "valid" adalah konvensi yang jelas dan mudah diperiksa.

Menampilkan Pesan Error

Pesan error terbaik ditampilkan dekat input yang bermasalah, bukan menumpuk di satu tempat:

JSMenampilkan pesan error
function tampilkanError(input, pesan) {
  const errorEl = input.nextElementSibling;
 
  if (pesan === null) {
    errorEl.hidden = true;
    input.classList.remove("salah");
  } else {
    errorEl.textContent = pesan;
    errorEl.hidden = false;
    input.classList.add("salah");
  }
}
 
const inputNama = document.querySelector("#nama");
tampilkanError(inputNama, validasiNama(inputNama.value));

tampilkanError memakai input.nextElementSibling — asumsi elemen error menempel setelah input di HTML. Saat valid, pesan disembunyikan dan class salah dihapus; saat tidak, pesan ditampilkan dan input ditandai merah. Konsistensi posisi error ini membuat pengguna tidak perlu mencari-cari.

Validasi Saat Mengetik dan Submit

Validasi Real-time di Setiap Input

Validasi yang hanya terjadi saat submit terasa lamban. Pola umum: validasi ringan saat input berlangsung, validasi penuh saat blur dan submit:

JSValidasi saat mengetik
const inputNama = document.querySelector("#nama");
const form = document.querySelector("#form-daftar");
 
inputNama.addEventListener("input", () => {
  const pesan = inputNama.value.length < 3 ? "Nama minimal 3 karakter" : null;
  tampilkanError(inputNama, pesan);
});
 
form.addEventListener("submit", (event) => {
  event.preventDefault();
 
  const pesan = validasiNama(inputNama.value);
  tampilkanError(inputNama, pesan);
 
  if (pesan === null) {
    console.log("Form valid, siap dikirim");
  }
});

inputNama.addEventListener("input", ...) memperbarui pesan di setiap ketikan. Saat submit, event.preventDefault() menghentikan pengiriman default, validasi terakhir dijalankan, dan hanya jika bersih data diproses. Pengguna mendapat umpan balik seketika tanpa menunggu submit.

Submit Asynchronous dengan fetch

Jika semua kolom valid, kirim data ke server dengan fetch dan tampilkan hasilnya:

JSSubmit form dengan fetch
async function kirimPendaftaran(data) {
  const respons = await fetch("/api/daftar", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(data),
  });
 
  if (!respons.ok) {
    throw new Error(`HTTP ${respons.status}`);
  }
 
  return respons.json();
}
 
const dataForm = {
  nama: document.querySelector("#nama").value,
  email: document.querySelector("#email").value,
};
 
await kirimPendaftaran(dataForm);
console.log("Pendaftaran berhasil");

async function kirimPendaftaran(data) memakai pola fetch POST dari episode 15 lengkap dengan pengecekan respons.ok. Memisahkan fungsi pengiriman dari logika form membuat kode mudah diuji, dan error await ditangkap dengan try...catch seperti di episode 16.

Penutup

Episode 17 membuat kalian membangun form yang andal: validasi HTML5 dengan Constraint Validation API, validasi custom untuk aturan kompleks, tampilan pesan error yang jelas dekat input, validasi saat mengetik, dan submit asynchronous dengan fetch.

Inti yang harus dibawa pulang:

  • Validasi HTML5 menangani aturan umum tanpa JavaScript.
  • validity dan validationMessage memberi akses programatik ke validasi browser.
  • novalidate memberi kontrol penuh pada validasi JavaScript.
  • Aturan kompleks seperti kecocokan password butuh fungsi validasi custom.
  • Tampilkan error dekat input, bukan menumpuk di satu tempat.
  • Validasi client-side untuk UX; validasi server-side untuk keamanan.

Di episode 18 selanjutnya kita akan membahas Web Storage, cookies, dan state client-side — menyimpan data di browser dengan localStorage dan sessionStorage, bekerja dengan cookies, serta pola state yang aman dan efektif. Kalian akan tahu kapan harus memakai yang mana.

Belajar JavaScript - Form Validation dan Interaksi Pengguna | Belajar JavaScript