{"id":33197,"date":"2025-10-31T01:01:45","date_gmt":"2025-10-30T22:01:45","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/"},"modified":"2025-10-31T01:01:45","modified_gmt":"2025-10-30T22:01:45","slug":"form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/","title":{"rendered":"Form Do\u011frulama Evrimi: customError&#8217;dan Sade Nesnelere Ge\u00e7i\u015f"},"content":{"rendered":"<p><body><\/p>\n<p>Web formlar\u0131, kullan\u0131c\u0131 etkile\u015fiminin ve veri toplaman\u0131n omurgas\u0131n\u0131 olu\u015ftururken, do\u011fru ve g\u00fcvenilir veri giri\u015fi her uygulaman\u0131n ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir. Kullan\u0131c\u0131lar\u0131m\u0131z\u0131n formlar\u0131 sorunsuz doldurabilmesi ve yanl\u0131\u015f veri giri\u015flerinden kaynaklanan hayal k\u0131r\u0131kl\u0131klar\u0131n\u0131 ya\u015famamas\u0131 i\u00e7in etkili form do\u011frulama mekanizmalar\u0131na sahip olmak zorunludur. Peki, bu s\u00fcre\u00e7te eski ve k\u0131s\u0131tlay\u0131c\u0131 <code>customError<\/code> yakla\u015f\u0131mlar\u0131ndan, modern ve esnek sade JavaScript nesnelerine ge\u00e7i\u015fin ard\u0131nda yatan evrim nedir?<\/p>\n<p>Form do\u011frulama, hem kullan\u0131c\u0131 deneyimi hem de veri b\u00fct\u00fcnl\u00fc\u011f\u00fc a\u00e7\u0131s\u0131ndan vazge\u00e7ilmez bir s\u00fcre\u00e7tir. Yanl\u0131\u015f girilen bir e-posta adresi, eksik b\u0131rak\u0131lan bir zorunlu alan veya hatal\u0131 formatta bir telefon numaras\u0131, sadece kullan\u0131c\u0131y\u0131 de\u011fil, ayn\u0131 zamanda uygulaman\u0131n arka u\u00e7 sistemlerini de olumsuz etkileyebilir. Bu nedenle, formlar\u0131m\u0131z\u0131n do\u011fru bilgiyi almas\u0131n\u0131 sa\u011flamak, geli\u015ftiriciler olarak en \u00f6ncelikli g\u00f6revlerimizden biridir.<\/p>\n<p>Ge\u00e7mi\u015fte, taray\u0131c\u0131lar\u0131n sundu\u011fu yerle\u015fik do\u011frulama mekanizmalar\u0131 ve JavaScript&#8217;in <code>setCustomValidity<\/code> gibi \u00f6zellikleri s\u0131kl\u0131kla kullan\u0131l\u0131yordu. \u00d6rne\u011fin, bir input alan\u0131n\u0131n ge\u00e7erlili\u011fini kontrol etmek ve \u00f6zel bir hata mesaj\u0131 g\u00f6stermek i\u00e7in a\u015fa\u011f\u0131daki gibi bir yap\u0131 tercih edilebilirdi:<\/p>\n<pre><code class=\"language-javascript\">\nconst emailInput = document.getElementById('email');\n\nemailInput.addEventListener('input', () => {\n  if (emailInput.validity.typeMismatch) {\n    emailInput.setCustomValidity('L\u00fctfen ge\u00e7erli bir e-posta adresi giriniz.');\n  } else if (emailInput.validity.valueMissing) {\n    emailInput.setCustomValidity('E-posta alan\u0131 bo\u015f b\u0131rak\u0131lamaz.');\n  } else {\n    emailInput.setCustomValidity(''); \/\/ Hata yoksa mesaj\u0131 temizle\n  }\n  emailInput.reportValidity(); \/\/ Hata mesaj\u0131n\u0131 g\u00f6ster\n});\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu yakla\u015f\u0131m, basit senaryolar i\u00e7in yeterli olsa da, karma\u015f\u0131k formlar ve modern uygulamalar\u0131n gereksinimleri kar\u015f\u0131s\u0131nda yetersiz kalmaktayd\u0131. \u0130lk olarak, <code>setCustomValidity<\/code> taray\u0131c\u0131n\u0131n kendi hata g\u00f6sterim mekanizmalar\u0131n\u0131 tetikler ve bu mekanizmalar\u0131n g\u00f6r\u00fcn\u00fcm\u00fc, stil kontrol\u00fc ve konumland\u0131rmas\u0131 \u00fczerinde s\u0131n\u0131rl\u0131 bir hakimiyetimiz olurdu. Her taray\u0131c\u0131 kendi varsay\u0131lan stilini uygulad\u0131\u011f\u0131 i\u00e7in, farkl\u0131 taray\u0131c\u0131larda tutars\u0131z bir kullan\u0131c\u0131 deneyimi ortaya \u00e7\u0131kabiliyordu. Ayr\u0131ca, ayn\u0131 anda birden fazla alan\u0131 do\u011frularken, t\u00fcm hatalar\u0131 tek bir \u00e7at\u0131 alt\u0131nda y\u00f6netmek ve kullan\u0131c\u0131ya toplu bir geri bildirim sunmak olduk\u00e7a zordu.<\/p>\n<p>Dahas\u0131, bu y\u00f6ntem genellikle alan baz\u0131nda tek bir hata mesaj\u0131n\u0131 g\u00f6stermeye odaklan\u0131r. \u00d6rne\u011fin, bir alan hem bo\u015f olamaz hem de belirli bir formatta olmal\u0131d\u0131r. <code>setCustomValidity<\/code> ile bu iki hatay\u0131 ayn\u0131 anda y\u00f6netmek ve kullan\u0131c\u0131ya her iki sorunu da bildirmek, ek mant\u0131k ve ge\u00e7ici \u00e7\u00f6z\u00fcmler gerektirebilirdi. Bu durum, \u00f6zellikle formun genel ge\u00e7erlili\u011fi \u00fczerinde tam bir kontrol sa\u011flamak isteyen geli\u015ftiriciler i\u00e7in \u00f6nemli bir k\u0131s\u0131tlamayd\u0131. Modern web uygulamalar\u0131nda ise kullan\u0131c\u0131lar\u0131n an\u0131nda ve kapsaml\u0131 geri bildirim almas\u0131 beklenir; bu da eski y\u00f6ntemlerin yeteneklerini a\u015fan bir gereksinimdir.<\/p>\n<p>Son olarak, <code>customError<\/code> yakla\u015f\u0131m\u0131, form do\u011frulama mant\u0131\u011f\u0131n\u0131 UI'dan (Kullan\u0131c\u0131 Aray\u00fcz\u00fc) ay\u0131rmay\u0131 zorla\u015ft\u0131r\u0131r. Do\u011frulama kurallar\u0131 genellikle do\u011frudan DOM manip\u00fclasyonuyla i\u00e7 i\u00e7e ge\u00e7er, bu da test edilebilirli\u011fi azalt\u0131r ve kodun yeniden kullan\u0131labilirli\u011fini s\u0131n\u0131rlar. Framework tabanl\u0131 geli\u015ftirme \u00e7a\u011f\u0131nda, bu t\u00fcr ba\u011f\u0131ml\u0131l\u0131klar kod taban\u0131n\u0131 karma\u015f\u0131kla\u015ft\u0131r\u0131r ve bak\u0131m\u0131 g\u00fc\u00e7le\u015ftirir. T\u00fcm bu s\u0131n\u0131rlamalar, geli\u015ftiricileri daha esnek, kontrol edilebilir ve \u00f6l\u00e7eklenebilir bir hata y\u00f6netimi \u00e7\u00f6z\u00fcm\u00fcne itmi\u015ftir.<\/p>\n<h2>Sade Nesnelerle Hata Y\u00f6netimine Giri\u015f: Modern Yakla\u015f\u0131m\u0131n Temelleri Nelerdir?<\/h2>\n<p><code>customError<\/code> gibi taray\u0131c\u0131ya ba\u011f\u0131ml\u0131 ve k\u0131s\u0131tlay\u0131c\u0131 yakla\u015f\u0131mlardan uzakla\u015farak, modern form do\u011frulamada \"sade JavaScript nesneleri\" kullanmak, geli\u015ftiricilere yepyeni bir esneklik ve kontrol d\u00fczeyi sunar. Peki, bu sade nesneler tam olarak nedir ve neden bu kadar pop\u00fcler hale gelmi\u015ftir? Temel olarak, bir sade nesne (plain object), formdaki her bir alan i\u00e7in hata mesajlar\u0131n\u0131 veya hata durumlar\u0131n\u0131 tutan basit bir anahtar-de\u011fer \u00e7iftleri koleksiyonudur. \u00d6rne\u011fin, bir e-posta alan\u0131ndaki hata durumu <code>errors.email<\/code> \u015feklinde, bir \u015fifre alan\u0131ndaki hata ise <code>errors.password<\/code> \u015feklinde temsil edilebilir.<\/p>\n<p>Bu yakla\u015f\u0131m\u0131n en b\u00fcy\u00fck avantajlar\u0131ndan biri, hata durumunu uygulaman\u0131z\u0131n di\u011fer par\u00e7alar\u0131ndan tamamen ba\u011f\u0131ms\u0131z bir \u015fekilde y\u00f6netebilmenizdir. Do\u011frulama mant\u0131\u011f\u0131, do\u011frudan DOM'a m\u00fcdahale etmek yerine, bu nesne \u00fczerindeki verileri manip\u00fcle eder. Bu sayede, do\u011frulama kurallar\u0131n\u0131z\u0131 kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fczden tamamen ay\u0131rabilir, b\u00f6ylece kodunuzu daha okunabilir, daha test edilebilir ve daha yeniden kullan\u0131labilir hale getirebilirsiniz. Bir ba\u015fka \u00f6nemli fayda, birden fazla hatay\u0131 ayn\u0131 anda ele alma yetene\u011fidir. <code>setCustomValidity<\/code> genellikle tek bir hata mesaj\u0131na odaklan\u0131rken, sade nesnelerle bir alan i\u00e7in birden fazla hata mesaj\u0131n\u0131 (\u00f6rne\u011fin, \"Bo\u015f b\u0131rak\u0131lamaz\" ve \"Minimum 6 karakter olmal\u0131\") kolayca tutabilir ve UI'da hepsini g\u00f6sterebilirsiniz.<\/p>\n<p>Ayr\u0131ca, sade nesnelerle hata y\u00f6netimi, herhangi bir JavaScript k\u00fct\u00fcphanesi veya \u00e7er\u00e7evesiyle (React, Vue, Angular vb.) sorunsuz bir \u015fekilde entegre edilebilir. \u00c7\u00fcnk\u00fc bu nesneler, framework'lerin veri ak\u0131\u015f\u0131 ve durum y\u00f6netimi paradigmalar\u0131na do\u011fal olarak uyum sa\u011flar. Geli\u015ftiriciler, hata nesnesini uygulaman\u0131n durumu (state) i\u00e7inde tutarak, UI'\u0131n bu duruma g\u00f6re otomatik olarak g\u00fcncellenmesini sa\u011flayabilirler. Bu, \u00f6zellikle karma\u015f\u0131k formlar ve dinamik olarak de\u011fi\u015fen alanlar i\u00e7eren uygulamalar i\u00e7in b\u00fcy\u00fck bir kolayl\u0131k sa\u011flar.<\/p>\n<p>\u0130\u015fte basit bir sade nesne tabanl\u0131 hata y\u00f6netiminin temel yap\u0131s\u0131:<\/p>\n<pre><code class=\"language-javascript\">\nlet formErrors = {}; \/\/ Ba\u015flang\u0131\u00e7ta bo\u015f bir hata nesnesi\n\nfunction validateInput(fieldName, value) {\n  let errors = []; \/\/ Bu alan i\u00e7in hatalar\u0131 topla\n\n  if (fieldName === 'username') {\n    if (!value) {\n      errors.push('Kullan\u0131c\u0131 ad\u0131 bo\u015f b\u0131rak\u0131lamaz.');\n    }\n    if (value && value.length < 3) {\n      errors.push('Kullan\u0131c\u0131 ad\u0131 en az 3 karakter olmal\u0131.');\n    }\n  }\n\n  if (fieldName === 'email') {\n    if (!value) {\n      errors.push('E-posta bo\u015f b\u0131rak\u0131lamaz.');\n    } else if (!\/\\S+@\\S+\\.\\S+\/.test(value)) {\n      errors.push('L\u00fctfen ge\u00e7erli bir e-posta adresi giriniz.');\n    }\n  }\n\n  \/\/ Hatalar varsa nesneye ekle, yoksa ilgili alan\u0131 kald\u0131r\n  if (errors.length > 0) {\n    formErrors = { ...formErrors, [fieldName]: errors };\n  } else {\n    \/\/ Hata yoksa o alan\u0131 formErrors nesnesinden kald\u0131r\n    const { [fieldName]: removed, ...rest } = formErrors;\n    formErrors = rest;\n  }\n}\n\n\/\/ \u00d6rnek kullan\u0131m:\nvalidateInput('username', '');\nvalidateInput('email', 'invalid-email');\nvalidateInput('password', '12'); \/\/ Diyelim ki password i\u00e7in de bir validasyon var\nconsole.log(formErrors);\n\/* \u00c7\u0131kt\u0131:\n{\n  username: [\"Kullan\u0131c\u0131 ad\u0131 bo\u015f b\u0131rak\u0131lamaz.\", \"Kullan\u0131c\u0131 ad\u0131 en az 3 karakter olmal\u0131.\"],\n  email: [\"L\u00fctfen ge\u00e7erli bir e-posta adresi giriniz.\"]\n}\n*\/\nvalidateInput('username', 'user123'); \/\/ Ge\u00e7erli bir kullan\u0131c\u0131 ad\u0131 girildi\nconsole.log(formErrors);\n\/* \u00c7\u0131kt\u0131:\n{\n  email: [\"L\u00fctfen ge\u00e7erli bir e-posta adresi giriniz.\"]\n}\n*\/\n    <\/pre>\n<p><\/code><\/p>\n<p>G\u00f6r\u00fcld\u00fc\u011f\u00fc gibi, <code>formErrors<\/code> nesnesi, her bir alan i\u00e7in bir dizi hata mesaj\u0131 tutarak, hata durumunu merkezi ve eri\u015filebilir bir \u015fekilde y\u00f6netmemizi sa\u011fl\u0131yor. Bu yap\u0131, hem formun anl\u0131k ge\u00e7erlili\u011fini kontrol etmeyi hem de kullan\u0131c\u0131lara do\u011fru ve kapsaml\u0131 geri bildirimler sunmay\u0131 olduk\u00e7a kolayla\u015ft\u0131r\u0131r. Ayr\u0131ca, bu yakla\u015f\u0131m sayesinde hata mesajlar\u0131n\u0131n stilini ve yerle\u015fimini tamamen kontrol edebiliriz, bu da marka tutarl\u0131l\u0131\u011f\u0131 ve kullan\u0131c\u0131 deneyimi a\u00e7\u0131s\u0131ndan \u00e7ok \u00f6nemlidir.<\/p>\n<h3>Vaka Analizi: E-ticaret Sepeti Formunda customError'dan Plain Objects'a Ge\u00e7i\u015f Nas\u0131l Yap\u0131l\u0131r?<\/h3>\n<p>Bir e-ticaret uygulamas\u0131nda, kullan\u0131c\u0131lar\u0131n sat\u0131n alma i\u015flemini tamamlamalar\u0131 i\u00e7in doldurmalar\u0131 gereken karma\u015f\u0131k bir \u00f6deme formu oldu\u011funu varsayal\u0131m. Bu form; teslimat adresi, fatura adresi, kredi kart\u0131 bilgileri, ileti\u015fim bilgileri gibi bir\u00e7ok alan\u0131 i\u00e7eriyor. Eski yakla\u015f\u0131mda, her bir alan i\u00e7in ayr\u0131 ayr\u0131 <code>setCustomValidity<\/code> kullanmak, hem kod karma\u015fas\u0131na yol a\u00e7acak hem de kullan\u0131c\u0131 deneyimini olumsuz etkileyecekti. \u00d6rne\u011fin, kullan\u0131c\u0131 formu g\u00f6ndermeye \u00e7al\u0131\u015ft\u0131\u011f\u0131nda, taray\u0131c\u0131 sadece ilk hatal\u0131 alan\u0131 i\u015faret edecek ve di\u011fer hatalar\u0131 gizli tutacakt\u0131. Bu da kullan\u0131c\u0131n\u0131n formu tekrar tekrar denemesine neden olacakt\u0131.<\/p>\n<div class=\"case-study-box\">\n<h4>Vaka Analizi: \u00d6deme Formunda Geli\u015fim<\/h4>\n<p><strong>Problem:<\/strong> Eski sistemde \u00f6deme formunda hatalar tek tek g\u00f6steriliyor, kullan\u0131c\u0131 t\u00fcm hatalar\u0131 ayn\u0131 anda g\u00f6remiyordu. Ayr\u0131ca, hata mesajlar\u0131n\u0131n g\u00f6r\u00fcn\u00fcm\u00fc taray\u0131c\u0131ya g\u00f6re de\u011fi\u015fiyordu.<\/p>\n<p><strong>Hedef:<\/strong> T\u00fcm form hatalar\u0131n\u0131 tek bir yerden y\u00f6netmek, kullan\u0131c\u0131ya an\u0131nda ve toplu geri bildirim sa\u011flamak, hata mesajlar\u0131n\u0131n stilini tamamen kontrol etmek.<\/p>\n<\/p><\/div>\n<p><strong>Eski Yakla\u015f\u0131m (<code>setCustomValidity<\/code> ile k\u0131saca):<\/strong><\/p>\n<p>Diyelim ki bir \"Adres Sat\u0131r\u0131 1\" alan\u0131 i\u00e7in basit bir do\u011frulama yap\u0131yorduk:<\/p>\n<pre><code class=\"language-html\">\n<input type=\"text\" id=\"address1\" required>\n<button type=\"submit\">G\u00f6nder<\/button>\n    <\/pre>\n<p><\/code><\/p>\n<pre><code class=\"language-javascript\"><\/pre>\n<p><\/code><br \/>\nconst addressInput = document.getElementById('address1');<br \/>\nconst form = document.querySelector('form');<\/p>\n<p>form.addEventListener('submit', (e) => {<br \/>\n  if (!addressInput.value) {<br \/>\n    addressInput.setCustomValidity('Adres alan\u0131 bo\u015f b\u0131rak\u0131lamaz.');<br \/>\n  } else {<br \/>\n    addressInput.setCustomValidity('');<br \/>\n  }<br \/>\n  if (!form.checkValidity()) {<br \/>\n    e.preventDefault(); \/\/ Formun g\u00f6nderilmesini engelle<br \/>\n  }<br \/>\n});<br \/>\n    <\/code><\/p>\n<p>Bu senaryoda, kullan\u0131c\u0131 \"Adres Sat\u0131r\u0131 1\" alan\u0131n\u0131 bo\u015f b\u0131rak\u0131rsa, taray\u0131c\u0131 taraf\u0131ndan belirlenen bir pop-up mesaj\u0131 g\u00f6r\u00fcrd\u00fc. Ancak \"\u015eehir\" ve \"Posta Kodu\" gibi di\u011fer zorunlu alanlar da bo\u015fsa, bu hatalar ancak \"Adres Sat\u0131r\u0131 1\" d\u00fczeltildikten sonra ortaya \u00e7\u0131kacakt\u0131.<\/p>\n<p><strong>Yeni Yakla\u015f\u0131m (Sade Nesnelerle):<\/strong><\/p>\n<p>\u015eimdi ayn\u0131 form i\u00e7in sade nesnelerle hata y\u00f6netimini uygulayal\u0131m. T\u00fcm hatalar\u0131 i\u00e7eren merkezi bir <code>errors<\/code> nesnesi tutaca\u011f\u0131z:<\/p>\n<pre><code class=\"language-html\">\n<form id=\"checkoutForm\">\n  <div>\n    <label for=\"address1\">Adres Sat\u0131r\u0131 1:<\/label>\n    <input type=\"text\" id=\"address1\" name=\"address1\">\n    <div class=\"error-message\" id=\"error-address1\"><\/div>\n  <\/div>\n  <div>\n    <label for=\"city\">\u015eehir:<\/label>\n    <input type=\"text\" id=\"city\" name=\"city\">\n    <div class=\"error-message\" id=\"error-city\"><\/div>\n  <\/div>\n  <div>\n    <label for=\"zipCode\">Posta Kodu:<\/label>\n    <input type=\"text\" id=\"zipCode\" name=\"zipCode\">\n    <div class=\"error-message\" id=\"error-zipCode\"><\/div>\n  <\/div>\n  <button type=\"submit\">\u00d6deme Yap<\/button>\n<\/form>\n    <\/pre>\n<p><\/code><\/p>\n<pre><code class=\"language-javascript\"><\/pre>\n<p><\/code><br \/>\nconst checkoutForm = document.getElementById('checkoutForm');<br \/>\nlet formErrors = {}; \/\/ T\u00fcm hatalar\u0131 tutacak merkezi nesne<\/p>\n<p>function validateField(fieldName, value) {<br \/>\n  let fieldErrors = [];<\/p>\n<p>  switch (fieldName) {<br \/>\n    case 'address1':<br \/>\n      if (!value.trim()) {<br \/>\n        fieldErrors.push('Adres Sat\u0131r\u0131 1 bo\u015f b\u0131rak\u0131lamaz.');<br \/>\n      }<br \/>\n      break;<br \/>\n    case 'city':<br \/>\n      if (!value.trim()) {<br \/>\n        fieldErrors.push('\u015eehir bo\u015f b\u0131rak\u0131lamaz.');<br \/>\n      }<br \/>\n      break;<br \/>\n    case 'zipCode':<br \/>\n      if (!value.trim()) {<br \/>\n        fieldErrors.push('Posta Kodu bo\u015f b\u0131rak\u0131lamaz.');<br \/>\n      } else if (!\/^\\d{5}$\/.test(value)) {<br \/>\n        fieldErrors.push('L\u00fctfen 5 haneli ge\u00e7erli bir posta kodu giriniz.');<br \/>\n      }<br \/>\n      break;<br \/>\n    \/\/ Di\u011fer alanlar i\u00e7in validasyon kurallar\u0131...<br \/>\n  }<br \/>\n  return fieldErrors;<br \/>\n}<\/p>\n<p>function displayErrors() {<br \/>\n  \/\/ \u00d6nceki t\u00fcm hata mesajlar\u0131n\u0131 temizle<br \/>\n  document.querySelectorAll('.error-message').forEach(el => el.textContent = '');<\/p>\n<p>  \/\/ Yeni hatalar\u0131 g\u00f6ster<br \/>\n  for (const fieldName in formErrors) {<br \/>\n    const errorMessages = formErrors[fieldName];<br \/>\n    const errorDiv = document.getElementById(<code>error-${fieldName}<\/code>);<br \/>\n    if (errorDiv && errorMessages.length > 0) {<br \/>\n      errorDiv.textContent = errorMessages.join(' '); \/\/ Birden fazla hatay\u0131 tek bir sat\u0131rda g\u00f6ster<br \/>\n      errorDiv.style.color = 'red'; \/\/ Hata mesajlar\u0131n\u0131 k\u0131rm\u0131z\u0131 yap<br \/>\n    }<br \/>\n  }<br \/>\n}<\/p>\n<p>checkoutForm.addEventListener('input', (e) => {<br \/>\n  const { name, value } = e.target;<br \/>\n  const errors = validateField(name, value);<\/p>\n<p>  if (errors.length > 0) {<br \/>\n    formErrors = { ...formErrors, [name]: errors };<br \/>\n  } else {<br \/>\n    \/\/ Hata yoksa, ilgili alan\u0131 hata nesnesinden kald\u0131r<br \/>\n    const { [name]: removed, ...rest } = formErrors;<br \/>\n    formErrors = rest;<br \/>\n  }<br \/>\n  displayErrors(); \/\/ Her inputta hatalar\u0131 g\u00fcncelle<br \/>\n});<\/p>\n<p>checkoutForm.addEventListener('submit', (e) => {<br \/>\n  e.preventDefault(); \/\/ Formun varsay\u0131lan g\u00f6nderimini engelle<\/p>\n<p>  \/\/ T\u00fcm alanlar\u0131 do\u011frulayal\u0131m<br \/>\n  const formData = new FormData(checkoutForm);<br \/>\n  formErrors = {}; \/\/ Her submit'te hatalar\u0131 s\u0131f\u0131rla<\/p>\n<p>  for (let [name, value] of formData.entries()) {<br \/>\n    const errors = validateField(name, value);<br \/>\n    if (errors.length > 0) {<br \/>\n      formErrors = { ...formErrors, [name]: errors };<br \/>\n    }<br \/>\n  }<\/p>\n<p>  displayErrors(); \/\/ T\u00fcm hatalar\u0131 g\u00f6ster<\/p>\n<p>  if (Object.keys(formErrors).length === 0) {<br \/>\n    alert('Form ba\u015far\u0131yla g\u00f6nderildi!');<br \/>\n    \/\/ Ger\u00e7ek bir uygulamada burada sunucuya veri g\u00f6nderilir.<br \/>\n  } else {<br \/>\n    alert('L\u00fctfen t\u00fcm hatalar\u0131 d\u00fczeltin.');<br \/>\n  }<br \/>\n});<br \/>\n    <\/code><\/p>\n<p>Bu yeni yakla\u015f\u0131mda, kullan\u0131c\u0131 formu g\u00f6ndermeye \u00e7al\u0131\u015ft\u0131\u011f\u0131nda veya bir alan\u0131 doldurdu\u011funda, <code>formErrors<\/code> nesnesi g\u00fcncellenir ve <code>displayErrors<\/code> fonksiyonu t\u00fcm hatalar\u0131 ilgili alanlar\u0131n alt\u0131nda ayn\u0131 anda g\u00f6sterir. Kullan\u0131c\u0131, t\u00fcm hatalar\u0131 tek bir bak\u0131\u015fta g\u00f6rebilir ve onlar\u0131 gidermek i\u00e7in harekete ge\u00e7ebilir. Bu, kullan\u0131c\u0131 deneyimini \u00f6nemli \u00f6l\u00e7\u00fcde iyile\u015ftirir ve formun daha h\u0131zl\u0131 tamamlanmas\u0131n\u0131 sa\u011flar. Ayr\u0131ca, hata mesajlar\u0131n\u0131n stilini CSS ile tamamen kontrol edebiliriz, bu da marka tutarl\u0131l\u0131\u011f\u0131 i\u00e7in b\u00fcy\u00fck bir avantajd\u0131r.<\/p>\n<h2>Ad\u0131m Ad\u0131m Uygulama: JavaScript ile Dinamik Form Do\u011frulama Nas\u0131l Geli\u015ftirilir?<\/h2>\n<p>Modern web geli\u015ftirmenin vazge\u00e7ilmez bir par\u00e7as\u0131 olan dinamik form do\u011frulama, kullan\u0131c\u0131lar\u0131n formlar\u0131 daha verimli ve hatas\u0131z doldurmalar\u0131na olanak tan\u0131r. Sade nesnelerle bu s\u00fcreci nas\u0131l ad\u0131m ad\u0131m in\u015fa edebilece\u011fimize yak\u0131ndan bakal\u0131m. \u0130lk olarak, HTML yap\u0131m\u0131z\u0131 olu\u015ftural\u0131m. Bu yap\u0131, her bir input alan\u0131 i\u00e7in bir <code><label><\/code>, bir <code><input><\/code> ve hata mesajlar\u0131n\u0131n g\u00f6sterilece\u011fi \u00f6zel bir <code><\/p>\n<div><\/code> i\u00e7erecektir.<\/p>\n<pre><code class=\"language-html\">\n<form id=\"registrationForm\" class=\"form-container\">\n  <div class=\"form-group\">\n    <label for=\"username\">Kullan\u0131c\u0131 Ad\u0131:<\/label>\n    <input type=\"text\" id=\"username\" name=\"username\">\n    <div class=\"error-text\" id=\"error-username\"><\/div>\n  <\/div>\n\n  <div class=\"form-group\">\n    <label for=\"email\">E-posta:<\/label>\n    <input type=\"email\" id=\"email\" name=\"email\">\n    <div class=\"error-text\" id=\"error-email\"><\/div>\n  <\/div>\n\n  <div class=\"form-group\">\n    <label for=\"password\">\u015eifre:<\/label>\n    <input type=\"password\" id=\"password\" name=\"password\">\n    <div class=\"error-text\" id=\"error-password\"><\/div>\n  <\/div>\n\n  <div class=\"form-group\">\n    <label for=\"confirmPassword\">\u015eifre Tekrar:<\/label>\n    <input type=\"password\" id=\"confirmPassword\" name=\"confirmPassword\">\n    <div class=\"error-text\" id=\"error-confirmPassword\"><\/div>\n  <\/div>\n\n  <button type=\"submit\">Kay\u0131t Ol<\/button>\n<\/form>\n    <\/pre>\n<p><\/code><\/p>\n<p>\u015eimdi JavaScript k\u0131sm\u0131na ge\u00e7elim. \u0130lk olarak, t\u00fcm form hatalar\u0131n\u0131 tek bir JavaScript nesnesinde saklayaca\u011f\u0131z. Bu nesne, anahtar olarak alan\u0131n ad\u0131n\u0131 ve de\u011fer olarak o alanla ilgili hata mesajlar\u0131n\u0131n bir dizisini tutacak.<\/p>\n<pre><code class=\"language-javascript\">\nconst registrationForm = document.getElementById('registrationForm');\nlet formErrors = {}; \/\/ Hatalar\u0131 tutacak merkezi nesne\n\n\/\/ 1. Alan bazl\u0131 do\u011frulama fonksiyonu\nfunction validateField(fieldName, value, allFormData) {\n  let fieldErrors = [];\n\n  switch (fieldName) {\n    case 'username':\n      if (!value.trim()) {\n        fieldErrors.push('Kullan\u0131c\u0131 ad\u0131 bo\u015f b\u0131rak\u0131lamaz.');\n      } else if (value.length < 5) {\n        fieldErrors.push('Kullan\u0131c\u0131 ad\u0131 en az 5 karakter olmal\u0131.');\n      }\n      break;\n    case 'email':\n      if (!value.trim()) {\n        fieldErrors.push('E-posta bo\u015f b\u0131rak\u0131lamaz.');\n      } else if (!\/\\S+@\\S+\\.\\S+\/.test(value)) {\n        fieldErrors.push('L\u00fctfen ge\u00e7erli bir e-posta adresi giriniz.');\n      }\n      break;\n    case 'password':\n      if (!value) {\n        fieldErrors.push('\u015eifre bo\u015f b\u0131rak\u0131lamaz.');\n      } else if (value.length < 8) {\n        fieldErrors.push('\u015eifre en az 8 karakter olmal\u0131.');\n      } else if (!\/[A-Z]\/.test(value)) {\n        fieldErrors.push('\u015eifre en az bir b\u00fcy\u00fck harf i\u00e7ermeli.');\n      } else if (!\/[0-9]\/.test(value)) {\n        fieldErrors.push('\u015eifre en az bir rakam i\u00e7ermeli.');\n      }\n      break;\n    case 'confirmPassword':\n      if (!value) {\n        fieldErrors.push('\u015eifre tekrar\u0131 bo\u015f b\u0131rak\u0131lamaz.');\n      } else if (value !== allFormData.password) { \/\/ \u015eifreyle e\u015fle\u015fme kontrol\u00fc\n        fieldErrors.push('\u015eifreler e\u015fle\u015fmiyor.');\n      }\n      break;\n  }\n  return fieldErrors;\n}\n\n\/\/ 2. Hatalar\u0131 UI'da g\u00f6sterme fonksiyonu\nfunction displayErrors() {\n  \/\/ T\u00fcm hata mesajlar\u0131n\u0131 temizle\n  document.querySelectorAll('.error-text').forEach(el => {\n    el.textContent = '';\n    el.classList.remove('active'); \/\/ CSS s\u0131n\u0131f\u0131n\u0131 kald\u0131r\n  });\n\n  \/\/ Yeni hatalar\u0131 g\u00f6ster\n  for (const fieldName in formErrors) {\n    const errorMessages = formErrors[fieldName];\n    const errorDiv = document.getElementById(<code>error-${fieldName}<\/code>);\n    if (errorDiv && errorMessages.length > 0) {\n      errorDiv.textContent = errorMessages.join(' ');\n      errorDiv.classList.add('active'); \/\/ CSS s\u0131n\u0131f\u0131 ekle\n    }\n  }\n}\n\n\/\/ 3. Form inputlar\u0131na event listener ekleyerek anl\u0131k do\u011frulama\nregistrationForm.addEventListener('input', (e) => {\n  const { name, value } = e.target;\n  \/\/ T\u00fcm form verisini alarak ili\u015fkili alanlar\u0131 da do\u011frulamak i\u00e7in\n  const allFormData = Object.fromEntries(new FormData(registrationForm).entries());\n  const errors = validateField(name, value, allFormData);\n\n  if (errors.length > 0) {\n    formErrors = { ...formErrors, [name]: errors };\n  } else {\n    \/\/ Hata yoksa, ilgili alan\u0131 hata nesnesinden kald\u0131r\n    const { [name]: removed, ...rest } = formErrors;\n    formErrors = rest;\n  }\n  displayErrors();\n});\n\n\/\/ 4. Form g\u00f6nderildi\u011finde t\u00fcm formu do\u011frulama\nregistrationForm.addEventListener('submit', (e) => {\n  e.preventDefault(); \/\/ Varsay\u0131lan g\u00f6nderimi engelle\n\n  const formData = new FormData(registrationForm);\n  const allFormData = Object.fromEntries(formData.entries());\n  formErrors = {}; \/\/ G\u00f6nderimde hatalar\u0131 s\u0131f\u0131rla\n\n  for (let [name, value] of formData.entries()) {\n    const errors = validateField(name, value, allFormData);\n    if (errors.length > 0) {\n      formErrors = { ...formErrors, [name]: errors };\n    }\n  }\n\n  displayErrors();\n\n  if (Object.keys(formErrors).length === 0) {\n    alert('Kay\u0131t ba\u015far\u0131yla tamamland\u0131!');\n    \/\/ Ger\u00e7ek bir uygulamada burada AJAX iste\u011fi ile sunucuya g\u00f6nderim yap\u0131l\u0131r\n  } else {\n    alert('L\u00fctfen formdaki hatalar\u0131 d\u00fczeltin.');\n  }\n});\n    <\/pre>\n<p><\/code><\/p>\n<div class=\"expert-tip-box\">\n<h4>Uzman \u0130pucu: Anl\u0131k Do\u011frulama ve Performans<\/h4>\n<p><code>input<\/code> olay\u0131nda her tu\u015f vuru\u015funda do\u011frulama yapmak, karma\u015f\u0131k do\u011frulama kurallar\u0131 veya \u00e7ok say\u0131da alan i\u00e7eren formlarda performans sorunlar\u0131na yol a\u00e7abilir. Bu t\u00fcr durumlarda <strong>debouncing<\/strong> tekni\u011fini kullanmak, do\u011frulama fonksiyonunun yaln\u0131zca kullan\u0131c\u0131 belirli bir s\u00fcre (\u00f6rne\u011fin 300ms) yazmay\u0131 b\u0131rakt\u0131\u011f\u0131nda \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flayarak performans\u0131 art\u0131rabilir. Bu, gereksiz i\u015flem y\u00fck\u00fcn\u00fc azalt\u0131r ve daha ak\u0131c\u0131 bir kullan\u0131c\u0131 deneyimi sunar.<\/p>\n<\/p><\/div>\n<p>Bu ad\u0131mlar, sade nesnelerle dinamik form do\u011frulamay\u0131 nas\u0131l uygulayaca\u011f\u0131n\u0131z\u0131 g\u00f6steriyor. <code>formErrors<\/code> nesnesi sayesinde, formun genel ge\u00e7erlili\u011fini ve her bir alan\u0131n hata durumunu merkezi bir yerden y\u00f6netebilir, b\u00f6ylece kullan\u0131c\u0131ya an\u0131nda ve anlaml\u0131 geri bildirimler sunabilirsiniz. Ayr\u0131ca, do\u011frulama mant\u0131\u011f\u0131n\u0131 UI'dan ay\u0131rarak kodunuzun mod\u00fclerli\u011fini ve s\u00fcrd\u00fcr\u00fclebilirli\u011fini art\u0131rm\u0131\u015f olursunuz.<\/p>\n<h3>\u0130leri D\u00fczey Teknikler: \u00c7oklu Hata Y\u00f6netimi ve Asenkron Do\u011frulama Stratejileri Nelerdir?<\/h3>\n<p>Sade nesnelerle form do\u011frulama, temel ihtiya\u00e7lar\u0131 kar\u015f\u0131laman\u0131n \u00f6tesinde, karma\u015f\u0131k senaryolar i\u00e7in de g\u00fc\u00e7l\u00fc \u00e7\u00f6z\u00fcmler sunar. \u00c7oklu hata y\u00f6netimi ve asenkron do\u011frulama, modern uygulamalarda s\u0131kl\u0131kla kar\u015f\u0131la\u015f\u0131lan ve bu yakla\u015f\u0131m\u0131n esnekli\u011fini kan\u0131tlayan iki \u00f6nemli ileri d\u00fczey tekniktir.<\/p>\n<h4>\u00c7oklu Hata Y\u00f6netimi: Bir Alanda Birden Fazla Hata Nas\u0131l G\u00f6sterilir?<\/h4>\n<p>Bir form alan\u0131, ayn\u0131 anda birden fazla do\u011frulama kural\u0131n\u0131 ihlal edebilir. \u00d6rne\u011fin, bir \u015fifre alan\u0131 hem bo\u015f olamaz, hem en az 8 karakter olmal\u0131, hem bir b\u00fcy\u00fck harf i\u00e7ermeli hem de bir say\u0131 i\u00e7ermelidir. Eski yakla\u015f\u0131mlarda bu t\u00fcr \u00e7oklu hatalar\u0131 g\u00f6stermek zorluyken, sade nesnelerle bu olduk\u00e7a basittir. Her alan i\u00e7in hata mesajlar\u0131n\u0131 bir dizi (array) i\u00e7inde tutarak, bu sorunu elegant bir \u015fekilde \u00e7\u00f6zebiliriz. Daha \u00f6nceki <code>validateField<\/code> fonksiyonumuz zaten bu prensibi kullan\u0131yordu.<\/p>\n<pre><code class=\"language-javascript\">\n\/\/ validateField fonksiyonu zaten bunu yap\u0131yordu:\n\/\/ ...\ncase 'password':\n  if (!value) {\n    fieldErrors.push('\u015eifre bo\u015f b\u0131rak\u0131lamaz.');\n  }\n  if (value && value.length < 8) {\n    fieldErrors.push('\u015eifre en az 8 karakter olmal\u0131.');\n  }\n  if (value &#038;&#038; !\/[A-Z]\/.test(value)) {\n    fieldErrors.push('\u015eifre en az bir b\u00fcy\u00fck harf i\u00e7ermeli.');\n  }\n  if (value &#038;&#038; !\/[0-9]\/.test(value)) {\n    fieldErrors.push('\u015eifre en az bir rakam i\u00e7ermeli.');\n  }\n  break;\n\/\/ ...\n    <\/pre>\n<p><\/code><\/p>\n<p><code>displayErrors<\/code> fonksiyonu da bu diziye eri\u015ferek t\u00fcm hata mesajlar\u0131n\u0131 tek bir yerde veya ayr\u0131 ayr\u0131 sat\u0131rlarda kullan\u0131c\u0131ya sunabilir. Bu sayede, kullan\u0131c\u0131 t\u00fcm sorunlar\u0131 tek bir bak\u0131\u015fta g\u00f6rebilir ve gerekli d\u00fczeltmeleri yapabilir, bu da kullan\u0131c\u0131 deneyimini \u00f6nemli \u00f6l\u00e7\u00fcde iyile\u015ftirir.<\/p>\n<h4>Asenkron Do\u011frulama Stratejileri: Sunucu Kontrolleri Nas\u0131l Entegre Edilir?<\/h4>\n<p>Baz\u0131 do\u011frulama kurallar\u0131, istemci taraf\u0131nda (taray\u0131c\u0131da) kontrol edilemez. \u00d6rne\u011fin, bir kullan\u0131c\u0131n\u0131n girdi\u011fi e-posta adresinin veritaban\u0131nda daha \u00f6nce kay\u0131tl\u0131 olup olmad\u0131\u011f\u0131n\u0131 kontrol etmek veya bir \u00fcr\u00fcn kodunun stokta olup olmad\u0131\u011f\u0131n\u0131 do\u011frulamak gibi i\u015flemler sunucu taraf\u0131nda yap\u0131lmal\u0131d\u0131r. Bu t\u00fcr \"asenkron do\u011frulama\" i\u015flemlerini sade nesnelerle y\u00f6netmek de olduk\u00e7a m\u00fcmk\u00fcnd\u00fcr.<\/p>\n<p>Asenkron do\u011frulama genellikle \u015fu ad\u0131mlar\u0131 i\u00e7erir:<\/p>\n<ol>\n<li>Kullan\u0131c\u0131 bir alan\u0131 doldurur (\u00f6rne\u011fin, e-posta).<\/li>\n<li>\u0130stemci, bu de\u011feri sunucuya bir API iste\u011fi ile g\u00f6nderir.<\/li>\n<li>Sunucu, de\u011feri do\u011frular ve bir yan\u0131t (ge\u00e7erli\/ge\u00e7ersiz, hata mesaj\u0131) d\u00f6nd\u00fcr\u00fcr.<\/li>\n<li>\u0130stemci, sunucudan gelen yan\u0131ta g\u00f6re hata nesnesini g\u00fcnceller.<\/li>\n<\/ol>\n<p>Bu s\u00fcre\u00e7, kullan\u0131c\u0131n\u0131n yazmay\u0131 bitirmesini beklemek i\u00e7in genellikle <strong>debouncing<\/strong> ile birle\u015ftirilir. \u0130\u015fte bir e-posta alan\u0131n\u0131n sunucuda benzersiz olup olmad\u0131\u011f\u0131n\u0131 kontrol eden bir \u00f6rnek:<\/p>\n<pre><code class=\"language-javascript\">\nlet formErrors = {}; \/\/ Merkezi hata nesnesi\nlet debounceTimer;\n\nasync function checkEmailAvailability(email) {\n  try {\n    const response = await fetch(<code>\/api\/check-email?email=${email}<\/code>);\n    const data = await response.json(); \/\/ { isAvailable: boolean, message?: string }\n\n    if (!data.isAvailable) {\n      return ['Bu e-posta adresi zaten kullan\u0131l\u0131yor.'];\n    }\n    return []; \/\/ Hata yok\n  } catch (error) {\n    console.error('E-posta kontrol\u00fcnde hata:', error);\n    return ['E-posta kontrol edilirken bir sorun olu\u015ftu.'];\n  }\n}\n\n\/\/ Yeni bir validateField fonksiyonu (asenkron do\u011frulamay\u0131 da kapsayacak \u015fekilde)\nasync function validateFieldAsync(fieldName, value, allFormData) {\n  let fieldErrors = validateField(fieldName, value, allFormData); \/\/ Senkron do\u011frulamalar\u0131 yap\n\n  if (fieldName === 'email' && fieldErrors.length === 0) { \/\/ Sadece ge\u00e7erli senkron emailler i\u00e7in async kontrol\n    \/\/ Kullan\u0131c\u0131n\u0131n yazmay\u0131 bitirmesini bekle\n    clearTimeout(debounceTimer);\n    return new Promise(resolve => {\n      debounceTimer = setTimeout(async () => {\n        const asyncErrors = await checkEmailAvailability(value);\n        resolve([...fieldErrors, ...asyncErrors]); \/\/ Mevcut hatalara asenkron hatalar\u0131 ekle\n      }, 500); \/\/ 500ms sonra kontrol et\n    });\n  }\n\n  return fieldErrors;\n}\n\n\/\/ Event listener'\u0131 buna g\u00f6re g\u00fcncelleyelim\nregistrationForm.addEventListener('input', async (e) => {\n  const { name, value } = e.target;\n  const allFormData = Object.fromEntries(new FormData(registrationForm).entries());\n  \n  \/\/ Asenkron validateFieldAsync'i \u00e7a\u011f\u0131r\n  const errors = await validateFieldAsync(name, value, allFormData);\n\n  if (errors.length > 0) {\n    formErrors = { ...formErrors, [name]: errors };\n  } else {\n    const { [name]: removed, ...rest } = formErrors;\n    formErrors = rest;\n  }\n  displayErrors();\n});\n\n\/\/ Submit listener'\u0131nda da asenkron do\u011frulama beklemeyi unutmay\u0131n\nregistrationForm.addEventListener('submit', async (e) => {\n  e.preventDefault();\n\n  const formData = new FormData(registrationForm);\n  const allFormData = Object.fromEntries(formData.entries());\n  formErrors = {};\n\n  const fieldValidationPromises = [];\n\n  for (let [name, value] of formData.entries()) {\n    fieldValidationPromises.push(\n      validateFieldAsync(name, value, allFormData).then(errors => {\n        if (errors.length > 0) {\n          formErrors = { ...formErrors, [name]: errors };\n        }\n      })\n    );\n  }\n\n  await Promise.all(fieldValidationPromises); \/\/ T\u00fcm asenkron do\u011frulamalar\u0131n bitmesini bekle\n\n  displayErrors();\n\n  if (Object.keys(formErrors).length === 0) {\n    alert('Kay\u0131t ba\u015far\u0131yla tamamland\u0131!');\n  } else {\n    alert('L\u00fctfen formdaki hatalar\u0131 d\u00fczeltin.');\n  }\n});\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>checkEmailAvailability<\/code> fonksiyonu sunucuya bir istek g\u00f6nderir. <code>validateFieldAsync<\/code> ise bu asenkron i\u015flemi bekler ve sonu\u00e7lar\u0131 d\u00f6nd\u00fcr\u00fcr. Form g\u00f6nderildi\u011finde, <code>Promise.all<\/code> kullanarak t\u00fcm alanlar\u0131n asenkron do\u011frulamalar\u0131n\u0131n tamamlanmas\u0131n\u0131 bekleriz. Bu, sade nesnelerin asenkron i\u015flemleri de nas\u0131l kolayca entegre edebildi\u011fini ve karma\u015f\u0131k do\u011frulama senaryolar\u0131nda dahi esneklik sa\u011flad\u0131\u011f\u0131n\u0131 g\u00f6stermektedir.<\/p>\n<h2>Kullan\u0131c\u0131 Deneyimi ve Eri\u015filebilirlik: Hata Mesajlar\u0131 Nas\u0131l Daha Anla\u015f\u0131l\u0131r Hale Getirilir?<\/h2>\n<p>Form do\u011frulama sadece teknik bir gereklilik de\u011fil, ayn\u0131 zamanda kullan\u0131c\u0131 deneyiminin (UX) ve eri\u015filebilirli\u011fin (Accessibility) temel bir par\u00e7as\u0131d\u0131r. Hata mesajlar\u0131n\u0131n do\u011fru, anla\u015f\u0131l\u0131r ve eri\u015filebilir bir \u015fekilde sunulmas\u0131, kullan\u0131c\u0131lar\u0131n formlar\u0131 sorunsuz bir \u015fekilde tamamlamalar\u0131 i\u00e7in kritik \u00f6neme sahiptir. Sade nesnelerle hata y\u00f6netimi, bu kontrol\u00fc geli\u015ftiricinin eline verirken, ayn\u0131 zamanda kullan\u0131c\u0131 dostu hata mesajlar\u0131 tasarlama f\u0131rsat\u0131 sunar.<\/p>\n<h3>Anla\u015f\u0131l\u0131r ve Eyleme Y\u00f6nelik Hata Mesajlar\u0131<\/h3>\n<p>Hata mesajlar\u0131, kullan\u0131c\u0131y\u0131 azarlayan veya teknik jargona bo\u011fan ifadelerden ziyade, nazik, a\u00e7\u0131klay\u0131c\u0131 ve \u00e7\u00f6z\u00fcm odakl\u0131 olmal\u0131d\u0131r. \u00d6rne\u011fin, \"Ge\u00e7ersiz giri\u015f\" yerine \"E-posta adresiniz hatal\u0131 g\u00f6r\u00fcn\u00fcyor, l\u00fctfen kontrol edin\" veya \"\u015eifre \u00e7ok k\u0131sa\" yerine \"\u015eifreniz en az 8 karakter olmal\u0131\" demek, kullan\u0131c\u0131ya ne yapmas\u0131 gerekti\u011fini a\u00e7\u0131k\u00e7a belirtir ve onlar\u0131n formdaki sorunlar\u0131 daha h\u0131zl\u0131 gidermelerine yard\u0131mc\u0131 olur.<\/p>\n<ul>\n<li><strong>Spesifik olun:<\/strong> Genel ifadelerden ka\u00e7\u0131n\u0131n. Hatay\u0131 tam olarak neyin tetikledi\u011fini belirtin.<\/li>\n<li><strong>\u00c7\u00f6z\u00fcm \u00f6nerin:<\/strong> Kullan\u0131c\u0131ya hatay\u0131 nas\u0131l d\u00fczeltece\u011fi konusunda yol g\u00f6sterin.<\/li>\n<li><strong>Nazik bir dil kullan\u0131n:<\/strong> Kullan\u0131c\u0131y\u0131 su\u00e7lay\u0131c\u0131 bir ton yerine yard\u0131mc\u0131 ve anlay\u0131\u015fl\u0131 bir dil tercih edin.<\/li>\n<li><strong>Yerle\u015fimi d\u00fc\u015f\u00fcn\u00fcn:<\/strong> Hata mesajlar\u0131, ilgili input alan\u0131n\u0131n hemen alt\u0131nda ve kolayca g\u00f6r\u00fclebilecek bir yerde olmal\u0131d\u0131r.<\/li>\n<\/ul>\n<h3>Eri\u015filebilirlik (Accessibility) i\u00e7in ARIA Nitelikleri<\/h3>\n<p>Eri\u015fim teknolojileri (\u00f6rne\u011fin ekran okuyucular) kullanan ki\u015filer i\u00e7in form hatalar\u0131n\u0131n anla\u015f\u0131l\u0131r olmas\u0131 hayati \u00f6neme sahiptir. HTML'in ARIA (Accessible Rich Internet Applications) nitelikleri, bu konuda bize yard\u0131mc\u0131 olur:<\/p>\n<ul>\n<li><strong><code>aria-invalid=\"true\"<\/code>:<\/strong> Hatal\u0131 olan input alan\u0131na bu niteli\u011fi eklemek, ekran okuyuculara bu alan\u0131n ge\u00e7ersiz oldu\u011funu bildirir.<\/li>\n<li><strong><code>aria-describedby=\"ID_OF_ERROR_MESSAGE\"<\/code>:<\/strong> Hata mesaj\u0131 elementinin ID'sini input alan\u0131n\u0131n <code>aria-describedby<\/code> niteli\u011fine ba\u011flamak, ekran okuyucunun input alan\u0131 odakland\u0131\u011f\u0131nda ilgili hata mesaj\u0131n\u0131 okumas\u0131n\u0131 sa\u011flar.<\/li>\n<\/ul>\n<pre><code class=\"language-html\">\n<div class=\"form-group\">\n  <label for=\"email\">E-posta:<\/label>\n  <input type=\"email\" id=\"email\" name=\"email\" aria-invalid=\"true\" aria-describedby=\"error-email\">\n  <div class=\"error-text active\" id=\"error-email\">L\u00fctfen ge\u00e7erli bir e-posta adresi giriniz.<\/div>\n<\/div>\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu nitelikleri JavaScript ile dinamik olarak ekleyip kald\u0131rarak, eri\u015filebilirli\u011fi \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131rabiliriz.<\/p>\n<pre><code class=\"language-javascript\">\nfunction displayErrors() {\n  document.querySelectorAll('input').forEach(input => {\n    input.removeAttribute('aria-invalid');\n  });\n\n  document.querySelectorAll('.error-text').forEach(el => {\n    el.textContent = '';\n    el.classList.remove('active');\n  });\n\n  for (const fieldName in formErrors) {\n    const errorMessages = formErrors[fieldName];\n    const errorDiv = document.getElementById(<code>error-${fieldName}<\/code>);\n    const inputField = document.querySelector(<code>[name=\"${fieldName}\"]<\/code>);\n\n    if (errorDiv && inputField && errorMessages.length > 0) {\n      errorDiv.textContent = errorMessages.join(' ');\n      errorDiv.classList.add('active');\n      inputField.setAttribute('aria-invalid', 'true');\n      inputField.setAttribute('aria-describedby', <code>error-${fieldName}<\/code>); \/\/ \u0130li\u015fkili hata div'ini belirt\n    }\n  }\n}\n    <\/pre>\n<p><\/code><\/p>\n<h3>Mobil Uyumlu Hata Mesajlar\u0131 ve G\u00f6rsel Geri Bildirim<\/h3>\n<p>Hata mesajlar\u0131n\u0131n mobil cihazlarda da d\u00fczg\u00fcn g\u00f6r\u00fcnmesi \u00f6nemlidir. K\u00fc\u00e7\u00fck ekranlarda metinlerin okunabilir olmas\u0131, input alanlar\u0131n\u0131n hatay\u0131 belirten g\u00f6rsel i\u015faretlerle desteklenmesi kullan\u0131c\u0131 deneyimini iyile\u015ftirir. CSS ile hata durumundaki input'lara k\u0131rm\u0131z\u0131 bir kenarl\u0131k eklemek veya hata mesajlar\u0131n\u0131n font boyutunu ayarlamak gibi g\u00f6rsel ipu\u00e7lar\u0131 kullanabiliriz.<\/p>\n<pre><code class=\"language-css\">\n\/* Genel form stilleri *\/\n.form-group {\n  margin-bottom: 15px;\n}\n\nlabel {\n  display: block;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\n\ninput {\n  width: 100%;\n  padding: 10px;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  box-sizing: border-box; \/* Padding'i geni\u015fli\u011fe dahil et *\/\n}\n\n\/* Hata durumundaki input ve mesaj stilleri *\/\ninput[aria-invalid=\"true\"] {\n  border-color: red;\n  box-shadow: 0 0 0 2px rgba(255, 0, 0, 0.2);\n}\n\n.error-text {\n  color: red;\n  font-size: 0.85em;\n  margin-top: 5px;\n  display: none; \/* Varsay\u0131lan olarak gizli *\/\n}\n\n.error-text.active {\n  display: block; \/* Hata varsa g\u00f6ster *\/\n}\n\n\/* Mobil uyumluluk i\u00e7in media query *\/\n@media (max-width: 600px) {\n  .form-container {\n    padding: 15px;\n  }\n  input, button {\n    font-size: 1em; \/* Mobil cihazlarda daha b\u00fcy\u00fck font *\/\n  }\n  .error-text {\n    font-size: 0.9em; \/* Mobil i\u00e7in hata metni boyutu *\/\n  }\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu yakla\u015f\u0131mlarla, sade nesnelerle y\u00f6netilen form hatalar\u0131 sadece fonksiyonel olmakla kalmaz, ayn\u0131 zamanda kullan\u0131c\u0131lar i\u00e7in daha anla\u015f\u0131l\u0131r, eri\u015filebilir ve estetik bir deneyim sunar.<\/p>\n<h2>Performans ve Optimizasyon: B\u00fcy\u00fck Formlarda Do\u011frulama Y\u00fck\u00fcn\u00fc Nas\u0131l Hafifletebiliriz?<\/h2>\n<p>\u00d6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k formlarda, her tu\u015f vuru\u015funda veya her input de\u011fi\u015fikli\u011finde t\u00fcm formun veya ilgili alan\u0131n do\u011frulanmas\u0131, performans sorunlar\u0131na yol a\u00e7abilir. Gereksiz i\u015flem y\u00fck\u00fc, kullan\u0131c\u0131 aray\u00fcz\u00fcnde tak\u0131lmalara, gecikmelere ve genel olarak k\u00f6t\u00fc bir kullan\u0131c\u0131 deneyimine neden olabilir. Sade nesnelerle hata y\u00f6netimini optimize etmek i\u00e7in kullanabilece\u011fimiz \u00e7e\u015fitli stratejiler bulunmaktad\u0131r.<\/p>\n<h3>Debouncing ve Throttling Kullan\u0131m\u0131<\/h3>\n<p>En yayg\u0131n performans optimizasyon tekniklerinden ikisi debouncing ve throttling'dir. Bu teknikler, belirli bir fonksiyonun ne s\u0131kl\u0131kla \u00e7al\u0131\u015ft\u0131r\u0131laca\u011f\u0131n\u0131 kontrol ederek gereksiz \u00e7a\u011fr\u0131lar\u0131 engeller.<\/p>\n<ul>\n<li><strong>Debouncing:<\/strong> Bir fonksiyonun, belirli bir s\u00fcre boyunca tekrar \u00e7a\u011fr\u0131lmad\u0131\u011f\u0131nda yaln\u0131zca bir kez \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar. \u00d6rne\u011fin, kullan\u0131c\u0131 bir input alan\u0131na yazarken, do\u011frulama fonksiyonu yaln\u0131zca kullan\u0131c\u0131 yazmay\u0131 b\u0131rakt\u0131ktan (\u00f6rne\u011fin 300-500ms) sonra tetiklenir. Bu, her tu\u015f vuru\u015funda do\u011frulama yap\u0131lmas\u0131n\u0131 engeller.<\/li>\n<li><strong>Throttling:<\/strong> Bir fonksiyonun belirli bir zaman dilimi i\u00e7inde en fazla bir kez \u00e7al\u0131\u015fmas\u0131n\u0131 sa\u011flar. \u00d6rne\u011fin, bir scroll olay\u0131nda her piksel hareketinde de\u011fil, her 100ms'de bir fonksiyonun \u00e7al\u0131\u015fmas\u0131 gibi. Form do\u011frulamada daha az kullan\u0131l\u0131r ancak belirli senaryolarda faydal\u0131 olabilir.<\/li>\n<\/ul>\n<pre><code class=\"language-javascript\">\n\/\/ Debounce fonksiyonu\nfunction debounce(func, delay) {\n  let timeout;\n  return function(...args) {\n    const context = this;\n    clearTimeout(timeout);\n    timeout = setTimeout(() => func.apply(context, args), delay);\n  };\n}\n\n\/\/ Input event listener'\u0131n\u0131 debounce ile saral\u0131m\nregistrationForm.addEventListener('input', debounce(async (e) => {\n  const { name, value } = e.target;\n  const allFormData = Object.fromEntries(new FormData(registrationForm).entries());\n  \n  const errors = await validateFieldAsync(name, value, allFormData); \/\/ Asenkron validasyon da olabilir\n\n  if (errors.length > 0) {\n    formErrors = { ...formErrors, [name]: errors };\n  } else {\n    const { [name]: removed, ...rest } = formErrors;\n    formErrors = rest;\n  }\n  displayErrors();\n}, 300)); \/\/ 300 milisaniye gecikme\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu sayede, kullan\u0131c\u0131 h\u0131zla yazarken do\u011frulama fonksiyonu gereksiz yere \u00e7al\u0131\u015fmayacak, bu da kaynak t\u00fcketimini azaltacakt\u0131r.<\/p>\n<h3>Tembel Do\u011frulama (Lazy Validation)<\/h3>\n<p>Her alan\u0131n her zaman do\u011frulanmas\u0131na gerek yoktur. \"Tembel do\u011frulama\" yakla\u015f\u0131m\u0131nda, bir alan\u0131n do\u011frulama i\u015flemi sadece belirli ko\u015fullar alt\u0131nda (\u00f6rne\u011fin, kullan\u0131c\u0131 input alan\u0131ndan ayr\u0131ld\u0131\u011f\u0131nda, formu g\u00f6ndermeye \u00e7al\u0131\u015ft\u0131\u011f\u0131nda veya hata d\u00fczeltildi\u011finde) tetiklenir. Bu, \u00f6zellikle \u00e7ok say\u0131da alan\u0131 olan veya karma\u015f\u0131k do\u011frulama kurallar\u0131na sahip formlarda yararl\u0131 olabilir. Kullan\u0131c\u0131 input alan\u0131n\u0131 doldurmaya ba\u015flamadan \u00f6nce hata g\u00f6stermemek, daha az m\u00fcdahaleci bir deneyim sunar.<\/p>\n<ul>\n<li><strong><code>onBlur<\/code> do\u011frulama:<\/strong> Kullan\u0131c\u0131 bir input alan\u0131n\u0131 terk etti\u011finde (focus kaybetti\u011finde) do\u011frulama tetiklenir. Bu, alana \u00f6zel anl\u0131k geri bildirim sa\u011flar.<\/li>\n<li><strong>Submit \u00fczerinde do\u011frulama:<\/strong> Formun tamam\u0131 sadece kullan\u0131c\u0131 \"G\u00f6nder\" butonuna t\u0131klad\u0131\u011f\u0131nda do\u011frulan\u0131r. Bu, anl\u0131k geri bildirim olmamas\u0131na ra\u011fmen, daha az i\u015flem y\u00fck\u00fc anlam\u0131na gelebilir. Genellikle her iki y\u00f6ntemin bir kombinasyonu kullan\u0131l\u0131r: <code>onBlur<\/code> ile alan baz\u0131nda, <code>onSubmit<\/code> ile t\u00fcm formun nihai do\u011frulamas\u0131.<\/li>\n<\/ul>\n<h3>Par\u00e7al\u0131 Do\u011frulama (Partial Validation)<\/h3>\n<p>\u00c7ok katmanl\u0131 formlarda veya sihirbaz benzeri ad\u0131ml\u0131 formlarda, her ad\u0131mda sadece ilgili alanlar\u0131n do\u011frulanmas\u0131 ve bir sonraki ad\u0131ma ge\u00e7meden \u00f6nce o ad\u0131m\u0131n ge\u00e7erlili\u011finin kontrol edilmesi, performans a\u00e7\u0131s\u0131ndan mant\u0131kl\u0131 olabilir. T\u00fcm formun her ad\u0131mda do\u011frulanmas\u0131na gerek yoktur. Sade nesnelerle hata y\u00f6netimi, <code>formErrors<\/code> nesnesini sadece o anki ad\u0131m\u0131n alanlar\u0131n\u0131 i\u00e7erecek \u015fekilde kolayca filtrelemeye olanak tan\u0131r.<\/p>\n<p>Bu optimizasyon tekniklerini birle\u015ftirerek, b\u00fcy\u00fck ve karma\u015f\u0131k formlarda bile ak\u0131c\u0131 ve performansl\u0131 bir do\u011frulama deneyimi sunabiliriz. Sade nesneler, bu t\u00fcr teknikleri uygulamak i\u00e7in gereken esnek ve veri odakl\u0131 yap\u0131y\u0131 zaten sa\u011flad\u0131\u011f\u0131 i\u00e7in, geli\u015ftiricilerin i\u015fini \u00f6nemli \u00f6l\u00e7\u00fcde kolayla\u015ft\u0131r\u0131r.<\/p>\n<h2>Sonu\u00e7: Modern Form Do\u011frulama Yakla\u015f\u0131m\u0131n\u0131n Gelece\u011fi Ne Y\u00f6nde Evriliyor?<\/h2>\n<p>Form do\u011frulama, web geli\u015ftirmenin temel ta\u015flar\u0131ndan biri olmaya devam ederken, uyguland\u0131\u011f\u0131 y\u00f6ntemler zamanla \u00f6nemli bir evrim ge\u00e7irdi. G\u00f6rd\u00fc\u011f\u00fcm\u00fcz gibi, taray\u0131c\u0131ya ba\u011f\u0131ml\u0131 <code>customError<\/code> yakla\u015f\u0131mlar\u0131n\u0131n k\u0131s\u0131tlamalar\u0131ndan, esnek ve g\u00fc\u00e7l\u00fc sade JavaScript nesnelerine ge\u00e7i\u015f, geli\u015ftiricilere daha fazla kontrol, daha iyi test edilebilirlik ve \u00fcst\u00fcn bir kullan\u0131c\u0131 deneyimi sunmu\u015ftur. Bu modern yakla\u015f\u0131m sayesinde, hata mesajlar\u0131n\u0131n stilini ve konumunu tam olarak y\u00f6netebilir, \u00e7oklu hatalar\u0131 kolayca ele alabilir ve asenkron do\u011frulama gibi karma\u015f\u0131k senaryolar\u0131 bile sorunsuzca entegre edebiliriz.<\/p>\n<p>Sade nesnelerin kullan\u0131m\u0131, form do\u011frulama mant\u0131\u011f\u0131n\u0131 UI'dan ay\u0131rarak kodun mod\u00fclerli\u011fini art\u0131r\u0131r. Bu ayr\u0131m, \u00f6zellikle React, Vue veya Angular gibi modern \u00f6n y\u00fcz \u00e7er\u00e7eveleriyle \u00e7al\u0131\u015f\u0131rken kritik \u00f6neme sahiptir. Durum y\u00f6netimiyle entegre olabilen bu yap\u0131, form verilerinin ve hata durumlar\u0131n\u0131n \u00f6ng\u00f6r\u00fclebilir ve y\u00f6netilebilir olmas\u0131n\u0131 sa\u011flar. Ayr\u0131ca, eri\u015filebilirlik (ARIA nitelikleri) ve mobil uyumluluk gibi kullan\u0131c\u0131 odakl\u0131 \u00f6zelliklerin uygulanmas\u0131n\u0131 da kolayla\u015ft\u0131r\u0131r, bu da daha kapsay\u0131c\u0131 ve kullan\u0131c\u0131 dostu uygulamalar\u0131n \u00f6n\u00fcn\u00fc a\u00e7ar.<\/p>\n<p>Gelecekte, form do\u011frulaman\u0131n evrimi muhtemelen daha da soyutlanm\u0131\u015f ve bildirimsel yakla\u015f\u0131mlara do\u011fru devam edecektir. Yup, Zod, Joi gibi schema tabanl\u0131 do\u011frulama k\u00fct\u00fcphaneleri, sade nesne mant\u0131\u011f\u0131n\u0131 daha \u00fcst bir seviyeye ta\u015f\u0131yarak, do\u011frulama kurallar\u0131n\u0131 ayr\u0131 bir \u015fema tan\u0131m\u0131 olarak belirlememizi sa\u011flar. Bu k\u00fct\u00fcphaneler, hem istemci taraf\u0131nda hem de sunucu taraf\u0131nda ayn\u0131 do\u011frulama mant\u0131\u011f\u0131n\u0131 kullanma olana\u011f\u0131 sunarak \"full-stack\" do\u011frulama senaryolar\u0131n\u0131 basitle\u015ftirir. Bu da, geli\u015ftirme s\u00fcrecini h\u0131zland\u0131r\u0131rken tutarl\u0131l\u0131\u011f\u0131 art\u0131r\u0131r.<\/p>\n<p>\u00d6zetle, <code>customError<\/code>'a elveda deyip sade nesnelere ho\u015f geldiniz demek, sadece bir teknik tercih de\u011fil, daha sa\u011flam, \u00f6l\u00e7eklenebilir ve kullan\u0131c\u0131 odakl\u0131 web uygulamalar\u0131 in\u015fa etme yolunda at\u0131lm\u0131\u015f stratejik bir ad\u0131md\u0131r. Bu yakla\u015f\u0131m, modern web geli\u015ftiricilerinin ara\u00e7 kutusunun vazge\u00e7ilmez bir par\u00e7as\u0131 olmaya devam edecektir.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<ul>\n<li>\n            <strong>S1: <code>setCustomValidity<\/code> tamamen kullan\u0131lmaz m\u0131 oldu?<\/strong><\/p>\n<p><strong>C:<\/strong> Hay\u0131r, tamamen kullan\u0131lmaz olmad\u0131. Basit ve k\u00fc\u00e7\u00fck formlar veya belirli taray\u0131c\u0131 varsay\u0131lan davran\u0131\u015flar\u0131n\u0131 h\u0131zl\u0131ca kullanmak istedi\u011finiz durumlar i\u00e7in hala ge\u00e7erli bir se\u00e7enektir. Ancak karma\u015f\u0131k formlar, \u00f6zel UI tasar\u0131m\u0131 veya framework entegrasyonu gerektiren senaryolarda sade nesnelerle hata y\u00f6netimi \u00e7ok daha esneklik ve kontrol sa\u011flar.<\/p>\n<\/li>\n<li>\n            <strong>S2: Plain objects yakla\u015f\u0131m\u0131 her projeye uyar m\u0131?<\/strong><\/p>\n<p><strong>C:<\/strong> Evet, sade nesnelerle hata y\u00f6netimi temel bir JavaScript prensibine dayand\u0131\u011f\u0131 i\u00e7in neredeyse her projeye uyarlanabilir. \u0130ster vanilla JavaScript, ister React, Vue, Angular gibi bir \u00e7er\u00e7eve kullan\u0131n, bu yakla\u015f\u0131m veri odakl\u0131 yap\u0131s\u0131 sayesinde kolayca entegre edilebilir ve \u00f6l\u00e7eklenebilir.<\/p>\n<\/li>\n<li>\n            <strong>S3: Asenkron validasyonun performans \u00fczerindeki etkisi nedir?<\/strong><\/p>\n<p><strong>C:<\/strong> Asenkron validasyon, sunucuya yap\u0131lan a\u011f istekleri nedeniyle ek gecikme yaratabilir. Bu etkiyi azaltmak i\u00e7in debouncing kullanmak, gereksiz API \u00e7a\u011fr\u0131lar\u0131n\u0131 \u00f6nlemek ve sunucu taraf\u0131nda h\u0131zl\u0131 yan\u0131tlar sa\u011flamak \u00f6nemlidir. Ayr\u0131ca, kritik olmayan asenkron do\u011frulamalar\u0131 form g\u00f6nderimine kadar ertelemek de bir strateji olabilir.<\/p>\n<\/li>\n<li>\n            <strong>S4: Hata mesajlar\u0131n\u0131 uluslararas\u0131 hale getirmek i\u00e7in ne yapmal\u0131y\u0131m?<\/strong><\/p>\n<p><strong>C:<\/strong> Hata mesajlar\u0131n\u0131 sade nesnelerde do\u011frudan string olarak tutmak yerine, bir anahtar (key) olarak tutabilir ve bu anahtar\u0131 bir \u00e7eviri (i18n) k\u00fct\u00fcphanesi ile e\u015fle\u015ftirebilirsiniz. \u00d6rne\u011fin, <code>errors: { email: ['email.invalidFormat'] }<\/code> \u015feklinde tutarak, <code>email.invalidFormat<\/code> anahtar\u0131n\u0131 kullan\u0131c\u0131n\u0131n diline g\u00f6re \u00e7eviren bir fonksiyonla render edebilirsiniz.<\/p>\n<\/li>\n<li>\n            <strong>S5: React\/Vue gibi framework'lerle bu yakla\u015f\u0131m\u0131 nas\u0131l entegre edebilirim?<\/strong><\/p>\n<p><strong>C:<\/strong> Modern framework'lerde bu yakla\u015f\u0131m \u00e7ok daha do\u011fal durur. Hata nesnesini framework'\u00fcn durum y\u00f6netimi (state) i\u00e7erisinde (\u00f6rn. React'ta <code>useState<\/code>, Vue'da <code>data<\/code>) tutars\u0131n\u0131z. Input alanlar\u0131n\u0131n <code>onChange<\/code> olay\u0131nda <code>validateField<\/code> fonksiyonunu \u00e7a\u011f\u0131r\u0131r, durum nesnesini g\u00fcnceller ve UI'\u0131n otomatik olarak g\u00fcncellenmesini beklersiniz. Form g\u00f6nderiminde de t\u00fcm formu do\u011frulay\u0131p nihai hata durumunu g\u00fcncellemi\u015f olursunuz. \u00c7o\u011fu framework zaten bu t\u00fcr durum y\u00f6netimi i\u00e7in optimize edilmi\u015f ara\u00e7lar sunar.<\/p>\n<\/li>\n<\/ul>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Web formlar\u0131, kullan\u0131c\u0131 etkile\u015fiminin ve veri toplaman\u0131n omurgas\u0131n\u0131 olu\u015ftururken, do\u011fru ve g\u00fcvenilir veri giri\u015fi her uygulaman\u0131n ba\u015far\u0131s\u0131 i\u00e7in&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-33197","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Form Do\u011frulama Evrimi: customError&#039;dan Sade Nesnelere Ge\u00e7i\u015f<\/title>\n<meta name=\"description\" content=\"Web formlar\u0131, kullan\u0131c\u0131 etkile\u015fiminin ve veri toplaman\u0131n omurgas\u0131n\u0131 olu\u015ftururken, do\u011fru ve g\u00fcvenilir veri giri\u015fi her uygulaman\u0131n ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir. Kullan\u0131c\u0131lar\u0131m\u0131z\u0131n formlar\u0131 sorunsuz doldurabilmesi ve yanl\u0131\u015f veri giri\u015flerinden kaynaklanan hayal k\u0131r\u0131kl\u0131klar\u0131n\u0131 ya\u015famamas\u0131 i\u00e7in etkili form do\u011frulama mekanizmalar\u0131na sahip olmak zorunludur. Peki, bu s\u00fcre\u00e7te eski ve k\u0131s\u0131tlay\u0131c\u0131 customError yakla\u015f\u0131mlar\u0131ndan, modern ve esnek sade JavaScript nesnelerine ge\u00e7i\u015fin ard\u0131nda yatan evrim nedir?\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Form Do\u011frulama Evrimi: customError&#039;dan Sade Nesnelere Ge\u00e7i\u015f\" \/>\n<meta property=\"og:description\" content=\"Web formlar\u0131, kullan\u0131c\u0131 etkile\u015fiminin ve veri toplaman\u0131n omurgas\u0131n\u0131 olu\u015ftururken, do\u011fru ve g\u00fcvenilir veri giri\u015fi her uygulaman\u0131n ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir. Kullan\u0131c\u0131lar\u0131m\u0131z\u0131n formlar\u0131 sorunsuz doldurabilmesi ve yanl\u0131\u015f veri giri\u015flerinden kaynaklanan hayal k\u0131r\u0131kl\u0131klar\u0131n\u0131 ya\u015famamas\u0131 i\u00e7in etkili form do\u011frulama mekanizmalar\u0131na sahip olmak zorunludur. Peki, bu s\u00fcre\u00e7te eski ve k\u0131s\u0131tlay\u0131c\u0131 customError yakla\u015f\u0131mlar\u0131ndan, modern ve esnek sade JavaScript nesnelerine ge\u00e7i\u015fin ard\u0131nda yatan evrim nedir?\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-30T22:01:45+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"28 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Form Do\u011frulama Evrimi: customError&#8217;dan Sade Nesnelere Ge\u00e7i\u015f\",\"datePublished\":\"2025-10-30T22:01:45+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/\"},\"wordCount\":4177,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/\",\"name\":\"Form Do\u011frulama Evrimi: customError'dan Sade Nesnelere Ge\u00e7i\u015f\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-30T22:01:45+00:00\",\"description\":\"Web formlar\u0131, kullan\u0131c\u0131 etkile\u015fiminin ve veri toplaman\u0131n omurgas\u0131n\u0131 olu\u015ftururken, do\u011fru ve g\u00fcvenilir veri giri\u015fi her uygulaman\u0131n ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir. Kullan\u0131c\u0131lar\u0131m\u0131z\u0131n formlar\u0131 sorunsuz doldurabilmesi ve yanl\u0131\u015f veri giri\u015flerinden kaynaklanan hayal k\u0131r\u0131kl\u0131klar\u0131n\u0131 ya\u015famamas\u0131 i\u00e7in etkili form do\u011frulama mekanizmalar\u0131na sahip olmak zorunludur. Peki, bu s\u00fcre\u00e7te eski ve k\u0131s\u0131tlay\u0131c\u0131 customError yakla\u015f\u0131mlar\u0131ndan, modern ve esnek sade JavaScript nesnelerine ge\u00e7i\u015fin ard\u0131nda yatan evrim nedir?\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Form Do\u011frulama Evrimi: customError&#8217;dan Sade Nesnelere Ge\u00e7i\u015f\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Form Do\u011frulama Evrimi: customError'dan Sade Nesnelere Ge\u00e7i\u015f","description":"Web formlar\u0131, kullan\u0131c\u0131 etkile\u015fiminin ve veri toplaman\u0131n omurgas\u0131n\u0131 olu\u015ftururken, do\u011fru ve g\u00fcvenilir veri giri\u015fi her uygulaman\u0131n ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir. Kullan\u0131c\u0131lar\u0131m\u0131z\u0131n formlar\u0131 sorunsuz doldurabilmesi ve yanl\u0131\u015f veri giri\u015flerinden kaynaklanan hayal k\u0131r\u0131kl\u0131klar\u0131n\u0131 ya\u015famamas\u0131 i\u00e7in etkili form do\u011frulama mekanizmalar\u0131na sahip olmak zorunludur. Peki, bu s\u00fcre\u00e7te eski ve k\u0131s\u0131tlay\u0131c\u0131 customError yakla\u015f\u0131mlar\u0131ndan, modern ve esnek sade JavaScript nesnelerine ge\u00e7i\u015fin ard\u0131nda yatan evrim nedir?","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/","og_locale":"tr_TR","og_type":"article","og_title":"Form Do\u011frulama Evrimi: customError'dan Sade Nesnelere Ge\u00e7i\u015f","og_description":"Web formlar\u0131, kullan\u0131c\u0131 etkile\u015fiminin ve veri toplaman\u0131n omurgas\u0131n\u0131 olu\u015ftururken, do\u011fru ve g\u00fcvenilir veri giri\u015fi her uygulaman\u0131n ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir. Kullan\u0131c\u0131lar\u0131m\u0131z\u0131n formlar\u0131 sorunsuz doldurabilmesi ve yanl\u0131\u015f veri giri\u015flerinden kaynaklanan hayal k\u0131r\u0131kl\u0131klar\u0131n\u0131 ya\u015famamas\u0131 i\u00e7in etkili form do\u011frulama mekanizmalar\u0131na sahip olmak zorunludur. Peki, bu s\u00fcre\u00e7te eski ve k\u0131s\u0131tlay\u0131c\u0131 customError yakla\u015f\u0131mlar\u0131ndan, modern ve esnek sade JavaScript nesnelerine ge\u00e7i\u015fin ard\u0131nda yatan evrim nedir?","og_url":"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-30T22:01:45+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"28 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Form Do\u011frulama Evrimi: customError&#8217;dan Sade Nesnelere Ge\u00e7i\u015f","datePublished":"2025-10-30T22:01:45+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/"},"wordCount":4177,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/","url":"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/","name":"Form Do\u011frulama Evrimi: customError'dan Sade Nesnelere Ge\u00e7i\u015f","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-30T22:01:45+00:00","description":"Web formlar\u0131, kullan\u0131c\u0131 etkile\u015fiminin ve veri toplaman\u0131n omurgas\u0131n\u0131 olu\u015ftururken, do\u011fru ve g\u00fcvenilir veri giri\u015fi her uygulaman\u0131n ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir. Kullan\u0131c\u0131lar\u0131m\u0131z\u0131n formlar\u0131 sorunsuz doldurabilmesi ve yanl\u0131\u015f veri giri\u015flerinden kaynaklanan hayal k\u0131r\u0131kl\u0131klar\u0131n\u0131 ya\u015famamas\u0131 i\u00e7in etkili form do\u011frulama mekanizmalar\u0131na sahip olmak zorunludur. Peki, bu s\u00fcre\u00e7te eski ve k\u0131s\u0131tlay\u0131c\u0131 customError yakla\u015f\u0131mlar\u0131ndan, modern ve esnek sade JavaScript nesnelerine ge\u00e7i\u015fin ard\u0131nda yatan evrim nedir?","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/form-dogrulama-evrimi-customerrordan-sade-nesnelere-gecis\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Form Do\u011frulama Evrimi: customError&#8217;dan Sade Nesnelere Ge\u00e7i\u015f"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/33197","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=33197"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/33197\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=33197"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=33197"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=33197"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}