Validasi Form

Sebelum data dikirim ke server (PHP), kita perlu memvalidasi data di sisi klien (browser) terlebih dahulu. Ini memastikan data yang dikirim sudah benar dan lengkap.

Kenapa Validasi di Client-Side?

ValidasiTempatTujuan
Client-side (JavaScript)BrowserUX — beri feedback cepat ke pengguna
Server-side (PHP)ServerKeamanan — jangan pernah percaya data dari browser
Selalu Validasi di Server Juga!

Validasi JavaScript bisa di-bypass oleh pengguna (misal disable JS). Jadi wajib validasi ulang di PHP. Validasi JS hanya untuk kenyamanan pengguna.

Validasi HTML5 (Bawaan Browser)

Sebelum pakai JavaScript, manfaatkan validasi bawaan HTML:

<form action="proses.php" method="POST">
    <!-- Wajib diisi -->
    <input type="text" name="nama" required>

    <!-- Harus format email -->
    <input type="email" name="email" required>

    <!-- Minimal 8 karakter -->
    <input type="password" name="password" minlength="8" required>

    <!-- Range angka -->
    <input type="number" name="umur" min="1" max="150" required>

    <!-- Pattern (regex) -->
    <input type="tel" name="telp" pattern="08[0-9]{9,11}"
           title="Nomor HP dimulai 08, 11-13 digit">

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

Validasi dengan JavaScript

Untuk validasi yang lebih kompleks, kita gunakan JavaScript:

const form = document.getElementById('form-daftar');

form.addEventListener('submit', function(event) {
    // Ambil nilai input
    const nama = document.getElementById('nama').value.trim();
    const email = document.getElementById('email').value.trim();
    const password = document.getElementById('password').value;
    const konfirmasi = document.getElementById('konfirmasi').value;

    let errors = [];

    // Validasi nama
    if (nama === '') {
        errors.push('Nama wajib diisi');
    } else if (nama.length < 3) {
        errors.push('Nama minimal 3 karakter');
    }

    // Validasi email
    if (email === '') {
        errors.push('Email wajib diisi');
    } else if (!isValidEmail(email)) {
        errors.push('Format email tidak valid');
    }

    // Validasi password
    if (password.length < 8) {
        errors.push('Password minimal 8 karakter');
    }

    // Validasi konfirmasi password
    if (password !== konfirmasi) {
        errors.push('Konfirmasi password tidak cocok');
    }

    // Jika ada error, tampilkan dan jangan kirim form
    if (errors.length > 0) {
        event.preventDefault();  // Jangan kirim form
        tampilkanError(errors);
    }
});

// Helper: validasi email sederhana
function isValidEmail(email) {
    return email.includes('@') && email.includes('.');
}

// Helper: tampilkan error
function tampilkanError(errors) {
    const errorDiv = document.getElementById('error-messages');
    errorDiv.innerHTML = errors.map(e => `<p>⚠️ ${e}</p>`).join('');
    errorDiv.style.display = 'block';
}

Validasi Real-Time (Saat Mengetik)

Beri feedback langsung saat pengguna mengetik:

const inputNama = document.getElementById('nama');
const feedbackNama = document.getElementById('feedback-nama');

inputNama.addEventListener('input', function() {
    const nilai = this.value.trim();

    if (nilai === '') {
        feedbackNama.textContent = '';
        feedbackNama.className = '';
    } else if (nilai.length < 3) {
        feedbackNama.textContent = '❌ Minimal 3 karakter';
        feedbackNama.className = 'error';
    } else {
        feedbackNama.textContent = '✅ Nama valid';
        feedbackNama.className = 'success';
    }
});

Latihan: Form Registrasi dengan Validasi

Buat file register.html:

