jQuery UI kütüphanesinin en güzel özelliklerinden bir tanesi de “autocomplete” özelliğidir. AJAX isteklerini klavyeden bir kaç tuşa basarak otomatik bir şekilde tamamlamaya yardımcı olur. Bu özelliği kullanmanın en kolay yolu mevcut bir JSON dosyası olmasına rağmen, gerçekte verilerin bir veri tabanından gelmesini isteriz. Mevcut autocomplete örneğinde de verileri bir veri tabanından çekip ekrana dökülecektir.
jQuery UI AutoComplete örneğinini yapmaya başlamadan önce nasıl bir işlem yapılacağını açıklayalım.
Öğrencilerin bilgilerinin olduğu bir mySql tablomuzun olduğunu varsayalım. Bu tabloda öğrencilerin numara, ad, soyad, cinsiyet, sınıf ve doğum tarihi bilgileri kaydedilmektedir. Hazırlayacağımız formda öğrencinin adı yada soyadı ile ilgili bir şey girdiğimizde ekrana ilişkili kayıtların listelenmesini sağlayacağız.
MySQL Tablosunun Tasarımı
Şekildeki bilgilere uygun olarak tabloyu aşağıdaki gibi tasarlıyoruz.
DDL Komutları
1 2 3 4 5 6 7 8 9 10 11 12 13 |
CREATE TABLE `ogrenciler` ( `ogrno` int(11) NOT NULL, `ad` varchar(50) NOT NULL, `soyad` varchar(50) NOT NULL, `cisiyet` varchar(1) NOT NULL, `dogum_tarih` date NOT NULL, `sinif` varchar(5) NOT NULL, `resim` varchar(100) NOT NULL ) ALTER TABLE `ogrenciler` ADD PRIMARY KEY (`ogrno`); |
DML Komutları
1 2 3 4 5 6 7 8 9 10 |
INSERT INTO `ogrenciler` (`ogrno`, `ad`, `soyad`, `cisiyet`, `dogum_tarih`, `sinif`, `resim`) VALUES (10, 'Ali', 'Pancarcı', 'E', '2003-10-12', '11C','ogrenci.jpg'), (15, 'Suna', 'Uğurlu', 'K', '2004-12-23', '11A','ogrenci.jpg'), (20, 'Suat', 'Uluçay', 'E', '2004-11-13', '11A','ogrenci.jpg'), (110, 'Ayye', 'Pınarcık', 'K', '2004-10-13', '11A','ogrenci.jpg'), (113, 'Ahmet', 'Güzelyurt', 'E', '2002-07-13', '11B','ogrenci.jpg'), (120, 'Ayye', 'Pınarcık', 'K', '2000-04-03', '11A','ogrenci.jpg'), (275, 'Saffet', 'Alancık', 'E', '2004-10-25', '11B','ogrenci.jpg'); |
(not: örneği hazırlarken cinsiyet yerine cisiyet yazmışım tanımsız hatası veriyor. Programın çalışmasına engel değil)
HTML Kodlarının Yazımı
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<div class="container"> <div class="row"> <div class="col-md-12 col-sm-12 col-xs-12"> <h1>JQUERY UI AUTOCOMPLETE</h1> </div> <div class="col-md-12 col-sm-12 col-xs-12"> <div class="form-group"> <from> <input class="form-control" type="text" id="SorguInput"> </from> </div> </div> </div> <div id="ogrenci-liste" class="row"> </div> </div> |
PHP Kodlarının Yazımı
Autocomplete, text kutusunda arama başlatıldığında sunucuya term isimli url parametresini göndermektedir. Göderilen parametre ile geriye JSON tipinde id, value ve label isimli özelliklere sahip bir veri kümesi dönmektedir. Yukarıda oluşturulan veritabanındaki verileri uygun şekilde çekmek için term paremetresi ile ad yada soyad ile eşleşen kayıtları alıp foreach döngüsü içinde id, value ve label isimlerine sahip yeni bir dizi oluşturuyoruz.
Burada dikkat edilmesi gerek küçük bir noktayı bahsetmek istiyorum. Form ekranında gösterilen liste değerleri label içindeki verileri, value seçim yapıldıktan sonra text kutusu içindeki değeri gösterecektir. Tüm satırdaki verileri getirmek için ekranda görünmeyen id değerini kullanmayı tercih ettim. İkinci bir AJAX işlemi yapmamak için bu şekilde bir tercihte bulundum.
Dizi oluşturulup içine değerler foreach ile eklendikten sonra JSON formatına çevirip ekrana yazdırma işlemi yaparak PHP ile yapılacakları bitirdim.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php /*veritabanı bağlantısı*/ $dsn = 'mysql:dbname=kutuphane;host=127.0.0.1'; $user = 'root'; $password = ''; try { $baglan = new PDO($dsn, $user, $password); } catch (PDOException $e) { echo 'Bağlantı kurulamadı: ' . $e->getMessage(); } /*veritabanı bağlantısı*****/ if(isset($_GET['term'])) { $ifade=$_GET['term']; $isim=strtolower($ifade); $sth = $baglan->query("SELECT * FROM ogrenciler WHERE ad LIKE '%$ifade%' OR soyad LIKE '%$ifade%'"); $cevap = $sth->fetchAll(); $liste=[]; $a=0; foreach($cevap as $c){ $liste[]=[ 'id'=>$c, 'label'=>$c['ad'].' '.$c['soyad'], 'value'=>$c['ogrno'].' '.$c['ad'].' '.$c['soyad'] ]; } //Dikkat: Bozuk Türkçe karakterler JSON çıktısını engeller. echo json_encode($liste); } |
JavaScript Kodlarının Yazımı
Tüm işlemler jQuery yüklendiğinde gerçekleşeceği için tüm javascript kodlarını jquery yüklendi metodunun içine yerleştirerek yazıyoruz.
1 2 3 4 5 6 7 |
$(document).ready(function(){ //bütün kodlar bu bölüm arasında olacak }); |
Bölüm 1: Bu bölümde autocomplete nesnesinin nasıl kullanıldığına bakalım. Liste nesnesinin kullanımı yazının devamında açıklanacaktır.
source: Bu kısmında veritabanından okuma yılacak olan server dosyasını gösteriyoruz.
minLength: en az kaç karakter olduğunda işlem aramaya başlayacağını ifade ediyoruz.
focus: Çekilen liste üzerinde fare ile gezinmeye başladığımızda neler yapılacağını ifade ediyor.
select: Çekilen listedeki nesnelerden her hangi birine tıkladığımızda yani seçim yapıldığında ne olacağını fonksiyona yazacağız.
close: Seçim yapıldığında liste kapandığında yapılacak işlemler bu fonksiyon arasına yazılacaktır.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
var ogrenciListe=new Liste(); $("#SorguInput").autocomplete({ source:'sorgu.php', minLenght:3, focus:function(event,ui){ /*bu bölümde fazla birşey yapılayacak liste üzerinde fare imleci hareket ederken nesnelerin detaylarını getireceğim */ }, select:function(event,ui){ /* Seçim yapıldıktan sonra oluşturulan öğrenci listesine öğrenciler eklenecek. Sonraki aşamada da listedeki öğrenciler html içine yazdırılacak. */ }, close: function( event, ui ) { /*Seçme işlemi tamamlandığında text kutusunun boşalması sağlanacak*/ } }); |
Yukarıdaki kodda en önemli kısım seçim yapıldığında neler yapılacağını anlatacağımız select fonksiyonunun içidir. Listeden çekilen veri ui parametresine item özelliği olarak eklenmektedir.
Eklenen item içinde de AJAX ile çekilen verinin id,labal ve value değerleri tutulmaktadır.
Bölüm 2: Seçim yapıldığında öğrenci adında bir nesneye ui ile gelen item.id değerini parametre olarak gönderip yeni bir öğrenci oluşturacağım. Oluşturduğum öğrenciyi de yine tüm öğrencilerin kaydını tutmak için oluşturduğum liste adında başka bir nesneye gönderip öğrencinin eklenmesini sağlayacağım. Öğrenci listeye eklendiğinde yine bu listenin bir metodunu çağırıp ekranın doldurulmasını sağlayacağım. ogrenciListe nesnesinin bir örneğini oluşturmak için autocomplete çağrıladan önce var ogrenciListe=new Liste(); yazarak yeni liste oluşturduğumu belirteyim.
Bu yaptığım açıkalamlardan sonra select fonksiyonu aşağıdaki gibi oluşacaktır.
1 2 3 4 5 6 7 8 9 |
..... select:function(event,ui){ var ogrenci=new Ogrenci(ui.item.id); //Ogrenci sınıfı ogrenciListe.ogrenciEkle(ogrenci); //Liste sınıfının metodu ogrenciListe.htmlGuncelle(); } ..... |
Bölüm 3: Örneğin en zor kısımına geldik. Ogrenci ve Liste nesnelerini oluşturuyoruz.
Ogrenci Sınıfı
1 2 3 4 5 6 7 8 9 10 11 12 |
function Ogrenci (gelen) { this.ogrno = gelen.ogrno; this.ad = gelen.ad; this.soyad = gelen.soyad; this.sinif = gelen.sinif; this.cinsiyet = gelen.cinsiyet; this.resim = gelen.resim; this.dogum_tarih= gelen.dogum_tarih ; } |
Liste Sınıfı
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
function Liste(){ this.ogrenciler=[]; this.ogrenciEkle=function(ogrenci) { var durum=this.ogrenciler.findIndex(function(x){ return x.ogrno==ogrenci.ogrno; }); if(durum!=-1) return false; this.ogrenciler.push(ogrenci); } this.getir=function() { return this.ogrenciler; } this.ogrenciSil=function(ogrId) { var sil= this.ogrenciler.find(function(e){ return e.ogrno==ogrId; }); this.ogrenciler.remove(sil); this.htmlGuncelle(); } this.htmlGuncelle=function() { $("#ogrenci-liste").html(''); for(item of this.ogrenciler) { this.htmlEkle(item); } } this.htmlEkle=function(ogrenci) { $ogrenciDiv= $('<div>').append( $('<div>') .css({ background:'#F1C954', padding:'5px', border:'5px solid #0F4061' }) .append('<img src="'+ogrenci.resim+'" class="img-responsive">') .append($('<p>Ad :'+ogrenci.ad+'</p>')) .append($('<p>Soyad :'+ogrenci.soyad+'</p>')) .append($('<p>Sınıf :'+ogrenci.sinif+'</p>')) .append($('<p>Cinsiyet:'+ogrenci.cinsiyet+'</p>')) .append($('<button data-id='+ogrenci.ogrno+' type="button" class="kaldir btn btn-danger">Kaldır</button>')) ); $ogrenciDiv .attr('class','ogrenci col-md-4 col-sm-6 col-xs-6') .appendTo('#ogrenci-liste'); } } |
Ogrenci nesesinde pek birşey olmamasına rağmen, liste içinde bir hayli fonksiyon ve özellik dikkatinizi çekmiştir. Adım adım neler yaptığımızı açıklayalım.
this.ogrenciler: listeye eklenen öğrencileri bu dizi içinde tutacağım.
this.ogrenciEkle: Listeye öğrenci daha önce eklenmediyse ekleme işlemini gerçekleştirecek fonksiyon. Listede öğrencinin olup olmadığını ogrno ile kontrol edip listeye öğrenciyi ekliyor.
this.getir: Her hangi bir yerde kullanmadım fakat test aşamasında lazım olduğu için yazmıştım.
this.ogrenciSil: Gönderilen öğrenci numarasına göre öğrenci silme işlemini gerçekleştiriyor. Silme işlemi için Array sınıfına remove adında ek bir fonksiyon ekledim. Eklenen fonksiyonun kodları aşağıda mevcuttur.
this.htmlGuncelle: for döngüsü ile this.ogrenciler içindeki tüm elemanları htmlEkle metodu yardımı ile ekrana yerleştiriyor.
this.htmlEkle: İçeriği çok fazla dolu olduğu için içime pek sinmeyen fonksiyon fakat daha kısa olması için template yapmak gerekirdi. Neyse kodun amacını açıklayayım. Bootstrap tasarımı için bir tane öğrenci kartı oluşturuyor. Oluşturulan öğrenci kartını da son satırda #ogrenci-liste içine ekliyor.
Array.remove fonksiyonu
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Array.prototype.remove = function() { var what, a = arguments, L = a.length, ax; while (L && this.length) { what = a[--L]; while ((ax = this.indexOf(what)) !== -1) { this.splice(ax, 1); } } return this; }; /*Bulduğum adres:https://stackoverflow.com/questions/3954438/how-to-remove-item-from-array-by-value*/ |
Bölüm 4: Öğrencileri kaldırmak için ekleme yapılırken .kaldir adınca class değerini sil butonuna ekledim. .kaldir adındaki butona tıklandığında yine aynı butona data-id nesnesi olarak eklenen ogrno değeri yardımı ile ogrenciSil fonksiyonuna öğrencinin numarasını gödererek öğrencinin silinmesini sağlıyorum.
1 2 3 4 5 6 |
$("body").on('click','.kaldir',function(){ var aktifIndex=$(this).data().id; ogrenciListe.ogrenciSil(aktifIndex); }); |
Sayfalarda kullanılan kodlar
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Jquery UI Autocomplete</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css"> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> <!-- Optional theme --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> <script src="https://code.jquery.com/jquery-3.2.1.js" integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-12 col-sm-12 col-xs-12"> <h1>JQUERY UI AUTOCOMPLETE</h1> </div> <div class="col-md-12 col-sm-12 col-xs-12"> <div class="form-group"> <from> <input class="form-control" type="text" id="SorguInput"> </from> </div> </div> </div> <div id="ogrenci-liste" class="row"> </div> </div> <script> $(document).ready(function(){ Array.prototype.remove = function() { var what, a = arguments, L = a.length, ax; while (L && this.length) { what = a[--L]; while ((ax = this.indexOf(what)) !== -1) { this.splice(ax, 1); } } return this; }; function Ogrenci (gelen) { this.ogrno = gelen.ogrno; this.ad = gelen.ad; this.soyad = gelen.soyad; this.sinif = gelen.sinif; this.cinsiyet = gelen.cinsiyet; this.resim = gelen.resim; this.dogum_tarih= gelen.dogum_tarih ; } function Liste(){ this.ogrenciler=[]; this.ogrenciEkle=function(ogrenci) { var durum=this.ogrenciler.findIndex(function(x){ return x.ogrno==ogrenci.ogrno; }); if(durum!=-1) return false; this.ogrenciler.push(ogrenci); } this.getir=function() { return this.ogrenciler; } this.ogrenciSil=function(ogrId) { var sil= this.ogrenciler.find(function(e){ return e.ogrno==ogrId; }); this.ogrenciler.remove(sil); this.htmlGuncelle(); } this.htmlGuncelle=function() { $("#ogrenci-liste").html(''); for(item of this.ogrenciler) { this.htmlEkle(item); } } this.htmlEkle=function(ogrenci) { $ogrenciDiv= $('<div>').append( $('<div>') .css({ background:'#F1C954', padding:'5px', border:'5px solid #0F4061' }) .append('<img src="'+ogrenci.resim+'" class="img-responsive">') .append($('<p>Ad :'+ogrenci.ad+'</p>')) .append($('<p>Soyad :'+ogrenci.soyad+'</p>')) .append($('<p>Sınıf :'+ogrenci.sinif+'</p>')) .append($('<p>Cinsiyet:'+ogrenci.cinsiyet+'</p>')) .append($('<button data-id='+ogrenci.ogrno+' type="button" class="kaldir btn btn-danger">Kaldır</button>')) ); $ogrenciDiv .attr('class','ogrenci col-md-4 col-sm-6 col-xs-6') .appendTo('#ogrenci-liste'); } } /*********PROGRAM*********/ var ogrenciListe=new Liste(); $("#SorguInput").autocomplete({ source:'sorgu.php', minLenght:3, focus:function(event,ui){ $("#SorguInput").val(ui.item.value); return false; }, select:function(event,ui){ console.log(ui); var ogrenci=new Ogrenci(ui.item.id); ogrenciListe.ogrenciEkle(ogrenci); ogrenciListe.htmlGuncelle(); }, close: function( event, ui ) { $("#SorguInput").val(''); } }); $("body").on('click','.kaldir',function(){ var aktifIndex=$(this).data().id; ogrenciListe.ogrenciSil(aktifIndex); }); }); </script> </body> </html> |
sorgu.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php /*veritabanı bağlantısı*/ $dsn = 'mysql:dbname=kutuphane;host=127.0.0.1'; $user = 'root'; $password = ''; try { $baglan = new PDO($dsn, $user, $password); } catch (PDOException $e) { echo 'Bağlantı kurulamadı: ' . $e->getMessage(); } /*veritabanı bağlantısı*****/ if(isset($_GET['term'])) { $ifade=$_GET['term']; $isim=strtolower($ifade); $sth = $baglan->query("SELECT * FROM ogrenciler WHERE ad LIKE '%$ifade%' OR soyad LIKE '%$ifade%'"); $cevap = $sth->fetchAll(); $liste=[]; $a=0; foreach($cevap as $c){ $liste[]=[ 'id'=>$c, 'label'=>$c['ad'].' '.$c['soyad'], 'value'=>$c['ogrno'].' '.$c['ad'].' '.$c['soyad'] ]; } //Dikkat: Bozuk Türkçe karakterler JSON çıktısını engeller. echo json_encode($liste); } |