Form HTML Lanjutan: Validasi, Pengelompokan, dan Kolom yang Lebih Pintar

Naik level dari dasar-dasar form HTML. Pelajari atribut name, validasi bawaan lewat required, pattern, dan min/max, pengelompokan dengan fieldset dan legend, saran lewat datalist, serta cara membuat form yang kokoh sekaligus mudah diakses.

Diterbitkan 6 Agustus 202610 menit bacaOleh ACY Partner Indonesia
Form HTML lanjutan — validasi, pengelompokan, dan batasan kolom
300 × 250Slot Iklan TersediaPasang iklan Anda di sini

Kamu sebenarnya sudah bisa membuat form — ada <form>, <input>, <label>, dan tombol submit. Kalau bagian itu masih terasa setengah-setengah, ada baiknya kamu mampir dulu ke Form dan Input HTML sebelum lanjut, karena semua yang kita bahas di sini menumpuk langsung di atas pengetahuan tadi.

Artikel ini soal membuat form yang benar-benar tahan banting di dunia nyata. Form dasar cuma mengumpulkan input; form lanjutan ikut menjaga-nya — setiap kolom diberi nama supaya datanya kembali dengan label yang jelas, input ngawur ditolak sebelum sampai ke server, kolom-kolom yang berkaitan dikelompokkan biar halamannya enak dibaca, dan pengguna terbantu mengisinya lebih cepat. Semua ini tanpa JavaScript sama sekali. HTML menyediakan banyak hal secara gratis, dan menguasainya sekarang bakal menghemat tumpukan kode kamu nanti.

Atribut name: jalan data benar-benar terkirim

Ada satu hal yang sengaja kita lewati di artikel dasar. Kamu bisa saja membuat form yang kelihatannya sempurna — lengkap dengan label dan tipe input yang tepat — tapi yang terkirim malah kosong melompong. Bagian yang membuat nilai sebuah kolom ikut terkirim adalah atribut name.

Saat form di-submit, browser mengumpulkan setiap kolom yang punya name, lalu mengirim masing-masing sebagai pasangan name=value. Kolom tanpa name langsung diabaikan begitu saja:

<form action="/signup" method="post">
  <label for="email">Email</label>
  <input type="email" id="email" name="email" />

  <label for="plan">Paket</label>
  <input type="text" id="plan" />  <!-- tanpa name = tidak pernah terkirim -->

  <button type="submit">Daftar</button>
</form>

Di form itu, server menerima email=... tapi sama sekali tidak tahu soal plan, karena plan tidak punya name. Bug ini gampang lolos dari pengawasan: kolomnya kelihatan baik-baik saja, pengguna sudah mengetik di situ, tapi nilainya hilang begitu saja saat submit.

id dan name itu dua hal berbeda

Ini yang bikin hampir semua orang bingung di awal. Atribut id menghubungkan <label> ke input-nya, dan dipakai CSS serta JavaScript di halaman. Sedangkan name adalah yang dikirim ke server. Keduanya memang sering bernilai sama (id="email" name="email"), tapi tugasnya beda — dan hanya name yang menentukan apa yang terkirim. Kalau form-mu “kelihatan jalan” tapi datanya tidak pernah sampai, name yang lupa dipasang adalah hal pertama yang patut kamu cek.

name juga berperan dalam mengelompokkan. Tombol radio yang memakai name sama otomatis menjadi satu pilihan — begitu kamu pilih salah satu, yang lain ikut terlepas:

<input type="radio" id="kartu" name="bayar" value="kartu" />
<label for="kartu">Kartu</label>

<input type="radio" id="transfer" name="bayar" value="transfer" />
<label for="transfer">Transfer bank</label>

Karena kedua radio sama-sama ber-name="bayar", browser memperlakukannya sebagai satu pertanyaan dengan dua jawaban, lalu mengirim satu nilai saja: bayar=kartu (atau bayar=transfer). Nilai value di tiap radio itulah yang sebenarnya dikirim — teks label hanya untuk dibaca manusia.

Validasi bawaan, tanpa perlu JavaScript