<!DOCTYPE html>
<html lang="id">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Form Registrasi</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
            font-family: 'Segoe UI', sans-serif;
            background: #f0f2f5;
            display: flex;
            justify-content: center;
            padding: 40px 20px;
        }
        .form-container {
            background: white;
            padding: 35px;
            border-radius: 15px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
            width: 100%;
            max-width: 450px;
        }
        h1 { text-align: center; color: #667eea; margin-bottom: 25px; }

        .form-group {
            margin-bottom: 18px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: 600;
            color: #444;
        }
        input, select {
            width: 100%;
            padding: 10px 14px;
            border: 2px solid #ddd;
            border-radius: 8px;
            font-size: 15px;
            transition: border-color 0.3s;
        }
        input:focus {
            outline: none;
            border-color: #667eea;
        }
        input.valid { border-color: #28a745; }
        input.invalid { border-color: #dc3545; }

        .feedback {
            font-size: 13px;
            margin-top: 4px;
            min-height: 18px;
        }
        .feedback.success { color: #28a745; }
        .feedback.error { color: #dc3545; }

        .error-box {
            display: none;
            background: #fde8e8;
            border: 1px solid #dc3545;
            border-radius: 8px;
            padding: 12px;
            margin-bottom: 15px;
            color: #dc3545;
            font-size: 14px;
        }

        .success-box {
            display: none;
            background: #e8f5e9;
            border: 1px solid #28a745;
            border-radius: 8px;
            padding: 12px;
            margin-bottom: 15px;
            color: #28a745;
            font-size: 14px;
            text-align: center;
        }

        button {
            width: 100%;
            padding: 12px;
            background: #667eea;
            color: white;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            cursor: pointer;
            transition: background 0.3s;
        }
        button:hover { background: #5a6fd6; }
        button:disabled {
            background: #ccc;
            cursor: not-allowed;
        }
    </style>
</head>
<body>
    <div class="form-container">
        <h1>Registrasi 📝</h1>

        <div class="error-box" id="error-box"></div>
        <div class="success-box" id="success-box">
            ✅ Registrasi berhasil! Data valid.
        </div>

        <form id="form-daftar" action="proses-daftar.php" method="POST" novalidate>
            <div class="form-group">
                <label for="nama">Nama Lengkap</label>
                <input type="text" id="nama" name="nama" placeholder="Minimal 3 karakter">
                <div class="feedback" id="feedback-nama"></div>
            </div>

            <div class="form-group">
                <label for="email">Email</label>
                <input type="email" id="email" name="email" placeholder="contoh@email.com">
                <div class="feedback" id="feedback-email"></div>
            </div>

            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" id="password" name="password" placeholder="Minimal 8 karakter">
                <div class="feedback" id="feedback-password"></div>
            </div>

            <div class="form-group">
                <label for="konfirmasi">Konfirmasi Password</label>
                <input type="password" id="konfirmasi" name="konfirmasi" placeholder="Ketik ulang password">
                <div class="feedback" id="feedback-konfirmasi"></div>
            </div>

            <div class="form-group">
                <label for="telp">Nomor HP</label>
                <input type="tel" id="telp" name="telp" placeholder="08xxxxxxxxxx">
                <div class="feedback" id="feedback-telp"></div>
            </div>

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

    <script>
        const form = document.getElementById('form-daftar');
        const inputNama = document.getElementById('nama');
        const inputEmail = document.getElementById('email');
        const inputPassword = document.getElementById('password');
        const inputKonfirmasi = document.getElementById('konfirmasi');
        const inputTelp = document.getElementById('telp');

        // ======= Validasi Real-time =======

        inputNama.addEventListener('input', function() {
            const val = this.value.trim();
            const fb = document.getElementById('feedback-nama');
            if (val === '') {
                setFeedback(this, fb, '', '');
            } else if (val.length < 3) {
                setFeedback(this, fb, '❌ Minimal 3 karakter', 'error');
            } else {
                setFeedback(this, fb, '✅ Nama valid', 'success');
            }
        });

        inputEmail.addEventListener('input', function() {
            const val = this.value.trim();
            const fb = document.getElementById('feedback-email');
            if (val === '') {
                setFeedback(this, fb, '', '');
            } else if (!val.includes('@') || !val.includes('.')) {
                setFeedback(this, fb, '❌ Format email tidak valid', 'error');
            } else {
                setFeedback(this, fb, '✅ Email valid', 'success');
            }
        });

        inputPassword.addEventListener('input', function() {
            const val = this.value;
            const fb = document.getElementById('feedback-password');
            if (val === '') {
                setFeedback(this, fb, '', '');
            } else if (val.length < 8) {
                setFeedback(this, fb, `❌ ${val.length}/8 karakter`, 'error');
            } else {
                setFeedback(this, fb, '✅ Password cukup kuat', 'success');
            }
            // Cek ulang konfirmasi
            if (inputKonfirmasi.value !== '') {
                inputKonfirmasi.dispatchEvent(new Event('input'));
            }
        });

        inputKonfirmasi.addEventListener('input', function() {
            const val = this.value;
            const fb = document.getElementById('feedback-konfirmasi');
            if (val === '') {
                setFeedback(this, fb, '', '');
            } else if (val !== inputPassword.value) {
                setFeedback(this, fb, '❌ Password tidak cocok', 'error');
            } else {
                setFeedback(this, fb, '✅ Password cocok', 'success');
            }
        });

        inputTelp.addEventListener('input', function() {
            const val = this.value.trim();
            const fb = document.getElementById('feedback-telp');
            const pattern = /^08[0-9]{9,11}$/;
            if (val === '') {
                setFeedback(this, fb, '', '');
            } else if (!pattern.test(val)) {
                setFeedback(this, fb, '❌ Format: 08xxx (11-13 digit)', 'error');
            } else {
                setFeedback(this, fb, '✅ Nomor HP valid', 'success');
            }
        });

        // ======= Validasi Submit =======

        form.addEventListener('submit', function(event) {
            event.preventDefault();

            const nama = inputNama.value.trim();
            const email = inputEmail.value.trim();
            const password = inputPassword.value;
            const konfirmasi = inputKonfirmasi.value;
            const telp = inputTelp.value.trim();

            let errors = [];

            if (nama.length < 3) errors.push('Nama minimal 3 karakter');
            if (!email.includes('@') || !email.includes('.')) errors.push('Email tidak valid');
            if (password.length < 8) errors.push('Password minimal 8 karakter');
            if (password !== konfirmasi) errors.push('Konfirmasi password tidak cocok');
            if (!/^08[0-9]{9,11}$/.test(telp)) errors.push('Nomor HP tidak valid');

            const errorBox = document.getElementById('error-box');
            const successBox = document.getElementById('success-box');

            if (errors.length > 0) {
                errorBox.innerHTML = errors.map(e => `<p>⚠️ ${e}</p>`).join('');
                errorBox.style.display = 'block';
                successBox.style.display = 'none';
            } else {
                errorBox.style.display = 'none';
                successBox.style.display = 'block';

                // Di real project, form.submit() akan kirim ke PHP
                // form.submit();

                console.log('Data valid:', { nama, email, password, telp });
            }
        });

        // ======= Helper =======

        function setFeedback(input, feedbackEl, message, type) {
            feedbackEl.textContent = message;
            feedbackEl.className = 'feedback ' + type;
            input.className = type === 'error' ? 'invalid' :
                              type === 'success' ? 'valid' : '';
        }
    </script>
</body>
</html>

Rangkuman JavaScript

TopikYang Dipelajari
DasarVariabel, tipe data, operator, if/else, loop, function
DOMquerySelector, mengubah konten/style, classList
EventsaddEventListener, click, input, submit, preventDefault
ValidasiHTML5 validation, JavaScript validation, real-time feedback

Selanjutnya

Frontend sudah lengkap! Sekarang saatnya masuk ke backend — belajar Dasar PHP → untuk membuat website yang bisa memproses data dan berkomunikasi dengan database.