ile

JQuery

“Actioni contrariam semper et æqualem esse reactionem.”
“Her etkiye karşı zıt ve eşit bir tepki vardır.”

Isaac Newton

Giriş

Kitabımız bir Javascript kitabı olmadığı için bu konuya uzun uzadıya girmemize gerek yok. Ancak yine de javascript’in ne olduğunu, ne için kullanıldığını kısaca özetlemeliyiz ki JQuery konusunu anlayalım.

JavaScript

Bir programlama dilidir. Çoğu özelliği ile PHP’ye benzese de, temelde pek alakası olduğunu söyleyemeyecğim. Hatta bazen bir PHP geliştiricisi olarak JavaScript kodu okurken beynim duruyor diyebilirim. Peki neden icad edilmiş diyecek olursanız, 1995 yılında Netscape firmasında çalışan Brendan Eich tarafından kullanıcıların tarayıcıda girdikleri form verilerini, sunucuya gönderilmeden kontrol etmek için diyebiliriz. Kaynak: http://speakingjs.com/es5/ch04.html

Biz daha önce HTML’nin web sunucularına gönderilen istek sonucu tarayıcıda görüntülenen sayfanın dili olduğunu öğrenmiştik. PHP ise HTML dosyasına, kullanıcıdan gelen isteğe göre müdahele etmemizi sağlayan script “betik” diliydi ve sunucu tarafında çalışıyordu. JavaScript ise Tarayıcı tarafında içerikler henüz sunucuya gönderilmeden, kullanıcıların etkileşimlerine müdahele edebilmemizi sağlayan araç ve programlama dilidir. Son yıllarda Node.js sayesinde JavaScript sunucu tarafında çalışır hale geldi ve JavaScript ile sunucu uygulamaları da yapmak mümkün hale geldi. Ama dediğim gibi bu da baya uzun ve başka bir kitabın konusu.

JQuery Nedir?

En çok kullanılan JavaScript kütüphanesidir.

Bir yazılım kütüphanesi, bir amaca yönelik en çok kullanılan metod ve sınıfları bir araya getirip paketleyerek yeniden kullanmamızı ve tekrar tekrar yazmamızı önleyen yazılım parçacığıdır.

JQuery is web üzerinde JavaScript ile en çok yaptığımız işlemleri bir araya getiren, çok amaçlı çakı misali bir kütüphanedir. Peki nedir o işler?

  1. Tarayıcıda açılmış sayfayla canlı olarak oynamak. Dom Manipulation
  2. Kullanıcının yaptığı işlemlere göre farklı tepkiler vermek Events
  3. Sayfayı yenilemeden başka sunuculara başka istekler yollamak, veri çekmek. AJAX
  4. Efektler ve animasyonlar
  5. CSS şablonuna müdahele etmek
  6. Faydalı araçlar

Daha fazla bilgi için:

Neden Jquery peki?

  • JQuery neden bu kadar popüler diye soracak olursanız, bence JavaScript gibi bi dili öğrenmeye üşenen tasarımcılar,
  • Bir sürü ayrı tarayıcıda farklı faklı yapılan işlemleri, tek bir koda indirgemesi,
  • Kullanımı ve öğrenmesi kolay olması
  • İnternette yaygın kaynaklarının olması gibi seçenekler saymam mümkün.

Nasıl öğrenceğiz

Bu kitapta baştan sona yaptığım gibi, JQuery kütüphanesinin tek tek her özelliğini açıklayarak rehber yazmayacağım. Zaten konunun mantığını anladığınızda daha derinlemesine bilgiyi hem anlamanız hem de bulmanız daha kolay hale gelecek. Kısaca ana bileşenleri ve kavramları açıkladıktan sonra örneklerle devam edeceğiz.

Jquery Mantığı

Öncelikle daha önce öğrendiğimiz şekliyle bir web sayfasını hayalimizde canlandıralım. Bir web sayfası genel olarak şunlardan oluşuyordu:

  1. HTML etiketleri
  2. Tarayıcıda görebildiğimiz ve göremediğimiz kısımlar
  3. (Varsa) Görünüme müdahele ettiğimiz CSS şablonları
  4. JavaScript kütüphaneleri

HTML etiketlerinin, görüntülenen imajlar, başlıklar, yazılar, makaleler, linkler ve görüntülenmeyen meta, head gibi etiketlerden oluşturklarını biliyoruz. Bunlar da şimdi zihnimizin bir köşesinde dursun.

Olay

Ancak bu zamana kadar açıklamadığımız kısım şu. Etkileşim. Bir tarayıcı, kullanıcının yaptığı işlemlere göre tepki verir. Bir yere tıkladığında, sayfayı kaldırdığında, cep telefonundaysa dokunduğunda, metin seçtiğinde bu olaylara göre tepki vermesi gerekir. Bu yüzden tarayıcı internet sayfasında gezinirken yaptığınız bütün işlemleri takip eder, sizi gözler ki sizin isteklerinize anında cevap verebilsin. İşte sizin yaptığınız, kendi kendine olan, başka bir olayı tekip edev bu olaylar zincirine “Olaylar” ya da ingilizcesiyle Events diyoruz.

Dinleyici

Newton’un dediği gibi bir olay olduğunda, her zaman tepki de vardır. Yani tanımadığn birisi sokakta sana tokat attığında, ya sen de ona tokat atarsın, ya öbür yanağını çevirirsin, ya da hiçbişey yapmasan dahi, yanağın kızararak olaya tepki verir. Tarayıcı sürekli bizi gözetlediği ve olan olayları takip ettiği için bu olaylara tepki vermek durumundadır. Ancak hangi olaylara ne tepki vereceğini önceden bilmek durumundadır.

Mesela bir linke tıkladığımızda, sayfayı bize hissettirmeden değiştirmelidir. Ya da bir form girişi seçtiğimizde, o girişi seçtiğimizi anlamalı, ve yazacaklarımızı dinlemeye başlamalıdır. Bu olaylara karşı farklı tepki veren şey “Dinleyiciler” veya İngilizcesiyle Listeners olarak adlandırılır.

Eleman

Herhangi bir olayın nerede olduğu vereceğimiz tepkiyi de değiştirir. Yani her olaya aynı tepkiyi veremeyiz. Örneğin kardeşimizin doğum günü geldiğinde vereceğimiz tepki, halamızın kızının doğumgününe vereceğimiz tepkiyle aynı olmayacaktır. Yani olaylar ve tepkiler bağlama göre değişirler. Tarayıcı tıkladığınız her linke aynı tepkiyi verse, tüm sayfadaki linkler aynı yere giderlerdi ve istediğimiz işi yapmamış olurlardı. Burada tepki vereceğimiz olayın bağlantılı olduğu yapıya “Eleman” ya da İngilizce Element diyoruz.

Biz web sayfalarıyla ilgilendiğimiz için bütün bu elemanlar HTML dosyasının bir parçası.

Belge Nesne Modeli – Document Object Model (DOM)

"Ağaç"

By Brian Green, CC BY-SA 2.0, https://commons.wikimedia.org/w/index.php?curid=13127021

Başlık kafamızı karıştırmasın, çünkü aslında bu kavramı öğrendik. Daha önce HTML’yi oluşturan XML yapısını anlamıştık. Bir HTML dosyası iç içe geçmiş HTML etiketlerinden oluşuyordu. Tüm HTML sayfları en önce bir html etiketi ile başlıyorlardı. <html></html> Standart bir html dosyası şu etiketlerden oluşuyordu:

<!DOCTYPE html>

<html>
<head>
    <meta charset="UTF-8">

    <title>Title of the document</title>
