JavaScript Form Validation (Form Doğrulama)
Form doğrulama (validation) kullanıcıdan gelen verinin eksiksiz ve geçerli olmasını sağlar. Genellikle iki katmanlı yapılır: 1) Anlık kontrol (input/blur) + 2) Gönderimde son kontrol (submit).
Altın kural
JavaScript doğrulama kullanıcı deneyimi içindir.
Güvenlik için her zaman sunucu tarafında da doğrulama yapılmalıdır.
1) Örnek Form (Ad, E-posta, Şifre, KVKK)
<form id="frmValid" novalidate>
<div class="mb-3">
<label class="form-label">Ad Soyad</label>
<input id="adsoyad" name="adsoyad" type="text" class="form-control" placeholder="Ad Soyad">
<div class="small text-danger mt-1" id="err_adsoyad"></div>
</div>
<div class="mb-3">
<label class="form-label">E-posta</label>
<input id="email" name="email" type="email" class="form-control" placeholder="ornek@mail.com">
<div class="small text-danger mt-1" id="err_email"></div>
</div>
<div class="mb-3">
<label class="form-label">Şifre</label>
<input id="sifre" name="sifre" type="password" class="form-control" placeholder="En az 8 karakter">
<div class="small text-danger mt-1" id="err_sifre"></div>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="kvkk" name="kvkk">
<label class="form-check-label" for="kvkk">KVKK metnini okudum, kabul ediyorum</label>
<div class="small text-danger mt-1" id="err_kvkk"></div>
</div>
<button id="btnGonder" class="btn btn-primary" type="submit">Gönder</button>
<span id="loading" class="ms-2 small text-muted" style="display:none;">Gönderiliyor...</span>
<div id="result" class="mt-3"></div>
</form>
Neden
novalidate?
Tarayıcının kendi doğrulama baloncuklarını kapatır; böylece
tüm kontrol ve mesajları bizim UI standardımızla gösterebiliriz.
2) JavaScript Doğrulama Kodu (input + blur + submit)
(() => {
// --- Helpers ---
const $ = (id) => document.getElementById(id);
const setError = (field, message) => {
const err = $("err_" + field);
if (err) err.textContent = message || "";
};
const clearAllErrors = () => {
["adsoyad","email","sifre","kvkk"].forEach(f => setError(f, ""));
};
const isEmail = (val) => {
// Basit ve yeterli email kontrolü (aşırı katı regexlerden kaçın)
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(val);
};
// --- Form elements ---
const frm = $("frmValid");
const btn = $("btnGonder");
const load = $("loading");
const res = $("result");
const inpAd = $("adsoyad");
const inpEmail = $("email");
const inpSifre = $("sifre");
const inpKvkk = $("kvkk");
// --- Field validations ---
const validateAd = () => {
const v = inpAd.value.trim();
if (!v) return setError("adsoyad", "Ad Soyad boş olamaz."), false;
if (v.length < 3) return setError("adsoyad", "En az 3 karakter giriniz."), false;
setError("adsoyad", "");
return true;
};
const validateEmail = () => {
const v = inpEmail.value.trim();
if (!v) return setError("email", "E-posta boş olamaz."), false;
if (!isEmail(v)) return setError("email", "Geçerli bir e-posta giriniz."), false;
setError("email", "");
return true;
};
const validateSifre = () => {
const v = inpSifre.value;
if (!v) return setError("sifre", "Şifre boş olamaz."), false;
if (v.length < 8) return setError("sifre", "Şifre en az 8 karakter olmalı."), false;
// İsteğe bağlı: güç kontrolü (en az 1 harf + 1 rakam)
const hasLetter = /[A-Za-zÇĞİÖŞÜçğıöşü]/.test(v);
const hasNumber = /\d/.test(v);
if (!hasLetter || !hasNumber) {
return setError("sifre", "Şifre en az 1 harf ve 1 rakam içermeli."), false;
}
setError("sifre", "");
return true;
};
const validateKvkk = () => {
if (!inpKvkk.checked) return setError("kvkk", "Devam etmek için KVKK onayı gerekli."), false;
setError("kvkk", "");
return true;
};
const validateAll = () => {
// Sıralı doğrulama: kullanıcıya daha anlaşılır geri bildirim
const ok1 = validateAd();
const ok2 = validateEmail();
const ok3 = validateSifre();
const ok4 = validateKvkk();
return ok1 && ok2 && ok3 && ok4;
};
// --- Live validation events ---
inpAd.addEventListener("blur", validateAd);
inpEmail.addEventListener("blur", validateEmail);
inpSifre.addEventListener("blur", validateSifre);
inpKvkk.addEventListener("change", validateKvkk);
// İstersen anlık (input) doğrulama da ekleyebilirsin:
// inpEmail.addEventListener("input", () => { if (inpEmail.value.trim()) validateEmail(); });
// --- Submit handler ---
frm.addEventListener("submit", async (e) => {
e.preventDefault();
res.innerHTML = "";
clearAllErrors();
const ok = validateAll();
if (!ok) {
res.innerHTML = '<div class="alert alert-danger border">Lütfen hataları düzeltip tekrar deneyin.</div>';
return;
}
// Loading state (örnek)
btn.disabled = true;
load.style.display = "inline";
try {
// Simülasyon (gerçekte fetch/AJAX ile gönderirsin)
await new Promise(r => setTimeout(r, 900));
// FormData örneği
const fd = new FormData(frm);
const payload = Object.fromEntries(fd.entries());
res.innerHTML =
'<div class="alert alert-success border">' +
'<div class="fw-semibold">Başarılı ✅</div>' +
'<div class="small text-muted mt-1">Form doğrulandı. (Demo) Konsolu kontrol et.</div>' +
'</div>';
console.log("Gönderilecek payload:", payload);
// İstersen formu temizle:
// frm.reset();
} catch (err) {
res.innerHTML = '<div class="alert alert-danger border">Bir hata oluştu. Lütfen tekrar deneyin.</div>';
console.error(err);
} finally {
btn.disabled = false;
load.style.display = "none";
}
});
})();
3) İnce İpuçları ve Püf Noktalar
- Tek mesaj alanı: Her input altına
err_...div’i koymak, UI’yi standartlaştırır. - Blur + Submit: Blur ile “erken uyarı”, submit ile “son kontrol” en iyi kombinasyon.
- Regex’i abartma: E-posta gibi alanlarda aşırı katı regex kullanıcıyı gereksiz zorlar.
- Disable + Loading: Çift tıklayıp iki kez gönderme sorununu engellersin.
- Sunucu doğrulaması şart: JS devre dışı olabilir; güvenlik sunucuda sağlanır.
- HTML5 input type:
type="email"/type="number"mobil klavyeyi de iyileştirir.