Browser bisa memeriksa form sebelum dikirim, dan menolaknya dengan pesan yang membantu kalau ada yang salah. Kamu mengaktifkan pemeriksaan ini lewat atribut. Ini adalah validasi sisi klien — saringan pertama yang cepat dan ramah — dan kamu menyalakannya cukup dengan menulis HTML.

required — kolom tidak boleh kosong

Tambahkan required ke kolom mana pun yang wajib diisi, dan browser akan menolak submit selama kolom itu masih kosong, memunculkan pesan, lalu memfokuskan kursor ke kolomnya:

<label for="nama">Nama lengkap</label>
<input type="text" id="nama" name="nama" required />

Pemeriksaan berdasarkan tipe

Beberapa tipe input memvalidasi formatnya sendiri secara gratis. type="email" menolak teks yang tidak berbentuk email; type="url" menuntut URL yang sungguhan:

<input type="email" name="email" required />
<input type="url" name="website" />

Batas panjang dan rentang

Untuk teks, minlength dan maxlength membatasi jumlah karakter yang boleh dimasukkan. Untuk angka, tanggal, dan rentang, min dan max menetapkan batasnya, sedangkan step mengatur kelipatan yang diizinkan:

<input type="password" name="pw" minlength="8" maxlength="64" required />

<input type="number" name="jumlah" min="1" max="10" step="1" />

<input type="date" name="kapan" min="2026-01-01" max="2026-12-31" />

pattern — aturanmu sendiri lewat regex

Kalau tipe bawaan masih kurang spesifik, pattern memungkinkan kamu memberikan sebuah regular expression yang harus dicocokkan oleh nilainya. Ini contoh kolom yang hanya menerima kode pos 5 digit:

<label for="kodepos">Kode pos</label>
<input type="text" id="kodepos" name="kodepos"
       pattern="[0-9]{5}"
       title="Masukkan tepat 5 angka" />

title di sini punya dua peran sekaligus — teksnya ikut menjadi bagian dari pesan error yang ditampilkan browser saat pola tidak cocok, jadi tulislah sebagai instruksi yang jelas, bukan sekadar label.

Selalu pasangkan pattern dengan title yang jelas

Ketika sebuah pattern gagal dicocokkan, pesan bawaan browser (“Please match the requested format”) sama sekali tidak menjelaskan apa-apa ke pengguna. Tambahkan title yang menyebutkan aturannya secara gamblang — “Masukkan tepat 5 angka” atau “Hanya huruf dan angka, tanpa spasi” — dan teks itu yang muncul di gelembung validasi. Inilah pembeda antara form yang bikin orang frustrasi dan form yang menuntun mereka.

Validasi sisi klien tidak pernah cukup kalau berdiri sendiri

Validasi bawaan HTML itu kemudahan untuk pengguna yang jujur, bukan benteng keamanan. Siapa pun bisa mematikan JavaScript, menyunting HTML lewat browser, atau mengirim permintaan langsung ke server tanpa form sama sekali — melewati setiap required dan pattern yang sudah kamu tulis. Jadi anggap pemeriksaan ini sebagai saringan awal yang memperbaiki pengalaman, dan selalu validasi ulang di server, tempat datanya tidak bisa diutak-atik. Validasi sisi depan untuk manusia; validasi sisi belakang untuk keamanan.

Atribut bermanfaat yang bikin form lebih nyaman dipakai

Selain validasi, ada beberapa atribut yang diam-diam memperbaiki pengalaman pengguna:

  • placeholder menampilkan teks petunjuk samar di dalam kolom yang masih kosong. Berguna sebagai contoh, tapi bukan pengganti <label> — teksnya hilang begitu orang mulai mengetik.
  • autocomplete memberi tahu browser kolom itu untuk apa (autocomplete="email", "name", "tel"), supaya browser bisa menawarkan isian dari data yang tersimpan. Setel dengan benar, dan form-mu akan terisi sendiri saat pengguna datang lagi.
  • autofocus menaruh kursor di sebuah kolom begitu halaman dimuat. Pakai secukupnya saja — paling banyak satu per halaman.
  • readonly menampilkan nilai yang bisa dilihat dan disalin pengguna tapi tidak bisa diubah, sembari tetap ikut terkirim saat submit.
  • disabled mematikan total sebuah kontrol — dan yang penting, kolom yang disabled tidak ikut terkirim.