</head>

<body>
Sayfa içeriği
</body>
</html>

Etiketler <meta charset="UTF-8"> örneğinde görüldüğü gibi kapatılmadan, ya da <title>Title of the document</title> örneğindeki gibi kapatılarak da kullanılabiliyordu. <meta charset="UTF-8"> etiketindeki “charset” kelimesi etiketin özelliği attribute ve tırnak işaretleri içindeki “UTF-8” verisi de o özelliğe atadığımız değeri temsil ediyordu. İlk başta kullanılması ve öğrenilmesi bu kadar basit olduğu için HTML dünya çapında internetin standart dili haline gelmiştir.

Peki “etiket” ve “eleman” dediğimiz kavramların birbirlerinden farkı nedir? Bir eleman, açılış etiketi, özellikler, içerik ve kapanış etiketinden oluşabilir. Yani etiketler, tarayıcı tarafından okunup, anlaşılır bir hale geldikten sonra eleman haline gelirler.

Tarayıcılar bu elemanlara istedikleri zaman ulaşabilmek için, önce dosyayı okurlar, daha sonra da onları nesneler halinde getirirler. Bu işlemin nasıl yapıldığını şu an anlamadıysanız sorun değil. Zaten tarayıcı bizim için yapıyor bu işlemi. Sayfayı açtığımızda tarayıcı kendi hafızasında ağaç benzeri bir yapı oluşturur. Bu sayede <section> ile belirttiğimiz bir bölümde kaç tane link <a href="#"><a> kaç tane paragraf <p>Paragraf<p> olduğunu sorgulayabiliriz. İşte bu sorgulamayı yapmamızı sağlayan varlığa “Belge Nesne Modeli (DOM)” ya da Document Object Model (DOM) deniyor. Bu konudaki detayları merak ediyorsanız bölüm sonundaki kaynaklardan öğrenebilirsiniz. Ama biz şimdilik ihtiyacımız olan kısmını bilsek yeter.

"Doküman Obje Modeli"

Kaynak: https://www.kirupa.com/html5/javascript_the_browser_and_the_dom.htm

Seçiciler

Daha önce CSS kısmında internet sayfamınızın içindeki bir elemanı nasıl şekillendireceğimizi kısaca öğrenmiştik. Aslında JQuery derken en önce öğrenmemiz gerek kavram bu. HTML sayfamızdaki elemanlara şu şekilde ulaşabiliriz.

  1. Etiket isimleriyle p, a, img gibi.
  2. Class özelliği ile: Etiket: <p class="important-paragraph">Paragraph</p> seçmek için: p.important-paragraph
  3. id özelliği ile: Etiket: <p id="main-paragraph">Paragraph</p> p#main-paragraph
  4. Sözde elemanlar ile öreğin ilk paragrafı bulmak için p:first
  5. Veya bir etiketin, özelliğinin aldığı veriye göre Etiket: <a href="mynameismidori.com"> mynameismidori.com</a> seçmek için: a[href='mynameismidori.com']

Eğer kafanız karıştıysa sorun değil, bu listedeki seçicilerin hepsi için ayrı ayrı örnekler yapacağız. Daha da ayrıntılı ve değişik seçiciler oluşturabiliriz ancak şimdilik detaya girmiyoruz. CSS’de elemanları şekillendirmek için kullandığımız seçicileri JQuery’de elemanları seçerken kullanabiliyoruz. JQuery’nin tasarımcılar tarafından sevilerek kullanılmasının bence en önemli nedeni de bu.

JQuery kütüphanesini kurmak

JQuery açık kaynaklı bir JavaScript kütüphanesi olduğu için herhangi bir kurulum işlemine ihtiyacımız yok. JQuery kütüphanesini 3 ayrı şekilde web sayfamızda kullanabiliriz. Birincisi javascript dosyasını indirip js diziniimize kopyalayabiliriz. Bunun için şu adımları takip etmemiz gerek:

  1. https://jquery.com/ sayfasını açalım. “Download JQuery” linkine tıklayalım.
"İndirme Linki"
  1. Açılan sayfada Download the uncompressed, development jQuery 2.2.0 linkine tıklayalım ve ‘http://code.jquery.com/jquery-2.2.0.js’ adresinden dosyayı indirelim.
"İndirme Linki"
  1. İndirdiğimiz dosyayı internet sayfamızın olduğu dizinin altında js dizinine kopyalayalım.
"Kaydetme dizini"
  1. HTML sayfamızdan bu dosyaya referans verelim.
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title of the document</title>
    <script src="js/jquery-1.12.0.js"></script>
</head>
<body>
Sayfa içeriği
</body>
</html>

İkincisi internette CDN denen başka sunuculardan jquery’ye referans verebiliriz. Ancak bu yöntemle çalışırken, sayfamızın internete bağlı olması gerekiyor. Yani internet yoksa, JQuery tarayıcı tarafından indirilmez.

Bu yöntemde de ekteki gibi uzak sunucu dosyalarını <head> etiketin içine <script> etiketiyle ekliyoruz.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title of the document</title>
    <script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
    <script src="//code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
</head>
<body>
Sayfa içeriği
</body>
</html>

Üçüncü yöntem ise “Bower” isimli aracı kullanmak. Bower JavaScript için yararlı bir kütüphane yönetim aracı, araç ancak kitabımızın konusu JavaScript olmadığı için bu konuyu araştırmayı size bırakıyorum.

Jquery kodu

Temel kavramları anladığımıza göre JQuery kodu yazmaya giriş yapabiliriz. Temel olarak bir JQuery kodu şöyle yazılır:

$('seçici').olay(dinleyici);

Burada “dinleyici” yan listener dediğimiz kavrama “hareket” yani action dendiği de oluyor. Aslında şu aşamada “JQuery bu kadar, dağılın!” desem de olur, çünkü JQuery JavaScript ile yapılan işleri gerçekten bu kadar basitleştiriyor. Ancak kitabımızın adı “Projelerle PHP” olduğu için devam edelim.

Diyelim ki en basitinden sayfadaki tüm paragraflara tıklayınca, uyarı olarak “paragrafa dokundun” diyecek bir kod parçası yazmamız gerek.

$('p').click(function(){alert("paragrafa dokundun")});

Açıklayayım. $('p') ile sayfadaki bütün <p> etiketiyle başlayan paragraf elemanlarını seçtik. click seçeneği ile dinleyeceğimiz olayı belirledik. function(){alert("paragrafa dokundun")} kısmında ise olay olduğunda yapacağımız işi belirttik. Bu nasıl metod demeyin. Bu adı sanı ismi cismi belli olmayan anonim method. Sadece lazım olduğunda kullanmamıza yarıyor. JavaScript’te bir süredir vardı. Son zamanlarda PHP’ye de geldi. Burası yine kafanızı karıştırmasın, bizi ilgilendiren “{}” süslü parantezlerin arasındaki kısım. Orada sadece alert metodunu çağırıp ekranda uyarı veriyoruz.

Herhangi bir sayfada JavaScript konsolunda bu kodu çalıştırıp, bir paragrafa tıkladığımızda, (eğer JQuery’i doğru kurulmuşsa tabii) karşılaşmamız gereken görüntü şu:

"Click örneği"

JavaScript kodu aşağı yukarı PHP ile benzerlik gösterse de benzerlik genellikle görüntüde kalıyor. Ancak örnekler kısmında işimize yarayacak ve anlayabileceğimiz kadar JavaScript kodu kullanacağız.

Örnekler

