HTML Dasar #15 - Atribut Penting: placeholder, required, readonly, disabled

Setelah kita belajar berbagai jenis input dan tombol, sekarang saatnya mengenal atribut-atribut penting yang membuat form lebih ramah pengguna dan profesional. Atribut-atribut ini akan membantu pengguna mengisi form dengan benar dan mencegah kesalahan.


Ringkasan Keempat Atribut

Atribut Fungsi Pengguna Bisa Mengubah? Data Terkirim ke Server?
placeholder Menampilkan teks contoh di dalam input Ya (teks placeholder hilang saat diketik) Tidak (hanya contoh visual)
required Memastikan field harus diisi sebelum submit Ya Ya (jika diisi)
readonly Input hanya bisa dibaca (tidak bisa diubah) Tidak Ya (nilai tetap terkirim)
disabled Input dinonaktifkan sepenuhnya Tidak Tidak (tidak terkirim)
Perbedaan Utama:
  • readonly → data tetap terkirim, tapi tidak bisa diubah
  • disabled → data TIDAK terkirim, dan tidak bisa diubah
  • placeholder → hanya contoh visual, tidak mempengaruhi data
  • required → validasi wajib isi sebelum submit

1. Atribut placeholder - Teks Contoh

placeholder menampilkan teks contoh di dalam input yang hilang otomatis saat pengguna mulai mengetik. Sangat membantu untuk memberi petunjuk format input.

Contoh Dasar:

<input type="text" name="nama" placeholder="Masukkan nama lengkap">
<input type="email" name="email" placeholder="contoh@email.com">
<input type="tel" name="telpon" placeholder="08xx-xxxx-xxxx">

Contoh langsung:

Teks abu-abu di dalam input adalah placeholder — akan hilang saat kamu mulai mengetik

Placeholder untuk Textarea:

<textarea name="pesan" rows="4" placeholder="Tulis pesan Anda di sini..."></textarea>
Tips Placeholder:
  • Jangan gunakan placeholder sebagai pengganti label — buruk untuk aksesibilitas!
  • Placeholder yang baik: "contoh@email.com" atau "DD/MM/YYYY"
  • Placeholder yang buruk: "Isi di sini" (terlalu umum)
  • Gunakan warna teks placeholder yang kontras tapi tidak terlalu mencolok (biasanya abu-abu)

2. Atribut required - Wajib Diisi

required memastikan bahwa field harus diisi sebelum form bisa di-submit. Browser akan menampilkan pesan peringatan otomatis jika field kosong.

Contoh Dasar:

<input type="text" name="nama" required>
<input type="email" name="email" required>
<input type="number" name="umur" required>

Contoh langsung (coba submit tanpa mengisi):

Coba klik submit tanpa mengisi nama atau email — browser akan mencegah submit dan menampilkan peringatan!

Required pada Radio Button dan Checkbox:

<!-- Radio button: minimal satu dipilih -->
<input type="radio" name="jenis_kelamin" value="laki" required> Laki-laki
<input type="radio" name="jenis_kelamin" value="perempuan"> Perempuan

<!-- Checkbox: harus dicentang (biasanya untuk setuju syarat) -->
<input type="checkbox" name="setuju" required> Saya setuju dengan syarat & ketentuan

3. Atribut readonly - Hanya Baca

readonly membuat input tidak bisa diubah oleh pengguna, tetapi nilainya tetap terkirim ke server. Cocok untuk data yang sudah ditentukan sistem (seperti ID, username yang sudah terisi otomatis).

Contoh Dasar:

<input type="text" name="username" value="johndoe123" readonly>
<input type="text" name="email" value="john@example.com" readonly>

Contoh langsung (coba edit — tidak bisa!):

Field dengan readonly memiliki latar abu-abu dan tidak bisa diedit, tapi nilainya tetap akan terkirim saat form di-submit

Readonly pada Textarea:

