Çarşamba, 29 Temmuz 2009

AJAX ile Kullanıcı İsmi Kontrolü

 

Siteye kayıt olurken kullanıcının seçtiği ismin daha önce alınıp alınmadığının kontrolü bir çok sitede AJAX ile yapılmaktadır. AJAXìn en büyük avantajı veritabanı üzerinden yapılan sorgunun, bir sonraki sayfada kullanıcıya bildirilmesi yerine aynı sayfa içinde sonucun gösterilmesidir. Böylelikle hem kullanıcı bir sonraki adımda çıkacak sonuca göre herşeyi baştan yapmasına gerek kalmayacak, hem de sunucu kaynakları gereksiz yere harcanamyacaktır. Bu yazımda, JQUERY kütüphanesi yardımıyla AJAX özelliklerini kullanarak CodeIgniter`da kullanıcı ismi sorgulamayı anlatacağım.

Öncelikle veritabanımız üzerine users adındaki tablomuzu yaratıyoruz. Tablomuz kolay anlaşılabilmesi amacı ile iki kolondan oluşuyor: id (sıra numarası) ve isim (kullanıcı ismi) kolonları. Veritabanımızın şeması aşağıdadır:

--
-- Table structure for table `users`
--

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL auto_increment,
  `isim` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`),
  FULLTEXT KEY `isim_2` (`isim`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

--
-- Dumping data for table `users`
--

INSERT INTO `users` (`id`, `isim`) VALUES
(1, 'admin'),
(2, 'fatih');

CodeIgniter ayarlarını application/config/database.php dosyasında kendi veritabanınıza göre yapmanız dışında, applicaiton/config/autoload.php dosyaı içinde açılışta yüklenecek kütüphane ve helper dosyaları için de aşağıdaki ayarların yapılmış olması gereklidir:

$autoload['libraries'] = array('database');
$autoload['helper'] = array('url');

İşe kolay anlamak açısından view dosyamızdaki Javascript kodlarını yazarak başlayalım:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js" type="text/javascript"></script>
<script language="javascript">
$(document).ready(function() { 
	$('#username').blur(function() {
        var field_value = $(this).val();

        if (field_value != '')
        {	
			$.ajax({
				url: '<?=base_url()?>user/kontrol/' + $(this).val(),
				type: 'POST',
				success: function(result) {
					$('#username_check').attr('innerHTML', result);
				}
			});
		}
	});
});
</script>
 

İlk satırda JQUERY kütüphanesini yüklüyoruz. Ardından gelen Javascript kısmı ise (Wayne Khan`ın sitesinden alınmadır.), "username" id değerine sahip div parçasındaki değişikliklerde, user isimli controller dosyasındaki kontrol isimli metodu çağırmasını, daha sonra da "username_check" id değerine sahip div parçası içine de result isimli değişkeni yazmasını söylüyoruz.

Bu kodlar ile birlikte formun çalışacağı (üye kaydının yapılacağı esas form) kısımları ekleyince application/view dizini altına kayıtlı user_view.php isimli view dosyamızın içeriği aşağıdadır.

<html>
<head>
<title>Ajax Ornek</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js" type="text/javascript"></script>
<script language="javascript">
$(document).ready(function() { 
	$('#username').blur(function() {
        var field_value = $(this).val();

        if (field_value != '')
        {	
			$.ajax({
				url: '<?=base_url()?>user/kontrol/' + $(this).val(),
				type: 'POST',
				success: function(result) {
					$('#username_check').attr('innerHTML', result);
				}
			});
		}
	});
});
</script>
	
</head>

<body>
<form action="<?=base_url()?>user/gonder" method="POST">
İsminiz : <input id="username" name="username" type="text" /> 
<div id="username_check"></div>
<p><input type="submit" name="send" value="gonder"/></p>
</form>
</body>
</html>


Yukarıdaki kodlardan da takip ettiğiniz üzere user isimli controller dosyamızda kontrol ve gonder isimli iki metodumuz olması gerekiyor. Kontrol isimli metod AJAX ile isim kontrolü yapıp ekrana yansıtırken, gonder isimli metod sonucun veritabanına aktarılması işlerini gerçekleştiriyor. Buna göre application/controllers dizini altına kayıtlı user.php isimli controller dosyamızın içeriği aşağıdadır:

class User extends Controller {

 function User()
 {
  parent::Controller();
 }
 
 function index()
 {
  $this->load->view('user_view'); 
 }
 
 
 function kontrol()
 {
  $this->load->model('user_model','Model');
  
  $username = trim(strip_tags($this->uri->segment(3)));
  
  if($this->Model->get_user($username) === FALSE) $data['message'] = "Seçtiniz isim daha önce alınmıştır.";
  else $data['message'] ="Seçtiğiniz isim uygundur.";

  $this->load->view('ajax_view',$data);
 
 }
 
 function gonder()
 {
  $data['message'] = $this->input->post('username',TRUE);
  $this->load->view('gonder_view',$data);
 }
 
}

Yukarıdaki kodlara göre index metodu ile user_view.php dosyamızı ekrana bastırıyoruz. Eğer kullanıcı isim kutusuna bir isim yazarsa kontrol isimli metod çalıştırılıyor ve URL adresinin üçüncü segmenti "username" isimli değişkeni Javascript ile post ediyor. Yüklenen user_model.php dosyası ile veritabanından sorgu çekiliyor ve eğer daha önce bir kullanıcı adı alınmışsa "Seçtiniz isim daha önce alınmıştır." mesajı, alınmamışsa "Seçtiğiniz isim uygundur." mesajı application/views/ajax_views.php dosyasına gönderiliyor.

Tek amacı gelen message değişkeni değerini ekrana bastırmak olan application/views/ajax_view.php dosyamızın içeriği aşağıdadır:

 <?=$message?> 

Application/controllers/user.php dosyamızdaki gonder isimli metod ise, kontrol metodundan geçen ismi input kutusundan çekerek application/views/gonder_views.php dosyası ile ekrana yazdırıyor. Bu metod aslında değişkenlerin alınarak veritabanına yazdırılmak üzere hazır hale getirilmesi şeklinde yazılmalıdır. Fakat bu yazıda anlamanız için ben detaya girmedim. Application/views/gonder_view.php isimli dosyanın içeriği aşağıdadır:

 <?=$message?>  isimli kullanıcıyı veritabanına kayıt edebilirsiniz.

Geriye Model dosyamız kaldı. Model dosyamızda geçen get_user fonksiyonu, kendisine gelen ismi veritabanında sorgular. Eğer bulursa FALSE, bulamazsa TRUE değeri döner. Application/models/user_model.php dosyasının içeriği aşağıdadır:

class User_model extends Model {
 
    function User_model()
    {
        parent::Model();
    }

 function get_user($isim)
 {
 
  $query = $this->db->get_where('users',array('isim'=>$isim));
 
  if($query->num_rows() > 0) return FALSE;
  else return TRUE;
 
 }
 
}

Kullanıcı veritabanına kayıtlı isimlerden "admin" ya da "fatih" ismini girerse ekrana hata mesajı gelirken, bu isimler dışında girilen her isim için uygundur mesajı geleecektir.

Bu yazı ile JQUERY kütüphanesinin AJAX fonksiyonunu CodeIgniter dosyalarında nasıl kullanabileceğimizi anlattım. Yazıda geçen kütüphaneleri hazır olarak buradan indirebilirsiniz. JQUERY kütüphanesi başkalarına ait olması nedeniyle, view dosyası içinden linkle çağrılmıştır. Kendi uygulamalarınızda kütüphaneyi indirip kullanmanız daha doğrudur.

Bu yazı Wayne Khan`ın yazısından hareketle yazılsa da, o yazıda anlatılmayan veritabanı bağlantılarının anlatılması ile o yazıda geçen hataların düzeltilmesi yoluyla özgün olarak yeniden kaleme alınmıştır.

Bu yazıda geçen JQUERY kodları, ALEXIS isimli ziyaretçimizin önerisi ile yeniden düzenlenmiştir.@02 Ağustos 2009

Yorumlar

Çok güzel makale olmuş Fatih BAZMAN bey elinize sağlık işimize yarayabilir.

Şu satırın ne işe yaradığını anlamadım:

$this->load->view('ajax_view',$data);

zaten başında echo var, bu view ile neyi yüklüyoruz,
ajax_view diye bie view dosyası oluşturmadık ki?

Jquery ile ilgili oldukça hız kazandıracak bir fikrim var, ajax ile post yapmadan önce değerin boş olup olmadığına bakalım. Eğer kullanıcı kutunun içine tıklayıp birşey yazmadan dışına tıklarsa boşuna post çalıştırıp, sql sorgusu yapmayalım?

@ALEXIS: ajax_view.php isimli dosyamız application/views altına kayıtlıdır. Yukarıda da belirttiğim gibi:

 <?=$message?>  

içeriğine sahiptir. Echo komutunu kullanmadım ama Javascript içinde geçen innerHtml komutunu mu kastediyorsun tam anlamadım.

Dediğin gibi satır kontrolü yapılarak gereksiz SQL sorgusu yapılması engellenebilir. Değiştirdiğin kodları gönderirsen sitede yayımlayabiliriz. Böylece uygulama daha geliştirilmiş olur.

application/views/ajax_view.php dosyasını oluşturucksınız makalede yazıyor zaten içeriğide

<STRONG> <?=$message?> </STRONG> olumlu olumsuz mesajları yazdırmak için yazılmış.

+ ek olarak $this->load->view('ajax_view',$data); echo ile gösteriliyor demişsiniz ama ben kodlarda echo ile iligli bir yer bile göremedim ?

Benzer uygulamaları daha önce de geliştirdim. CI kullandım ancak şu an aktif olarak kohana kullanıyorum.

Söz konusu tartışmalı satırın ajax isteğine cevap verebileceğini ben de düşünmüyorum.

$this->load->view('ajax_view',$data);

innerHTML nin çalışması için cevabı echo ile yazdırmalıyız.

------------------------------

Önceki cevabımda sözüne ettiğim kodları aşağıya yazacağım, yalnız benim sistemim biraz farklı, basitçe yazarsam, username alanına yazılanı almak için kullandığımız "$(this).val()" değişkeninin içini if ile kontrol ettim. Bilgiyi POST ile gönderdim, sizin gibi URI parametresi ile değil.

<script type="text/javascript">
// <![CDATA[
$(document).ready(function() {
    $('#login_field').blur(function() {

        var field_value = $(this).val();

        if (field_value != '')
        {
            //console.info("username: %s", field_value);

            $.ajax({
                url: '<?php echo url::base();?>user/check/',
                data: 'value='+field_value,<br>                type: 'POST',
                success: function(result) {
                    $('#login_field_check').attr('innerHTML', result);
                }
            });

        }

    });
});
// ]]>
</script>

------------------------------

controller kodlarımı yazmıyorum, çünkü sizin için bir anlam ifade etmeyecek, kohana kullanıyorum ben.

@ALEXIS: Uygulamaya cevap vereceğini düşünmüyorum dediğiniz satır için, yayınladığım kodları CodeIgniter ile çalıştırırsanız beklediğimiz gibi cevap verdiğini görebilirsiniz. Daha önce de bir yazımda bahsettiğim gibi, çalıştığından emin olmadığım kodları yayınlamıyorum.

Eklediğiniz JQUERY kodlarından ilgili satırları örneğime aktardım. Yorumunuz ve paylaşımınız için teşekkür ederim.

Ajax için sade ve basit bir örnek olmuş kodlar sade ve akıcı. Madem jquery tartışılıyor bende şöyle bir yorum getireyim ajax dan dönen veriyi attr gibi bir özellik ile neden yazdırdın direk

$('#login_field_check').html(result);

demek yeterli olacaktır.

Bir de Fatihcim data ile veri yollarken data değerini value=hebele yazmak yerine form etiketine bir id değeri verip

data: $('form#id').serialize(), dersek o bizim yerimize data değerine uygun şekilde verileri verecektir.

teşekkürler örnek için.

controller dosyasında

$this->load->view('ajax_view',$data); 

diyerek veriyi view ile sayfaya yazdırmak yerine

echo "<strong>".$message."</strong>";

diye yazdırmanın güvenlik veya başka herhangi bir nedenden ötürü sakıncası var mı? Böyle basit sayfalar için view dosyası oluşturmaya değer bir sebep var mı?

@Muhittin: Controller dosyası ekrana yazdırmak için kullanılmaz. Bu MVC mantığına aykırı olduğu için ayırıp Vİew dosyası çağırdım.

Bu sebeple, ne kadar basit olursa olsun ekran çıktılarını View dosyaları üzerinden yapmamız her zaman doğru yöntemdir.

Yorum Ekle