Kitaptaki örneklerin genellikle işimize yarar örnekler olmasına dikkat ediyorum. Sonuçta kimse her paragrafa tıklandığında, “Paragrafa dokundun” diyen ruh hastası bir kodu kullanmak istemez. O yüzden daha önce yaptığımız sayfalarda olduğu gibi, işimize yarayacak ve yaramaya devam edecek, gerçek hayattan örnekler vereceğim.

  1. Sayfa açıldıktan sonra, yönlendirme yapan basit bir script. Window Events
  2. Form verisini, sunucuya göndermeden önce kontrol etmek. Input Validation
  3. Şehir seçtikten sonra ilçeleri gösteren seçenek oluşturan script. Ajax

Şu an JQuery’ye giriş yapmak ve PHP öğrenimimize destek olmak için bu ilk üç örnek yeterli.

Sayfa Yönlendirme

Bazen herhangi bir sayfayı doğrudan başka bir adrese yönlendirmek isteriz. Bunun için kullanışlı ve basit bir script yazalım ve ne zaman bir sayfayı yönlendirmek istesek bu scripti kullanalım.

Öncelikle sayfanın tarayıcıda açıldığından ve herşeyin indirildiğinden emin olmamız gerek. Bunun için JQuery’de $(document).ready() metodunu kullanacağız. Şimdiye kadar öğrendiklerimizden anlayacağımız üzere elemanımız tüm belge document. Olayımız ise hazır yani ready olayı. Bütün JQuery metodlarını ve kodunu bu metodun içinde çalıştırmamız gerek ki sayfanın bütün DOM yani Belge Nesne Modeli indirilmiş olsun ve JQuery aradığı herşeye ulaşabileceğinden emin olsun ve hata alma riskimizi minimuma indirelim. Yani tüm JQuery kodlarımız ne yazarsak yazalım şu şekilde olacak:

<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JQuery Redirection</title>
</head>
<body>
  <script type="text/javascript">
    $(document).ready(function(){
      // Bütün kodlarımızı buraya yazacağız.
    });
  </script>
</body>
</html>

Yönlendirme için yapmamız gereken işlem ise baya basit.

<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JQuery Redirection</title>
</head>
<body>
  <script type="text/javascript">
    $(document).ready(function(){
      $(location).attr('href', "http://www.mynameismidori.com");
    });
  </script>
</body>
</html>

Burada yönlendirme için $(location).attr('href', "http://www.mynameismidori.com"); metodunu kullandık. Bu ifade aslında JQuery kullanmadan sade vanilla JavaScript ile window.location.href="http://www.mynameismidori.com"; diye de yazılabilirdi. Burada JQuery’nin ne yaptığını görmemiz açısından biraz daha açıklama yapayım. JavaScript koduna baktığımızda DOM yani Belge Nesne Modelinin Window yani pencere nesnesinin, location özelliğini değiştiriyoruz. Burada o özelliğin href (bunu hedef diye de çevirebiliriz. <a href="#"></a> etiketinden hatırlıyoruz.) özelliğini istediğimiz adresle değiştiriyoruz. Tarayıcı bunu anlıyor ve pencerenin adresini değiştiriyor.

Bunu ready yani “hazır” olayı olduğunda yapıyoruz ki, sayfa açılır açılmaz yönlendirme işlemi yapılsın.

Yönlendirme işlemini yapmanın bir sürü farklı yöntemi de mevcut. Ancak JQuery ile bu şekilde yapılıyor.

Form Kontrolü

Bölümün başındaki JavaScript tarihçesini okuduysanız, JavaScript’in bu amaç için icat edildiğini görmüşsünüzdür. Gerçi JavaScript artık form kontrolünden daha çok işleve sahip. Ama yine de tarihi bir örnek olması açısından bununla başlayalım.

PHP bölümünde sunucuya form göndermeyi öğrenmiştik. Diyelim ki elimizde üye kayıt formu var. Form şu bilgilerden oluşsun:

  1. E-posta adresi
  2. Kullanıcı adı
  3. İki adet parola alanı
  4. Telefon numarası (Opsiyonel)

Her zamanki gibi işe akıl yürüterek başlayalım. Gerçekten bazen bu işi yaparken kendimi Sherlock Holmes gibi hissediyorum. Önce ipuçlarını değerlendiriyorum, parçaları birleştiriyorum ve sonuca ulaşıyorum. Yani çok zevkli:

  • En önce bu formda opsiyonel olmayan alanların boş olmadıklarından emin olmalıyız.
  • E-posta adresinin doğru olduğundan emin olmalıyız. Yani “1234” gibi bir e-posta adresi olamaz.
  • İki adet parola alanının birbiriyle tıpatıp aynı olduklarını kontrol etmeliyiz.
  • Parolaların en az 8 hane olduklarını kontrol etmeliyiz. (Neden mi 8 hane? Salladım çünkü 🙂 Ama genellikle web uygulamaları en az 8 hane ve güvenlik yüksekse büyük-küçük harf, özel karakter ve bir sayı içermesini istiyorlar. Ve siz parolayı yazarken bunları anında kontrol ediyorlar. Bunu da bir sonraki örneğimizde yapalım.)
  • Telefon numarası opsiyonel olacağı için boş kalabilir. Ancak o da 7 haneden küçük olmamalıdır.

Kurallarımız bunları. Peki ulaşmak istediğimiz sonuç nedir?

  1. Hatalı olan form alanının altında küçük kırmızı bir uyarı çıkmalı.
  2. Form hatalı ise, gönder butonuna tıklanamamalı.
  3. Tüm form verileri doğruysa form gönderilebilmeli.

Bütün bu denetleme işini formu gönderdikten sonra PHP ile yapabilirdik. Ama tüm sayfanın yenilenmesi can sıkıcı olduğundan ve sunucuyu hatalı isteklerle meşgul etmek istemediğimizden bu kontrol işlemlerini tarayıcı tarafında yapmamız daha avantajlı.

Önce örnek bir form hazırlayalım. Formumuz henüz tarayıcı tarafında çalışacağı için, sunucu tarafıyla uğraşmamıza şimdilik gerek yok. Daha önce görünüm açısından Foundation CSS kütüphanesinin 5. sürümünü kullanmıştık. 6. sürümde işler karıştığı için daha hafif bir css kütüphanesi olan Milgram CSS’i kullanacağız.

"Milligram CSS Kütüphanesi"

Milligram kütüphanesini tıpkı JQuery indirdiğimiz gibi zip dosyasını http://milligram.github.io/index.html adresinden indirerek kullanabilirsiniz. Getting Started linkine tıklayarak açılan sayfadan Download Milligram butonuna tıklayalım ve zip dosyasını indirelim.

"Milligram CSS Kütüphanesini indirmek"

Zip dosyasını açtıktan sonra karşımıza şöyle bir görüntü gelecek:

"Milligram CSS Kütüphanesi arşivi"

Buradan dist dizinine tıklayalım.

"Milligram CSS Kütüphanesi arşivi dist dizini"

Bu dizindeki milligram.css dosyasını JQuery’yi yüklediğimiz gibi, ancak bu sefer kendi projemizin css dizinine kopyalayalım.

"CSS dizini"

Daha sonra Download Milligram kısmında anlatıldığı üzere ihtiyacımız olan diğer kütüphaneleri de ekleyelim.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Form Örneği</title>
    <script src="js/jquery-1.12.0.js"></script>
    <!-- Google Fonts -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">

    <!-- CSS Reset -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.3/normalize.css">

    <!-- Milligram CSS minified -->
    <link rel="stylesheet" href="css/milligram.css">

</head>
<body>
Sayfa içeriği
</body>
</html>