<textarea name="terms" rows="5" readonly>
Syarat dan ketentuan aplikasi...
</textarea>
Kapan menggunakan readonly?
  • ID atau kode unik yang ditentukan sistem (tidak boleh diubah)
  • Username yang sudah terisi otomatis dari email
  • Data yang diambil dari database (sebagai konfirmasi)
  • Syarat dan ketentuan yang hanya bisa dibaca
  • Nilai perhitungan otomatis (total harga, dll)

4. Atribut disabled - Dinonaktifkan

disabled membuat input tidak bisa diubah dan nilainya TIDAK terkirim ke server. Cocok untuk opsi yang tidak tersedia atau sementara tidak aktif.

Contoh Dasar:

<input type="text" name="kode_voucher" value="DISKON50" disabled>
<select name="metode_pengiriman" disabled>
    <option>Reguler (sedang tidak tersedia)</option>
</select>

Contoh langsung (coba interaksi — semua disabled):

Field dengan disabled memiliki tampilan redup (opacity) dan tidak bisa diinteraksi. Nilainya TIDAK akan terkirim ke server.

Disabled pada Tombol:

<button type="submit" disabled>Submit (Tidak Aktif)</button>

Tombol disabled tidak bisa diklik dan tampil redup

Perbedaan Kritis: readonly vs disabled
readonly Bisa di-focus / di-tab Data terkirim ke server Tampilan normal
disabled Tidak bisa di-focus Data TIDAK terkirim Tampilan redup

Studi Kasus: Form Profil dengan Semua Atribut

Berikut form lengkap yang menggabungkan placeholder, required, readonly, dan disabled:

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <title>Form Profil - Pengaturan Akun</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f0f4f8;
            padding: 40px 20px;
        }
        .profile-card {
            max-width: 650px;
            margin: 0 auto;
            background: white;
            border-radius: 20px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            overflow: hidden;
        }
        .header {
            background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%);
            color: white;
            padding: 25px 30px;
        }
        .header h1 {
            font-size: 24px;
            margin-bottom: 5px;
        }
        .header p {
            opacity: 0.9;
            font-size: 14px;
        }
        form {
            padding: 30px;
        }
        .form-group {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #333;
        }
        .required-star {
            color: #ef4444;
        }
        .hint {
            font-size: 12px;
            color: #666;
            margin-top: 5px;
        }
        input, select, textarea {
            width: 100%;
            padding: 12px;
            border: 2px solid #e0e0e0;
            border-radius: 10px;
            font-size: 14px;
            transition: all 0.3s;
            font-family: inherit;
        }
        input:focus, select:focus, textarea:focus {
            outline: none;
            border-color: #3b82f6;
            box-shadow: 0 0 0 3px rgba(59,130,246,0.1);
        }
        input:read-only, input:disabled, select:disabled, textarea:read-only {
            background: #f5f5f5;
            cursor: not-allowed;
        }
        input:disabled, select:disabled {
            opacity: 0.6;
        }
        .row-2 {
            display: flex;
            gap: 20px;
        }
        .row-2 .form-group {
            flex: 1;
        }
        .checkbox-group {
            display: flex;
            align-items: center;
            gap: 10px;
        }
        .checkbox-group input {
            width: auto;
        }
        .checkbox-group label {
            margin-bottom: 0;
            font-weight: normal;
        }
        .button-group {
            display: flex;
            gap: 15px;
            margin-top: 25px;
        }
        .btn-submit {
            background: #3b82f6;
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 10px;
            font-size: 16px;
            font-weight: bold;
            cursor: pointer;
            flex: 1;
            transition: transform 0.2s;
        }
        .btn-submit:hover {
            transform: translateY(-2px);
            background: #2563eb;
        }
        .btn-reset {
            background: #ef4444;
            color: white;
            border: none;
            padding: 12px 24px;
            border-radius: 10px;
            font-size: 16px;
            font-weight: bold;
            cursor: pointer;
            flex: 1;
            transition: transform 0.2s;
        }
        .btn-reset:hover {
            transform: translateY(-2px);
            background: #dc2626;
        }
        .info-box {
            background: #f8f9fa;
            padding: 15px;
            border-radius: 10px;
            margin-top: 20px;
            font-size: 13px;
            border-left: 4px solid #3b82f6;
        }
        .info-box ul {
            margin-left: 20px;
            margin-top: 8px;
        }
        hr {
            margin: 20px 0;
            border: none;
            border-top: 1px solid #eee;
        }
        .badge {
            display: inline-block;
            background: #e5e7eb;
            padding: 2px 8px;
            border-radius: 12px;
            font-size: 10px;
            font-weight: normal;
            margin-left: 8px;
            color: #4b5563;
        }
    </style>