<input type="email" name="email"
       placeholder="kamu@contoh.com"
       autocomplete="email"
       required />

readonly tetap terkirim, disabled tidak

Keduanya kelihatan mirip di layar tapi berperilaku sangat berbeda saat submit. Nilai kolom readonly ikut masuk ke data yang dikirim — pas untuk menampilkan total yang dihitung otomatis dan tak boleh diubah pengguna. Sementara nilai kolom disabled ditinggalkan sepenuhnya. Kalau kamu mau pengguna melihat sebuah nilai sekaligus mengirimkannya, pakai readonly; kalau mau mematikan kontrol secara total, pakai disabled.

Mengelompokkan kolom dengan <fieldset> dan <legend>

Form yang panjang jadi lebih enak dibaca kalau kolom-kolom yang berkaitan dikelompokkan, baik secara tampilan maupun struktur. Untuk itulah <fieldset> ada — ia membungkus sekumpulan kontrol yang sejenis, dan <legend> memberi judul untuk kelompok itu:

<form action="/checkout" method="post">
  <fieldset>
    <legend>Alamat pengiriman</legend>

    <label for="jalan">Jalan</label>
    <input type="text" id="jalan" name="jalan" />

    <label for="kota">Kota</label>
    <input type="text" id="kota" name="kota" />
  </fieldset>

  <fieldset>
    <legend>Pembayaran</legend>

    <input type="radio" id="kartu" name="bayar" value="kartu" />
    <label for="kartu">Kartu</label>

    <input type="radio" id="transfer" name="bayar" value="transfer" />
    <label for="transfer">Transfer bank</label>
  </fieldset>

  <button type="submit">Buat pesanan</button>
</form>

Secara bawaan browser menggambar garis tepi di sekeliling tiap <fieldset> dengan <legend> menempel di sisi atasnya — dan semua tampilan itu bisa kamu rombak ulang pakai CSS nanti. Keuntungan sejatinya ada di sisi aksesibilitas: pembaca layar mengumumkan teks legend saat pengguna masuk ke kelompoknya, jadi mereka mendengar “Pembayaran, Kartu” alih-alih cuma “Kartu” yang mengambang tanpa konteks. Ini sangat berharga untuk grup radio, di mana pertanyaannya sendiri (“mau bayar pakai apa?”) tinggal di dalam legend.

Input yang lebih pintar: datalist dan optgroup

Dua elemen ini melangkah lebih jauh dari dropdown biasa.

Sebuah <datalist> memberi input teks daftar saran sambil tetap membiarkan pengguna mengetik versinya sendiri. Anggap saja autocomplete yang tidak mengunci pilihanmu:

<label for="browser">Browser kamu</label>
<input type="text" id="browser" name="browser" list="daftar-browser" />

<datalist id="daftar-browser">
  <option value="Chrome"></option>
  <option value="Firefox"></option>
  <option value="Safari"></option>
  <option value="Edge"></option>
</datalist>

Atribut list="daftar-browser" di input mengarah ke id="daftar-browser" di datalist-nya. Saat pengguna mengetik, saran yang cocok bermunculan — tapi mereka bebas mengabaikannya dan memasukkan apa pun. Bandingkan dengan <select> yang memaksa pengguna memilih dari daftar dan tidak boleh selain itu.

Saat kamu memang memakai <select> dan pilihannya banyak, <optgroup> menatanya ke dalam bagian-bagian yang berlabel:

<label for="kota">Kota</label>
<select id="kota" name="kota">
  <optgroup label="Indonesia">
    <option value="jkt">Jakarta</option>
    <option value="sby">Surabaya</option>
  </optgroup>
  <optgroup label="Malaysia">
    <option value="kul">Kuala Lumpur</option>
  </optgroup>