Dikkat ettiyseniz dosyaları <head> etiketinin içine yerleştirdik. Bu dosyaları kullanmanız için, daha önce dediğim gibi, internet bağlantısına ihtiyacınız olacak. İnternet olmadan çalıştırmak istiyorsanız, burada href özelliğindeki dosyaları da indirip, js uzantısı ile bitiyorlarsa, js dizinine, font dosyası iseler, font dizinine, css uzantılı iseler, css dizinine kopyalamalıyız. Şimdilik biz CDN yani internette barındırılan dosyaları kullanacağız ve internete bağlı olmaya dikkat edeceğiz. İnternetten dosyaları indirirken dosyaların minified yani sıkıştırılmış olma durumları var. Genellikle kütüphaneler dosyanın okunabilir sürümlerini de paylaşıyorlar. Sıkıştırılmış dosyalar, boşluklardan ve gereksiz yeni satırlardan arındırıldıkları için okunamaz halde oluyorlar ve min.js uzantısıyla dağıtılıyorlar. Biz eğitim amaçlı çalıştığımız için min.js uzantısını kullanmıyoruz, ancak internet sitenizi yayına çıkarmadan önce, performans için yapabileceğiniz iyileştirmelerden biri de bu.

"Form"

Şimdi şu kodları kullanarak basit formumuzu oluşturalım.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Form Örneği</title>
  <script src="js/jquery-1.12.0.js"></script>
  <!-- Google Fonts -->
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300italic,700,700italic">

  <!-- CSS Reset -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/3.0.3/normalize.css">

  <!-- Milligram CSS minified -->
  <link rel="stylesheet" href="css/milligram.css">
  <link rel="stylesheet" href="css/app.css">

</head>
<body>
  <div class="container">
    <div class="row">
      <div class="column">
        <h5>Üyelik Formu</h5>
        <form id="registration-form">
          <fieldset>
            <label for="email">E-Posta</label>
            <input type="email" placeholder="E-Posta Adresi" id="email" required>
            <label for="username">Kullanıcı Adı</label>
            <input type="text" placeholder="Kullanıcı Adı" id="username" required>
            <label for="password-1">Parola</label>
            <input type="password" placeholder="Parola" id="password-1" required>
            <input type="password" placeholder="Parola Tekrar" id="password-2" required>
            <label for="phone">Telefon Numarası</label>
            <input type="number" placeholder="Telefon Numarası" id="phone">
            <input class="button-primary float-right" type="submit" value="Gönder">
          </fieldset>
        </form>
      </div>
    </div>
  </div>
  <script type="text/javascript">
  // Jquery kodlarımızı buraya yazacağız
  </script>
</body>
</html>

Not: app.css dosyasını da dosyamıza ekledik. Bu sayede sayfamızda yapmak istediğimiz değişiklikler olduğunda, kütüphane dosyasını katletmek yerine, kendi değişkliklerimizi bu dosyada tutabiliriz. CSS dosyalarının sırasına göre, tarayıcı en son yüklenen dosyayı en önemli kabul edecek. Bu dosya da sadece şu tek satır koddan oluşuyor:

.container {
    max-width: 80rem;
    padding: 4rem 2rem;
}

Not 2: </body> yani body etiketinin kapandığı yerde script etiketi kullandık. JQuery kodlarımızı oraya yazacağız. Kodları sayfanın sonuna eklememizin sebebi, bütün sayfanın tamamen indirildiğinden emin olmak istememiz.

Form içindeki etiketlerde input type kısmında number, email gibi değerler kullandığımıza dikkat edin. Ayrıca gerekli olan veri giriş alanlarının sonuna da required kelimesini yerleştirdik. HTML5 ile gelen bu yenilik sayesinde JQuery veya başka bir JavaScript kütüphanesi kullanmadan formlarımız -eğer tarayıcı da destekliyorsa- kendliğinden tarayıcı tarafından kontrol ediliyor ve gönderilmiyor.

"Tarayıcı Form Uyarısı"

Bu uyarı tarayıcının türüne, işletim sisteminin diline göre değişiyor. Sonuç olarak biz Türkçe web sitesi yazdığımızdan, uyarıların da Türkçe çıkmasını hatta biraz da lakayıt olmalarını ve de bu uyarıların görünümünü de kendimize göre ayarlamak isteyebiliriz.

Önce app.css dosyasına şu kodu ekleyelim. Bu kod sayesinde, hatalı olan veri giriş alanının etrafını kırmızıya boyayacak ve mesaj kısmını istediğimiz gibi şekillendireceğiz.

input.warning{
    margin-bottom: 0rem;
    border: 0.1rem solid red;
}

div.warning{
  margin-bottom: 1.5rem;
  color:red;
  font-size: 86%;
}

div.warning::before { 
    content: "* ";
}

div.warning::before kısmı CSS3 ile gelen yeni bir özellik. İçerik ne olursa olsun, bütün yazıların önüne, “*” işaretini eklememize yarıyor. Genellikle ikon fontları kullanıldığında bu CSS koduna ihtiyaç duyuyoruz.

Şimdi burada bütün sayda kodunu tekrarlamak yerine sayfanın sonundaki script etiketini buraya ekleyeceğim ve adım adım açıklayacağım. Ayrıca bölüm sonundaki linklerden buradaki örneklerin GitHub paketi adresine de ulaşabilirsiniz.

  // HTML sayfasının indirildiğinden emin olalım.
  $(document).ready(function(){
    // E-posta alanından çıkıldığını tespit edelim
    $('#email').focusout(function(){
      // Gerekli olan alanların boş olup olmadıklarını ve zaten uyarı içerip içermediklerini kontrol edelim.
      if($('#email').val() == "" && !$('#email').hasClass('warning')){
        $('#email').addClass('warning');
                                $('#email').after('<div id="email-warning" class="warning"> E-posta alanı boş olamaz</div>');
      }
      if($('#email').val() != "")
      {
        // Eğer hata yoksa uyarıları yok edelim.
        $('#email').removeClass('warning');
        $('#email-warning').remove();
      }
    });
  });

Bu kodu çalıştırıp e-posta alanına tıklayıp çıktığımızda, ya da TAB tuşu ile başka bir alana yazmaya çalıştığımızda karşımıza şöyle bir görüntü gelece.

"İlk Jquery Uyarısı"