</head>
<body>

    <div class="profile-card">
        <div class="header">
            <h1>Pengaturan Profil</h1>
            <p>Kelola informasi akun Anda</p>
        </div>
        
        <form action="#" method="POST" id="profileForm">
            <div class="row-2">
                <div class="form-group">
                    <label>User ID <span class="badge">readonly</span></label>
                    <input type="text" name="user_id" value="USER-2024-001" readonly>
                    <div class="hint">ID tidak bisa diubah, otomatis dari sistem</div>
                </div>
                
                <div class="form-group">
                    <label>Status Akun <span class="badge">disabled</span></label>
                    <select name="status" disabled>
                        <option>Premium (Aktif)</option>
                        <option>Basic</option>
                    </select>
                    <div class="hint">Upgrade status sedang dalam proses</div>
                </div>
            </div>
            
            <div class="form-group">
                <label>Nama Lengkap <span class="required-star">*</span> <span class="badge">required</span></label>
                <input type="text" name="fullname" placeholder="Contoh: Ahmad Fauzan" required>
                <div class="hint">Masukkan nama sesuai KTP</div>
            </div>
            
            <div class="row-2">
                <div class="form-group">
                    <label>Email <span class="required-star">*</span> <span class="badge">required</span></label>
                    <input type="email" name="email" placeholder="contoh@email.com" required>
                </div>
                
                <div class="form-group">
                    <label>Nomor Telepon <span class="badge">placeholder</span></label>
                    <input type="tel" name="phone" placeholder="08xx-xxxx-xxxx">
                </div>
            </div>
            
            <div class="form-group">
                <label>Alamat Lengkap <span class="badge">placeholder</span></label>
                <textarea name="address" rows="3" placeholder="Jl. Contoh No. 123, RT/RW, Kelurahan, Kecamatan, Kota"></textarea>
            </div>
            
            <div class="form-group">
                <label>Kode Voucher <span class="badge">disabled</span></label>
                <input type="text" name="voucher" value="WELCOME50" disabled>
                <div class="hint">Voucher sudah digunakan atau expired</div>
            </div>
            
            <div class="form-group">
                <div class="checkbox-group">
                    <input type="checkbox" name="agreement" id="agreement" required>
                    <label for="agreement">Saya menyetujui syarat dan ketentuan yang berlaku <span class="required-star">*</span> <span class="badge">required</span></label>
                </div>
            </div>
            
            <div class="button-group">
                <button type="submit" class="btn-submit">
                    Simpan Perubahan
                </button>
                <button type="reset" class="btn-reset">
                    Reset Form
                </button>
            </div>
            
            <div class="info-box">
                Informasi Atribut yang Digunakan:
                <ul>
                    <li><strong>placeholder</strong> → Nama, Email, Telepon, Alamat (memberi contoh format)</li>
                    <li><strong>required</strong> → Nama, Email, Setuju Syarat (wajib diisi)</li>
                    <li><strong>readonly</strong> → User ID (tidak bisa diubah, tapi tetap terkirim)</li>
                    <li><strong>disabled</strong> → Status Akun, Kode Voucher (tidak aktif, data tidak terkirim)</li>
                </ul>
            </div>
        </form>
    </div>

    <script>
        document.getElementById('profileForm').addEventListener('submit', function(e) {
            e.preventDefault();
            alert('Profil berhasil disimpan! (Contoh - data tidak benar-benar dikirim ke server)');
        });
        
        document.getElementById('profileForm').addEventListener('reset', function() {
            alert('Form telah direset! Field yang readonly/disabled akan kembali ke nilai default.');
        });
    </script>