</select>

Atribut label di tiap <optgroup> hanyalah judul — ia sendiri tidak bisa dipilih. Keberadaannya semata-mata supaya daftar yang panjang jadi gampang ditelusuri.

Unggah berkas dan nilai ganda

Input berkas punya atributnya sendiri yang berguna. accept memberi petunjuk tipe berkas yang ditawarkan, dan multiple memungkinkan pengguna memilih lebih dari satu berkas:

<label for="dokumen">Unggah dokumen</label>
<input type="file" id="dokumen" name="dokumen"
       accept=".pdf,.docx" multiple />

accept=".pdf,.docx" mengarahkan pemilih berkas ke tipe-tipe itu (kamu juga bisa memakai tipe MIME seperti image/* untuk “gambar apa saja”). Atribut multiple juga berlaku pada type="email", yang lalu mengizinkan daftar alamat yang dipisah koma. Satu catatan penting: form yang mengunggah berkas butuh enctype="multipart/form-data" di elemen <form>-nya, kalau tidak isi berkasnya tidak akan terkirim dengan benar.

Menyambungkan label tanpa for

Ada cara kedua, yang sering kali lebih rapi, untuk mengaitkan label ke kontrolnya: bungkus input-nya di dalam label. Dengan begitu kamu tidak butuh for/id sama sekali — sambungannya terjadi secara implisit:

<label>
  <input type="checkbox" name="setuju" />
  Saya setuju dengan syarat dan ketentuan
</label>

Kedua cara ini sama-sama sah. Versi for/id yang eksplisit memberimu lebih banyak kebebasan dalam menata tata letak (label dan input boleh diletakkan di mana saja), sementara cara membungkus terasa praktis untuk kontrol kecil seperti checkbox yang labelnya menempel persis di sebelah kotaknya. Pilih saja mana yang terbaca lebih bersih sesuai situasinya — yang penting, jangan pernah membiarkan satu input pun tanpa label.

Sebuah form yang utuh dan kokoh

Sekarang mari kita satukan semuanya menjadi form pendaftaran yang memvalidasi dirinya sendiri, mengelompokkan kolomnya, dan mengirim data yang bersih serta berlabel:

<form action="/register" method="post">
  <fieldset>
    <legend>Akun kamu</legend>

    <label for="namalengkap">Nama lengkap</label>
    <input type="text" id="namalengkap" name="namalengkap"
           autocomplete="name" required />

    <label for="email">Email</label>
    <input type="email" id="email" name="email"
           autocomplete="email" placeholder="kamu@contoh.com" required />

    <label for="password">Kata sandi</label>
    <input type="password" id="password" name="password"
           minlength="8" required
           title="Minimal 8 karakter" />
  </fieldset>

  <fieldset>
    <legend>Paket</legend>

    <input type="radio" id="gratis" name="paket" value="gratis" checked />
    <label for="gratis">Gratis</label>

    <input type="radio" id="pro" name="paket" value="pro" />
    <label for="pro">Pro</label>
  </fieldset>

  <label>
    <input type="checkbox" name="newsletter" />
    Kirimi saya kabar terbaru produk
  </label>

  <button type="submit">Buat akun</button>
</form>

Coba telusuri apa saja yang sekarang dikerjakan form ini sendirian, tanpa setitik pun JavaScript: ia menolak submit sampai nama, email, dan kata sandi terisi; ia memeriksa email-nya berbentuk email dan kata sandinya minimal delapan karakter; ia memisahkan kolom akun dari pilihan paket supaya tata letaknya terbaca jelas; ia memilihkan paket “Gratis” lebih dulu lewat checked; dan tiap kolom punya name, sehingga server menerima kumpulan nilai yang bersih seperti namalengkap=...&email=...&password=...&paket=gratis. Itu form yang benar-benar kokoh, dan semuanya cuma markup.

Penutup

Kamu sudah membawa form HTML dari sekadar “mengumpulkan input” menjadi “mengumpulkan input yang bagus, dengan aman dan jelas”:

  • Atribut name adalah yang sesungguhnya membuat nilai sebuah kolom terkirim — tanpa name, tanpa data. Ia terpisah dari id, dan ia pula yang mengelompokkan tombol radio.
  • Validasi bawaan lewat required, minlength/maxlength, min/max/step, dan pattern (dipasangkan dengan title yang jelas) menolak input buruk sebelum submit — tapi tetap validasi juga di server.
  • Atribut seperti placeholder, autocomplete, readonly, dan disabled memoles pengalaman pengguna — dan ingat, readonly ikut terkirim sedangkan disabled tidak.
  • <fieldset> dan <legend> mengelompokkan kolom yang berkaitan dan benar-benar menguntungkan dari sisi aksesibilitas, terutama untuk grup radio.
  • <datalist> menawarkan saran tanpa memaksa satu pilihan, sedangkan <optgroup> merapikan dropdown yang panjang.

Dengan alat-alat ini, form-mu berhenti menjadi sekadar deretan kotak kosong dan mulai menjadi sesuatu yang aktif membantu orang mengisinya dengan benar. Berikutnya, kita akan menyelami elemen <input> itu sendiri lebih dalam dan menjelajahi seluruh ragam tipe input HTML — pemilih tanggal, pemilih warna, penggeser, dan banyak lagi.

Tag:htmlfrontendformvalidasimenengah
728 × 90Slot Iklan TersediaPasang iklan Anda di sini

Artikel Terkait

Lihat Semua Artikel

Artikel yang Mungkin Kamu Suka

Apa Itu Framework Frontend? — chip kode dengan tag komponen
Frontend / Dasar

Apa Itu Framework Frontend?

Penjelasan ramah untuk pemula tentang apa itu framework frontend, kenapa mereka ada, masalah apa yang mereka selesaikan dibanding JavaScript biasa, dan kapan kamu memang sebaiknya memakainya.

20 Sep 20268 menit baca
Sampul fundamentals frontend bertuliskan Apa Itu Frontend dan HTML + CSS + JS
Frontend / Dasar

Apa Itu Frontend Development?

Panduan ramah pemula tentang frontend development: bagian website yang kamu lihat dan klik secara langsung. Pahami cara kerja HTML, CSS, dan JavaScript, serta bedanya frontend dengan backend.

20 Sep 20268 menit baca
Ilustrasi sampul untuk Apa yang Dikerjakan Frontend Developer
Frontend / Dasar

Apa yang Dikerjakan Frontend Developer: Panduan untuk Pemula

Penjelasan ramah pemula tentang apa yang sebenarnya dikerjakan frontend developer setiap hari: mengubah desain jadi antarmuka yang berfungsi, membangun UI yang bisa dipakai ulang, sampai urusan responsif, aksesibilitas, dan kecepatan.

20 Sep 20269 menit baca
Kartu judul bertuliskan Styling dan Interaktivitas di atas latar biru gelap ACY Partner
Frontend / Dasar

Cara Kerja Styling dan Interaktivitas

Penjelasan ramah pemula soal bagaimana CSS menyulap HTML polos jadi tampilan rapi, dan bagaimana JavaScript menambahkan perilaku — pola berpikir struktur, gaya, perilaku saat membangun halaman web.

20 Sep 20268 menit baca
Tiga lapisan front-end menyatu di satu halaman web
Frontend / Dasar

Cara HTML, CSS, dan JavaScript Bekerja Bersama

Panduan praktis untuk pemula: bikin satu tombol kecil, beri struktur dengan HTML, tampilan dengan CSS, dan perilaku dengan JavaScript, lalu lihat ketiga lapisan ini bekerja sama di halaman nyata.

20 Sep 20268 menit baca
Sampul ikhtisar praktik terbaik frontend
Frontend / Dasar

Ikhtisar Praktik Terbaik Frontend

Peta ringkas tentang apa itu frontend yang baik — HTML bermakna, CSS rapi, JavaScript secukupnya, desain responsif, performa, dan progressive enhancement, lengkap dengan arahan untuk mendalaminya.

20 Sep 20268 menit baca