Kod bloğumuzun içinde yorumlar mevcut ama bi yine de tek tek kullandığımız metodları açıklayalım.

  1. $(document).ready(function(){... metodu ile HTML belgemizin tarayıcıya tamamen yüklendiğinden emin olduk.
  2. $('#email').focusout(function(){ metodunda, id’si email olan elemanı bulduk ve focusout olayını gözetlemeye başladık. focusout olayı, herhangi bir input yani veri giriş alanına yazı yazmaktan vazgeçip, başka yere tıkladığımızda ya da klavyede TAB tuşuna bastığımızda meydana geliyor.
  3. Buradaki kısım PHP kodunu andırıyor. $('#email').val() ile input etiketinin şu anki değerini elde ettik. Boş olup olmadığını kontrol ettik.
  4. $('#email').hasClass('warning') kısmında ise warning diye bir class değeri eklemediğimizden emin olduk. Çünkü bir veri girişi uyarı verdiyse, kodun devamında warning isimli class değerini elemana ekliyoruz.
  5. Eğer e-posta alanı boşsa, $('#email').addClass('warning'); işlemindeki addClass metoduyla, uyarı class’ını etikete ekliyoruz. JQuery ile bu işlemi yapmak gerçekten çok kolay.
  6. $('#email').after('<div id="email-warning" class="warning"> E-posta alanı boş olamaz</div>'); kısmında uyarı mesajını içerek etiketi, veri giriş alanından hemen sonraya ekliyoruz.
  7. email id’sine sahip bu alan için focusout dinleyicisini eklediğimizden, her focusout olayında kod bloğumuz çalışıyor. Eğer sonra if($('#email').val() != "") kısmında, eğer değer boş değilse, warning uyarısını removeClass metodu ile ve mesaj kısmını $('#email-warning').remove(); işlemiyle etiketten siliyoruz.

Peki her alan için bu kodları tekrarlamak zorunda mıyız? Tabii ki hayır. JavaScript dilinde Nesne Yönelimli Programlama çok tuhaf olduğu için kod tekrarını daha önceden öğrendiğimiz fonksiyon kavramıyla önleyeceğiz. Önce her eleman için ortak olan durumlara bakalım.

  • Tüm input yani veri giriş elemanları için focusout olayını dinlemeliyiz.
  • Hangi elemanın gerekli, hangi elemanın isteğe bağlı olduğunu anlamalıyız. Bunun için input:required sözde seçicisini veya JQuery’nin $(this).prop('required') metodunu kullanabiliriz. Prop bir DOM elemanının bir özelliğe property sahip olup olmadığını kontrol eden metod.
  • Elemanın testi geçip geçmediğini kontrol etmeliyiz. Geçmiyorsa uyarı eklemeliyiz. Geçiyorsa uyarıyı kaldırmalıyız. Ayrıca her uyarının kendine ait bir kimliği olmalı ki onu bulup kaldırabilelim.
  • Tüm uyarı mesajı alanları veri girişine özel olmalı ki, o veri girişini kontrol ettiğimizde mesajı da bulup kaldırabilelim.
  • Birden fazla eleman içeren dizi üzerinde işlem yapacaksak, PHP’den hatırladığımız şekilde for veya while döngülerini kullanabiliriz. Ancak JQuery bunun için de bir kısayol sunuyor. $(eleman).each() metodu ile seçicimizin döndürdüğü eleman listesi üzerinde işlem yapabiliyoruz. İpucu: Bu, PHP’deki array_map() metoduna benziyor.

Şu minik kod parçası ne yapıyor bir bakalım:

    $('input').click(function(){
      console.log($(this).val());
    });

Bu JQuery işlemi, oncelikle bütün input elemanlarını seçiyor. Sonra click yani tıklanma olaylarını yakalıyor ve $(this).val() metodu ile hangi veri girişi elemanı içindeysek ve veri girişine ne değer girildiyse o değeri, geliştirici konsoluna yazıyor. Biz Chrome Developer Tools kullanıyoruz. İşte tüm kontrol işlemlerinde, veri girişinin değerini kontrol ederken buradaki kod parçasının mantığından yararlanacağız.

"Geliştirici Konsolu"

Yani amacımızi, belirlediğimiz olay durumunda veri girişi alanı input içerisindeki değeri kontrol etmek ve o değere göre işlem yapmak.

Tam detaylı örnek

Tek tek yapacaklarımızı yeniden Sherlock Holmes’in akıl tümevarım metoduyla belirleyelim.

"Form Doğrulama"
  1. Çok fazla kod tekrarı istemiyoruz. Bu nedenle tekrar ettiğimiz kodları fonksiyonlara dönüştürelim.
  2. Eklediğimiz uyarı mesajlarının, kendilerine ağit bir benzersiz id değerleri olsun ki, onları daha sonra silebilelim. Çünkü eğer benzersiz bir id değeri olmazda bir alanla birden fazla uyarı olduğunda bunları ayırdedemeyiz ve silemeyiz.
  3. Silme metodunda, uyarıyı eklediğimiz alanın ve silmeyi istediğimiz uyarı etiketinin id değerlerine ihtiyacımız olacak.
  4. Önceki örnerğimizde yaptığımız gibi focusout() metodunu kullanacağız, ancak harf miktarını kontrol etmek için, her harf girdiğimizde kontrol yapacak bir metoda ihtiyacımız var. Bunun için JQuery’nin keyup metodunu, her klavyeye basılıp çekilme olayını tespit etmek için kullanacağız.
  5. Ayrıca okunurluk ve kullanırlık açısından mesajları da değişkenlere yerleştireceğiz.

** Bir Tavsiye: ** Hiç İngilizce bilmiyorsanız dahi kodlarınızdaki değişken isimlerini veya metod, sınıf isimlerini Türkçe yazmayın. Tamamen ingilizce olan if, else gibi kodların arasında Türkçe hem kötü duruyor hem de değişken isimlerinde Türkçe karakter kullanmadığımız için, Türkçe’ye de ayıp oluyor. Ayrıca eğer biliyorsanız, yorum alanlarınızın da Ingilizce olması avantaj. Çünkü açık kaynak yazılım üretip bunu dünya ile Github aracılığı ile paylaştığınız zaman, tüm dünyadan geliştiriciler sizin kodunuzu okuyup anlayabiliyorlar.

Öncelikle uyarı eklemek için kullanacağımız addWarning ve removeWarning metodlarını inceleyelim.

  function addWarning(element, message, messageId) {
    if (!element.hasClass('warning')) {
      element.addClass('warning');
    }
    if ($('#' + messageId).length == 0) {
      element.after('<div class="warning" id="' + messageId + '">' + message + '</div>');
    }
  }

  function removeWarning(element, messageId) {
    if (element.hasClass('warning')) {
      element.removeClass('warning');
    }
    $('#' + messageId).remove();
  }

addWarning(element, message, messageId) metodu ile başlayalım.

  • element parametresinde kullanmak istediğimiz elemanın “kendisini” $(this) ile fonksiyona göndereceğiz. id de kullanabilirdik.
  • message parametresinde görüntülenmesini istediğimiz uyarı mesajını göndereceğiz.
  • messageId parametresinde daha sonra uyarıyı silmek için kullanacağımız id değişkenini belirleyeceğiz.
  • Fonksiyon içinde hasClass() elemanın daha önceden bir uyarı class‘ına sahip olup olmadığını kontrol ettik. Öyle bir uyarı class‘ı varsa, tekrar eklememize gerek yok.
  • if ($('#' + messageId).length == 0) { kısmında bu id‘ye sahip bir elemanın sayfada olup olmadığını, uyarıyı tekrar eklememek için kontrol ettik. JQuery’nin döndürdüğü elemanın .length özelliği bize elemanın sayfada bulunup bulunmadığını söylüyor. Varsa, tabii ki tekrar eklememize gerek yok.
  • .after() metoduyla, oluşturduğumuz div etiketini, veri giriş alanımızdan input hemen sonraya ekliyoruz.
  • removeWarning() fonksiyonunu anlamak artık sizin için çok kolay. Yine uyarı class‘ını kontrol ettik ve removeClass() metodu ile class‘ı etiketten çıkardık.
  • $('#' + messageId).remove(); işlemi ile de uyarı mesajımızı, benzersiz id‘si sayesinde sildik.

Şimdi bu iki metodu kullanarak, belirli olaylarda Event, belirli koşullara nasıl tepki vereceğimizi görelim.

  // HTML sayfasının indirildiğinden emin olalım.
  $(document).ready(function() {


    // Veri girişi alanından çıkıldığını tespit edelim
    $('input').focusout(function() {

      // Eğer eleman required özelliğine sahip ise boş olmamalıdır.
      var fieldNotEmptyMessage = " alanı boş olamaz";

      // Alanın gereli olup olmadığını kontrol eden değişken
      var inputRequired = $(this).prop('required');

      // Placeholder değerine alanların Türkçe isimlerini yazdığımız için, bu değeri mesajlarda da kullanabiliriz.
      var inputPlaceHolder = $(this).attr('placeholder');

      // Eğer input gerekliyse ve boş ise uyarı ekleyelim
      if (inputRequired && $(this).val() == "") {
        // buraya dikkat, eklediğimiz uyarı etiketlerini messageId parametresine göre sileceğimiz için bu kısmı ekledik
        addWarning($(this), inputPlaceHolder + fieldNotEmptyMessage, $(this).attr('id') + '-not-empty'); 
      }
      if (inputRequired && $(this).val() != "") {
        removeWarning($(this), $(this).attr('id') + '-not-empty');
      }

    });

    // Keyup metodu herhangi bir alanda klavyenin tuşuna basıldığını algılar.
    // Burada biz her tuşa basıldığında veri girişinin uzunluğunu kontrol edeceğiz.
    // Eğer yazarken doğrulama sağlanırsa uyarı kendiliğinden kaybolacak.
    $('#username, #phone').keyup(function() {
      // Telefon numarası en az 7 haneden, Kullanıcı adı en az 8 haneden oluşmalıdır.
      var phoneNumberLessThankSevenCharsMessage = "Telefon Numarası en 7 haneden oluşmalıdır.";
      var usernameLessThankEightCharsMessage = "Kullanıcı adı en 8 haneden oluşmalıdır.";
      var inputLessThanSevenChars = $(this).val().length < 7;
      var inputLessThanEightChars = $(this).val().length < 8;

      if ($(this).attr('id') == 'username' && inputLessThanEightChars) {
        addWarning($(this), usernameLessThankEightCharsMessage, $(this).attr('id') + '-less-than-eight');
      } else {
        removeWarning($(this), $(this).attr('id') + '-less-than-eight');
      }

      if ($(this).attr('id') == 'phone' && inputLessThanSevenChars) {
        addWarning($(this), phoneNumberLessThankSevenCharsMessage, $(this).attr('id') + '-less-than-seven');
      } else {
        removeWarning($(this), $(this).attr('id') + '-less-than-seven');
      }
    });
    // Yine aynı şekilde burada da her tuşa basıldığında iki parola alanının aynı olup olmadığını kontrol edeceğiz
    $('#password-1, #password2').keyup(function() {

      var passwordNotEqualMessage = "Parola alanları aynı olmalıdır";

      // Eleman password1 id'sine sahipse password2 ile eşit olmalıdır. Ya da tam tersi.
      if ($('#password-1').val() != $('#password-2').val()) {
        addWarning($('#password-2'), passwordNotEqualMessage, 'password-2-not-equal');
      } else {
        removeWarning($('#password-2'), 'password-2-not-equal');
      }
    });

  });

Kodumumuz yeterince açık ve kendini anlatıyor. Zaten yorumlar da var. Kısaca ne yaptığımızı anlatırsak, tüm alanlar için focusout() metodunu gözledik. #password1, #password2 ve #username, #phone alanlarını birlikte, keyup() olayı için gözlemeye başladık.

var inputPlaceHolder = $(this).attr('placeholder'); ifadesi ile placeholder yani yazmadan önce çıkan yazı değerini JQuery’nin attr() metodu ile etiketten aldık.

JavaScript’te PHP’den farklı olarak, metin birleştirme işlemlerinin . işareti ile değil + işareti ile yapıldığına dikkat edin.

keyup() metodu ile gözetlediğimiz ve uyarı verdiğimiz alanlar bastığımız karaktere göre test ettiğimiz alanlar. Örneğin $(this).val().length < 7 ifadesi ile her tuşa bastığımızda alan input metninin miktarının 7’den küçük olup olmadığını kontrol ediyoruz. 8 karaktere ulaştığımızda uyarı otomatik olarak ortadan kalkıyor.

Bu örneği kullanarak yazdığınız web uygulamalarında kullandığınız formlara uyarılar ekleyebilirsiniz. Ancak dikkat, tarayıcı tarafında çalıştırılarn JavaScript/JQuery kodunu kesinlikle güvenlik amaçlı kullanmayın, çünkü tarayıcıdaki gelişitirici araçlarında bu kodlara müdahele etmek gayet basit.

Form içinde ile bağlı ilçe seçimi – AJAX

İnternette il seçtiğimizde, biraz bekledikten sonra sihirli bi şekilde bize ilçeleri de seçmemizi sağlayan formları görmüşsünüzdür. Bu örnekte de bu seçim alanlarından aynısını yapacağız. Tüm ülkenin, tüm ilçelerini kodlarımıza ekleyip bu işlemi yapabilirdik ancak verinin büyüklüğü sitemizin yavaş bağlantılarda indirilememesine sebep olabilir. Bu nedenle, JQuery ve JavaScript kullanarak internetten, sadece istediğimiz zamanda veri indireceğiz. Örneğin twitter gibi internet sitelerinin sayfayı yenilemeden verileri güncelleme işi de bu yöntemle yapılıyor.

Bu konu hakkında başka bir kitap yazılabilecek kadar uzun bir konu olduğu için fazla detaylı girmeyeceğiz ancak bölüm sonunda uygulamalarınızda Ajax teknikleri kullanacak kadar bilgiye sahip olacaksınız.

Ajax Nedir?

Ajax aslında Asynchronous JavaScript + XML açıklamasının kısaltmasıdır ve web üzerinde neredeyse devrim yapan bir tekniği ifade eder. 2005 yılında Jesse James Garrett tarafından bulunmuş bir terim. Kaynak: https://developer.mozilla.org/en/docs/AJAX “Eşzamanlı olmayan JavaScript + XML” anlamına geliyor. Böyle söyleyince pek birşey ifade etmiyor olabilir. Ancak buradaki “eşzamanlı olmayan” kısmını anlamamız çok önemli.

"Ajax bir futbol takımı değildir"

PHP’de ya da JavaScript’te kod yazarken istediğimiz şeylerin anında olmasına alışkınız. Ancak diyelim ki internetteki bir kaynağa ya da çok büyük boyutlu veya şifrelenmiş bir dosyaya erişmemiz gerek. Normalde eğer tüm yaptığımız işlemler eşzamanlı olsaydı, yazdığımız programın kilitlenip, işlem bitene kadar bize cevap vermemesi gerekirdi. Yani karşıdan dosya indirilene kadar bomboş bir ekranla karşılaşırdık. Mesela, siz de benim gibi Google Chrome’da açık olan yüz adet sekme ile çalışıyorsanız, bilgisayarın bazen takıldığına şahit olmuşsunuzdur. Bilgisayar takılıyor, çünkü işlem yapabilmesi için yeterli bellek alanı yok. İşlemlere devam edebilmek için belleğin boşalmasını bekliyor.

Web üzerinde verilerle etkileşimli işler yaparken de bunun olmasını istemiyoruz. Bunun için icad edilmiş ve tarayıcımızda tıpkı daha önce kullandığımız DOM gibi hazır bulunan XMLHttpRequest API ve XMLHttpRequest nesnelerini kullanacağız.

"Ajax bir temizlik malzemesi hiç değildir"

JavaScript versiyonu ve tarayıcı türüne göre bu XMLHttpRequest API değişkenlik gösterdiğinden, ve birazcık da karmaşık olduğundan, JQuery’nin bu iş için bize sağladığı basit metodları kullanacağız. Eşzamanlı olmayan Asynchronous metodları kullanmak başta biraz garip gelebilir, ancak dikkatli olduğumuz sürece bir sorunla karşılaşmamız mümkün değil.

XML ve JSON

Daha önce XML’in ne olduğunu öğrenmiştik. Ve HTML’nin XML’in bir parçası olduğunu da. Peki JSON nedir? JavaScript Object Notation “JavaScript Nesne Gösterimi” anlamına gelir. JSON da verileri bir yerden bir yere gönderirken kullandığımız formatlardan biridir ve XML’e göre okunması ve JavaScript kodları ile müdahele edilmesi nispeten daha kolaydır. JSON dosyalarını tıpkı JavaScript’te nesneler ve özelliklerini oluşturduğumuz, onlara değer atadığımız gibi oluşturabiliriz. Bir örnek görelim: http://schema.org/address

“` JSON-LD

Burada bir kişi ile ilgili bilgileri standart `schema.org` formatında tanımladık. Bir `JSON` dokümanında obje özellikleri başka bir objeyi içinde barındırabilir. Örneğin burada `address` özelliği ayrıca bir objeyi içinde barındırıyor.

> **Ek Bilgi:** Bunun gibi iç içe geçmiş nesneleri kullanmak, rekürsif algoritmalar kullanabiliriz.

İşte `Ajax` işini yaparken, verileri de `JSON` ile gönderip alıyoruz ki işimiz daha kolay olsun.

### Çalışan Uygulama için Hazırlık

Her zamanki gibi hedefimizi ve yapmamız gerekenleri yazarak işe başlayalım.

1. Bir forma ihtiyacımız var. Önce 81 ili listeleyecek. İlçe kısmı boş olacak ve 'Lütfen bekleyiniz' yazacak.
2. İl seçtiğimizde ilçeleri sorgulayabileceğimiz bir veriye ihtiyacımız var.

!["İl ilçe formu"](il-ilce.png)

Bu iki işi yapabilmemiz için birçok yöntem ve karmaşık iş mevcut. Tüm veriyi sayfaya yerleştirebilirdik. Genellikle bütün il ve ilçeleri listeleyen bir JSON dosyaları 40 KB civarında oluyorlar. Bu miktar belki günümüz için düşük olabilir ancak milyonlarca veriyi tek seferde sayfaya indirmek biraz saçma. O yüzden veriyi filtrelemek için küçük ve basit bir PHP sınıfı da yazacağız. Tüm isteklerimizi kendi sunucumuzdaki bu dosyaya göndereceğiz ve yanıtları da bu dosyadan alacağız.

Biz bu işlemleri yaparken, kullanıcı kesinlikle hiçbir şeyin farkında olmayacak ve herşeyin sihirli bir şekilde hallolduğunu sanacak.

Form ile başlayalım.

html




Form Örneği

Şehir Seçme

İl Lütfen İl Seçiniz İlçe Lütfen İlçe Seçiniz

Formumuz gördüğünüz gibi şu anda neredeyse boş. Peki neye ihtiyacımız var, 81 adet ile. Dosyamız açılır açılmaz JQuery ile bu bilgiyi almalıyız. Peki herhangi bir filtreye ihtiyacımız var mı? Yok. Ama yine de biz bu forma cevap verecek PHP sınıfımızı yazalım.

Bu minik programcığın görevlerini anlayarak işe başlayalım.

1. Gelen istek eğer bir filtre içermiyorsa, cevap olarak 81 ilin listesini `JSON` formatında döndürmek.
2. Eğer filtre varsa -yani il seçildiyse- o ilin ilçelerini listelemek.

Pek zor bir iş değil. Tabii ki önce bir istek olup olmadığını 
 `$_POST['submit']` gibi bir kodla tespit etmemiz gerek. Ayrıca `file_get_contents()` metodu ile dosyayı açmalı, `json_decode()` metodu ile dosyayı bir diziye `array` çevirmeliyiz. Sonrasında bu dizi içinde arama yapabiliriz.

 Öncelikle `JSON` dosyamızın içine bakalım. Tabiki 2000 küsür satırlık dosyayı burada yazmayacağız. İlk birkaç satırla başlayalım.

JSON
[
{
“city_id”:1,
“city_name”:”Adana”,
“district_id”:1104,
“district_name”:”Seyhan”
},
{
“city_id”:1,
“city_name”:”Adana”,
“district_id”:1219,
“district_name”:”Ceyhan”
},
{
“city_id”:1,
“city_name”:”Adana”,
“district_id”:1329,
“district_name”:”Feke”
},
{
“city_id”:1,
“city_name”:”Adana”,
“district_id”:1437,
“district_name”:”Karaisalı”
},

Buna göre dosyayı açıp `json_decode()` metodu ile dizi oluşturacağımız diziden `city_id`, `city_name`, `district_id` ve `district_name` anahtarlarını kullanarak verilere ulaşacağız.

Kodumuzu inceleyelim. Aşağıdaki kodu internet sayfamızla aynı dizine `cities-basic.php` ismiyle kaydettik. `JSON` dosyası da `data` dizini altında `il-ilce.json` ismiyle kaydedlimiş olmalı.

php
<?php

 // Dosyanın JSON cevabı vermesini garantileyelim. 
header("Content-Type: application/json");
 // Sunucudaki Json dosyasını açalım
$file = file_get_contents('data/il-ilce.json');
// Json dosyasının içindekileri bir diziye yazalım
$data = json_decode($file,true);
// Daha sonra kullanmak için iki dizi oluşturalım.
$cities = [];
$districts = [];

 // Json dosyasında ilçeler var. 
 // Tüm ilçeler için tek tek veriyi işleyelim.
foreach($data as $district){
     // Önce şehir dizisini oluşturalım. 
     // Ve şehirleri diziye kaydedelim. 
    if(!isset($cities[$district['city_id']])){
        $cities[$district['city_id']] = $district['city_name'];
    }
    // İşlediğimiz şehirin dizide olup olmadığını kontrol edelim.
    // Dizide yoksa, ekleyelim.
    if(!isset($districts['city_id'])){
        $districts['city_id'] = [];
    }
    else{
          // İlçe dizisine bu şehre ait ilçeleri ekleyelim.
        array_push($districts['city_id'], ['id'=>$district['district_id'],'name'=> $district['district_name']]);
    }
}
// Verilerimizi oluşturmayı tammaladık.

 // Dosyaya şehir kodunun gelip gelmediğini kontrol edelim
 // Dikkat ederseniz, form kontrolü yaptığımız PHP koduna benzer
 // bir işlem yapıyoruz.
if(isset($_POST['id'])){
    $id = $_POST['id'];
    echo json_encode($districts[$id]);
}
else
{
      // Eğer şehir kodu yoksa, doğrudan şehir bilgilerini
      // Json formatında şehir dizisini döndürelim.
    echo json_encode($cities);
}

?>

Her zamanki gibi adım adım kodu açıklayayım.

1. `header("Content-Type: application/json");` kısmında php dosyasının her zaman `JSON` cevabı vermesini garantiler. Bu kısım sayesinde tarayıcı sayfayı `html` değil `JSON` formatında işleyecektir.
2. `$file = file_get_contents('data/il-ilce.json');` İşlemiyle dosyayı `$file` değişkenine kaydettik.
3. `$data = json_decode($file,true);` işlemiyle dosyadaki `JSON` kodunu `$data` adında bir diziye atadık.
4. Daha sonra kullanmak için `$cities` ve `$districts` isminde iki adet dizi oluşturduk.
5. `JSON` dosyasındaki elemanları tek tek işlemek için forach döngüsüne soktuk.
6. Sırayla önce şehirleri bulduk.
7. Daha sonra her şehir için ayrı ayrı ilçeler dizisini oluşturduk.
8. Son olarak dosyaya `post` işlemiyle eğer bir `id` değeri gelidyse, o şehrin ilçe dizisini ekrana `JSON` formatında yazdık. Eğer `id` bilgisi gelmediyse, tüm şehrilerin listesini içeren bir `JSON` dosyası oluşturduk.

!["Şehir Seçme"](sehir-secme.png)

Sıra geldi bu dosyaya for içinde JQuery ile erişip verileri çekmeye ve kullanmaya.

JavaScript
// HTML sayfasının indirildiğinden emin olalım.
$(document).ready(function () {
// cities-basic.php dosyasına get isteği gönderelim.
$.get(“cities-basic.php”, function (data, status) {
// Eğer status bilgisi başarıyı işaret ediyorsa işleme devam edelim.
if (status == ‘success’) {
// each metodu ile gelen tüm verileri id ve name alanlarına ayıralım.
$.each(data, function (id, name) {
// her il için il seçeneğini select etiketinin içine yerleştirelim.
$(‘#city’).append(” + name + ”);
});

              // Şehir alanının seçildiğini gözetleyelim. Seçim olayı olduğunda bu bölüm çalışsın.
              $("#city").change(function () {
                  // şehir kodunu seçilen alandan elde edelim.
                  var cityId = $(this).find('option:selected').attr('value');

                  // cities-basic.php dosyasına şehir kodu verisiyle istek göndereim.
                  $.post("cities-basic.php", {
                              id: cityId
                          },
                          function (data, status) {
                              // bu sefer gelen data bağlantılı data olduğu için ve birden fazla seçenek
                              // olduğu için district değerlerinin id ve name özelliklerine erişmeliyiz.
                              if (status == 'success') {
                                  // hazırda bulunan ilçe değeri varsa silelim.
                                  $('#district').empty();
                                  // gelen tüm data için tek tek seçenek etiketlerini sayfaya yerleştirelim.
                                  $.each(data, function (id, district) {
                                      //display the key and value pair
                                      $('#district').append('<option value="' + district.id + '">' + district.name + '</option>');
                                  });
                              }
                          });
              });
          }
      });
  });

“`

Bu sefer kodumuz sağa doğru alıp başını gitmiş. Normalde yazılımcılar olarak biz iç içe bu kadar çok işlem yapmayı sevmeyiz. Ya kodun çok dallandığını ya da çok kod tekrarı yapıldığını gösteren bir durumdur. Ancak burada amacımız JQuery’de AJAX işlemlerini anlamak olduğu için şimdilik kod temizliği (metodlara bölmek vs. gibi) yapmıyorum.

Tüm kodda anonim metodlar olmasının sebebi, bu metodların asenkron yani eş zamanlı olmayan bir şekilde çalışmaları. Kendi belirlediğimiz asenkron metodları kendimiz çağıramıyoruz, internete gönderilen HTTP isteği tamamlandığında XMLHttpRequest API sonuç durumuna göre kendisi çağırıyor.

Şehir seçtiğimizde gelen ilçe verisi şu şekilde:

"İlçe Verisi"

Yeni kodu adım adım incelersek:

  1. $(document).ready(function () { işlemiyle tüm işlemleri html sayfası hazır olduğundan sonra yaptığımıza emin oluyoruz.
  2. $.get("cities-basic.php", function (data, status) { işlemiyle cities-basic.php dosyasına get isteği gönderiyoruz ve şehir listesini elde ediyoruz.
  3. if (status == 'success') { işlemin başarılı olup olmadığını kontrol ediyoruz.
  4. Başarılı ise il verilerini tek tek $.each(data, function (id, name) { alıyoruz ve select etiketinin içine option etiketleri olarak yerleştiriyoruz.
  5. $("#city").change(function () { şehir alanı için change() olayını gözetliyoruz. Bu olay olduğunda o şehrin id bilgisi ile cities-basic.php dosyasına post isteği gönderip ilçe bilgilerini çekiyoruz.
  6. Seçili şehrin id bilgisine var cityId = $(this).find('option:selected').attr('value'); işlemiyle ulaşıyoruz.
  7. $.post("cities-basic.php", {id: cityId}, işlevi ile post isteği yaptıktan sonra, yine gelen her ilçe bilgisine göre ilçe seçimi yaptığımı select etiketi içine option etiketleri ile seçenekleri ekliyoruz.
"İlçe Seçme"

Gördüğümüz gibi sihirli bir şekilde girdiğimiz ilk seçeneğe göre başka bir alanın seçeneklerine müdahele etmeyi öğrendik ve JQuery konusunun sonuna gelidk. Bu bölümdeki tüm örnekleri incelemeniz için https://github.com/midorikocak/turkish-cities-districts adresinde de koydum. Umarım konuyu anlayabilmişsinizdir, çünkü teker teker anneye (ya da başka birine) anlatır gibi anlattım.

Kaynaklar:

  1. http://alexisgo.com/GDI/jquery1.pdf
  2. http://api.jquery.com/after/
  3. http://blog.webagesolutions.com/archives/138
  4. http://code.runnable.com/Ue9c4krQF7VjAAAP/how-to-get-selected-option-using-jquery
  5. http://code.tutsplus.com/series/css3-mastery–net-18126
  6. http://code.tutsplus.com/tutorials/10-css3-properties-you-need-to-be-familiar-with–net-16417
  7. http://code.tutsplus.com/tutorials/getting-to-work-with-css3-power-tools–net-13894
  8. http://code.tutsplus.com/tutorials/the-30-css-selectors-you-must-memorize–net-16048
  9. http://jqfundamentals.com/chapter/traversing-manipulating
  10. http://jquery.com/download/
  11. http://learn.jquery.com/about-jquery/how-jquery-works/
  12. http://learn.jquery.com/using-jquery-core/selecting-elements/
  13. http://stackoverflow.com/questions/5347357/jquery-get-selected-element-tag-name
  14. http://stackoverflow.com/questions/7861032/loop-and-get-key-value-pair-for-json-array-using-jquery
  15. http://www.456bereastreet.com/archive/200508 html_tags_vs_elements_vs_attributes/
  16. http://www.rapidtables.com/web/dev/jquery-redirect.htm
  17. http://www.sitepoint.com/a-basic-html5-template/
  18. http://www.sitepoint.com/use-jquerys-ajax-function/
  19. http://www.tutorialspoint.com/jquery/jquery-ajax.htm
  20. http://www.w3schools.com/cssref/sel_before.asp
  21. http://www.w3schools.com/jquery/jquery_ajax_get_post.asp
  22. http://www.w3schools.com/jquery/jquery_examples.asp
  23. http://www.w3schools.com/jquery/jquery_get_started.asp
  24. http://www.w3schools.com/jquery/jquery_ref_selectors.asp
  25. http://www.w3schools.com/jquery/jquery_selectors.asp
  26. http://www.w3schools.com/jquery/jquery_syntax.asp
  27. http://www.w3schools.com/js/js_htmldom_document.asp
  28. https://books.google.cz/books?id=PyWFCwAAQBAJ&pg=PA4&lpg=PA4&dq=history+of+jquery&source=bl&ots=vq2o80HLna&sig=ly4_wTF5UtWq1ETA4l-rFVOYFFo&hl=en&sa=X&ved=0ahUKEwi69bmQ54bLAhUjvnIKHbVfAFs4ChDoAQgmMAI#v=onepage&q=history%20of%20jquery&f=false
  29. https://tr.wikipedia.org/wiki/Newton%27%C4%B1n_hareket_yasalar%C4%B1
  30. https://www.kirupa.com/html5/javascript_the_browser_and_the_dom.htm
  31. https://www.w3.org/TR/1999/REC-html401-19991224/intro/sgmltut.html#h-3.2.1