</body>
</html>

Tabel Perbandingan Lengkap

Atribut Bisa Diedit? Bisa Di-focus? Data Terkirim? Tampilan Default
placeholder Ya Ya Ya (nilai input) Teks abu-abu di dalam input
required Ya Ya Ya (jika diisi) Validasi browser otomatis
readonly Tidak Ya Ya Normal (biasanya background abu-abu)
disabled Tidak Tidak Tidak Redup (opacity rendah)

Kesalahan Umum Pemula

  • Menggunakan placeholder sebagai pengganti <label> → Buruk untuk aksesibilitas (screen reader tidak membaca placeholder)
  • Lupa menambahkan required pada radio button group → Cukup tambahkan required di salah satu radio button dalam grup
  • Menggunakan disabled ketika seharusnya readonly → Data tidak terkirim! Jika data perlu tetap dikirim, gunakan readonly
  • Menggunakan readonly pada checkbox atau radio button → Tidak berfungsi dengan baik, gunakan disabled atau atur dengan JavaScript
  • Placeholder terlalu panjang → Bisa memotong dan tidak terbaca. Placeholder yang baik maksimal 30-40 karakter
Debugging Tips:
  • Jika form tidak bisa submit padahal semua field sudah diisi → cek apakah ada checkbox dengan required yang belum dicentang
  • Jika data tidak terkirim ke server → cek apakah field tidak sengaja diberi disabled (ganti dengan readonly jika perlu tetap terkirim)
  • Jika placeholder tidak muncul → cek apakah ada nilai value yang sudah terisi (placeholder tidak muncul jika value ada)

Latihan Singkat

  1. Buat file HTML baru dengan judul "Form Pemesanan Tiket"
  2. Buat form dengan field-field berikut:
    • Kode Booking (readonly, nilai default: "TICKET-2024-001")
    • Nama Pemesan (required, placeholder: "Masukkan nama lengkap")
    • Email (required, placeholder: "contoh@email.com")
    • Jenis Tiket (select dengan opsi: Regular, VIP, VVIP — disable opsi VVIP karena sold out)
    • Syarat & Ketentuan (textarea readonly dengan teks contoh)
    • Checkbox "Saya setuju" (required)
  3. Buat tombol submit dengan alert konfirmasi
  4. Simpan dan buka di browser, coba fungsi setiap atribut

Intisari Hari Ini

  • placeholder → teks contoh di dalam input (hilang saat diketik)
  • required → field wajib diisi (validasi browser otomatis)
  • readonly → hanya baca, tidak bisa diubah, data tetap terkirim
  • disabled → dinonaktifkan, tidak bisa diubah, data TIDAK terkirim
  • Jangan gunakan placeholder sebagai pengganti label (buruk untuk aksesibilitas)
  • Gunakan readonly untuk data otomatis yang perlu dikirim, disabled untuk opsi yang tidak tersedia
Tantangan Akhir Pekan: Buat sebuah Form Checkout E-commerce yang lengkap! Form harus memiliki:
  • placeholder → untuk field alamat, nomor telepon, kode pos (beri contoh format yang benar)
  • required → semua field penting (nama, alamat, telepon, metode pembayaran)
  • readonly → untuk ID transaksi (otomatis dari sistem) dan total harga (hasil perhitungan)
  • disabled → untuk opsi pengiriman yang sedang tidak tersedia (misal: "Reguler - Sedang Penuh")
  • Tambahkan checkbox "Setuju dengan syarat & ketentuan" dengan required
  • Gunakan CSS yang menarik dan buat kotak penjelasan di bagian bawah form yang menjelaskan penggunaan setiap atribut
  • Buat simulasi perhitungan total harga sederhana dengan JavaScript (type="button")
Selamat mencoba!

Artikel Sebelumnya: HTML Dasar #14 - Tombol (button) dan Submit
Artikel Selanjutnya: HTML Dasar #16 - Perbedaan div dan span (Block vs Inline Element)

Lebih baru Lebih lama

نموذج الاتصال