AJAX Web Sitelerinde Tarayıcıda Geri/İleri Düğmesi Sorunu
Bir arkadasım daron abinin bu yazısını gösterdi. hemen ekleyeyim buraya dedim
İnternet tarayıcılarındaki Geri ve İleri düğmelerinin ne kadar çok kişi tarafından kullanıldığını ilk AJAX web projelerinin kullanıcılarına teslim edilmesi ile anladım. Neredeyse herkes bu düğmelerin çalışmamasından şikayetçiyi (Haklılardı). AJAX altyapısı üzerine kurduğumuz web sitelerinde performansı arttırmak amacıyla olabildiğince işlemleri AJAX tekniği ile yapmaya çalışıyoruz. Bu durumun iki sakıncası var; birincisi web sitesi içerisindeki farklı konumlar için farklı adresler oluşmuyor. Kullanıcı web sitemizde onlarca düğmeye tıklayarak iç kısımlarda biryerlere ulaşmış olabiliyor fakat sayfa hiç yenilenmediği için ulaştığı noktanın bir adresi (URL) olmuyor. İkinci sakıncası ise makalemin ana nedeni olan ve bir önceki nedenden kaynaklanan, tarayıcılardaki Geri ve İleri düğmelerinin çalışmaması. Sayfanın adresi değişmediği için hiçbir internet tarayıcı sayfanın içerisindeki değişiklikleri adres geçmişine eklemiyor ve bu nedenle geriye veya ileriye gidiş de mümkün olmuyor.
Peki ne yapabiliriz? İlk aşamada sayfanın adresini değiştirmek için sayfa içi çapalar (linkler) kullanabiliriz. Bu tarz linkleri aşağıdaki şekilde tanımlayabilirsiniz. Normal adresin sonuna bir # işareti ile eklenirler ve adresein bu kısmının değişmesi için sayfanın yenilenmesi gerekmez.
http://www.biradres.com/birdosya.aspx?ID=2#Capa
Güzel bir taktik olduğu kesin fakat maalesef yukarıdaki şekliyle yaratılan adresler Internet Explorer içerisinde sayfa geçmişine eklenmeyebiliyor (IE sürümüne bağlı). Bizim tüm tarayıcılarla uyumlu olmamız şart. Bu durumda Internet Explorer için farklı bir teknik kullanmamız gerekecek. Sayfanın içerisine gizli bir IFRAME (Satır içi çerçeve) ekleyerek IFRAME içerisindeki dosyanın adresini değiştirebiliriz. Bu durum Internet Explorer’da adres geçmişine yeni bir sayfay eklemek için yeterli olacaktır. Tek yapmamız gereken sayfamızı yenileyen AJAX komutlarının başına IFRAME adresini de değiştiren bir kod eklemek. Peki Geri veya İleri düğmelerine basıldığını nasıl anlayacağız? IFRAME içerisinde kullanacağımız adres gerçek bir sayfaya yönlenecek ve eğer tarayıcıdaki düğmeler ile bu sayfa değişmişse bir üst seviyedeki ana sayfaya JavaScript ile bir parametre gönderecek. Böylece ana sayfa AJAX teknikleri ile kendini eski haline çevirecek.
Merak etmeyin, biz bunları tek tek yapmayacağız. Onun yerine bu konuda işimizi çok kolaylaştıracak bir sunucu kontrolü kullanacağız. Bahsettiğim kontrolün adı UpdateHistory. Aşağıdaki adresten kontrol paketini indirebilirsiniz. Paket içerisinde yer alan nStuff.UpdateControls.dll dosyasını Toolbox içerisine ekleyerek projenizdeki herhangi bir sayfaya sürükle&bırak tekniği ile kontrolü ekleyebilirsiniz.
http://www.nikhilk.net/Content/Samples/UpdateControls.zip
Kontrolü sayfaya eklediğinizde aşağıdaki şekilde gözükecektir. Kontrol üzerinde yapmamız gereken hiçbir ayar yok.
<nStuff:UpdateHistory ID=”UpdateHistory1“ runat=”server”>
</nStuff:UpdateHistory>
Sayfa içerisinde ayrıca deneme amaçlı olarak bir UpdatePanel bulunduralım. UpdatePanel içerisine bir düğme ve bir de Label yerleştirelim. Düğmeye her tıklandığında Label içerisindeki sayısal değeri alıp üzerine bir ekleyip geri döndürsün. Böylece sürekli içeriği değişen bir UpdatePanel sahibi olmuş oluruz.
<asp:UpdatePanel ID=”UpdatePanel1“ runat=”server”>
<ContentTemplate>
<asp:Label ID=”etiket“ runat=”server”>0</asp:Label>
<asp:Button ID=”dugme“ runat=”server” OnClick=”dugme_Click” Text=”TIKLA” />
</ContentTemplate>
</asp:UpdatePanel>
Yukarıdaki kod içerisinde düğmeye tıklandığında etiket adındaki Label içerisindeki değeri alarak bir arttıracağımızdan bahsetmiştik. Arttırma işlemini yaparken aslında sayfanın içeriği değiştiği için gerekli kaydın tarayıcıya ait sayfa geçmişi listesine de eklenmesini istiyoruz. Böylece İleri ve Geri düğmeleri ile site içerisinde gezebileceğiz. Bunun için aşağıdaki kodu yazıyor olacağız.
Protected Sub dugme_Click(ByVal sender As Object, ByVal e As System.EventArgs)
etiket.Text = CInt(etiket.Text) + 1
UpdateHistory1.AddEntry(CInt(etiket.Text))
End Sub
Yukarıdaki kodun ilk satırı bize yabancı değil. İkinci satıra baktığımızda ise UpdateHistory kontrolüne ait AddEntry metodunu kullandığımızı görüyoruz. Bu metoda vermiş olduğumuz tek parametre olan metin değeri sayfanın adresine, # işaretinden sonrasına ekleyecek. Tarayıcıda ileri veya geri düğmelerine basıldığında bizim sayfayı tekrar eski haline göre düzenlememiz için geriye yine bu veri döndürülecek. Veritabanına bağlı gerçek bir örnekte sayfada gösterilen veriyi bir veritabanı tablosundan Birincil Anahtar (Primary Key) değerini sorguyla göndererek aldığınızı düşünelim. Bu durumda AddEntry komutu ile adrese ekleyeceğimiz veri Primay Key’in ta kendisi olmalıdır. Böylece bir sonraki adımda göreceğimiz üzere sayfa kullanıcı tarafından ileri ve geri düğmeleri ile değiştirildiğinde adresin # işaretinden sonraki kısmına bakarak sayfaya kolaylıkla veri yerleştirebiliriz.
Son olarak gelelim kullanıcının ileri ve geri düğmelerini kullandığında sayfanın nasıl eski haline dönüştürüleceğine. Bu işlemi yapmak için UpdateHistory kontrolüne ait Navigate metodunu kullanacağız. Söz konusu metod bize hedef sayfanın EntryName değerini döndürüyor olacak.
Protected Sub UpdateHistory1_Navigate(ByVal sender As Object, ByVal e As nStuff.UpdateControls.HistoryEventArgs) Handles UpdateHistory1.Navigate
If String.IsNullOrEmpty(e.EntryName) = False Then
etiket.Text = e.EntryName
Else
etiket.Text = “0″
End If
End Sub
Kodumuz içerisinde ilk olarak gelen parametrenin boş olup olmadığını kontrol ediyoruz. Eğer sayfa ilk defa açılıyorsa söz konusu parametre boş olacaktır. Bu durumda etiket adındaki Label içerisine 0 yazmamız yeterli. Eğer UpdateHistory tarafından bize döndürülen EntryName boş değilse kullanıcı bir şekilde Geri veya İleri düğmelerini kullanmış demektir. Kullanıcının hangi sayfaya gitmek istediğini EntryName değişkeni ile anlıyorum. Benim örneğimde bu veriyi direk etiket içerisine yazdırıyorum. Veritabanına bağlı gerçek bir örnekte siz geri dönen Primary Key verinize göre veritabanından gerekli içeriği çekerek sayfaya yerleştirebilirsiniz.
Son olarak projemin doğru çalışıp çalışmadığını kontrol etmek için UpdatePanel dışına da bir Label yerleştirerek sayfa açılışında mevcut saat bilgisini yazdırdım. Böylece sadece UpdatePanel içeriği mi yenileniyor yoksa tüm sayfa mı yenileniyor anlayabileceğim.
Son hali ile sayfanın HTML kodu aşağıdaki şekilde;
<%@ Page Language=”VB” AutoEventWireup=”true” CodeFile=”Default.aspx.vb” Inherits=”_Default” %>
<%@ Register Assembly=”nStuff.UpdateControls” Namespace=”nStuff.UpdateControls” TagPrefix=”nStuff” %>
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.1//EN” “http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head runat=”server”>
<title>Untitled Page</title>
</head>
<body>
<form id=”form1″ runat=”server”>
<ajaxToolkit:ToolkitScriptManager ID=”ScriptManager1″ runat=”server” />
<div>
<nStuff:UpdateHistory ID=”UpdateHistory1″ runat=”server”>
</nStuff:UpdateHistory>
<asp:UpdatePanel ID=”UpdatePanel1″ runat=”server”>
<ContentTemplate>
<asp:Label ID=”etiket” runat=”server”>0</asp:Label>
<asp:Button ID=”dugme” runat=”server” OnClick=”dugme_Click” Text=”TIKLA” />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Label ID=”Label1″ runat=”server” Text=”Label”></asp:Label></div>
</form>
</body>
</html>
Sayfamızın Code-Behind kısmı da aşağıdaki gibi sonlandı.
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub dugme_Click(ByVal sender As Object, ByVal e As System.EventArgs)
etiket.Text = CInt(etiket.Text) + 1
UpdateHistory1.AddEntry(CInt(etiket.Text))
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Label1.Text = Date.Now.ToLongTimeString
End Sub
Protected Sub UpdateHistory1_Navigate(ByVal sender As Object, ByVal e As nStuff.UpdateControls.HistoryEventArgs) Handles UpdateHistory1.Navigate
If String.IsNullOrEmpty(e.EntryName) = False Then
etiket.Text = e.EntryName
Else
etiket.Text = “0″
End If
End Sub
End Class
Çözümümüz ile aslında sadece Geri ve İleri tuşları ile ilgili sorunu çözmedik. Ayrıca AJAX uygulamalarında her sayfanın ayrı adreslerinin olmaması sorununu da çözdük. Kopyala - Yapıştır tekniği ile adresler # işaretinden sonraki kısımları ile beraber taşındıklarında başka bir tarayıcıda denenmeleri durumda sayfa doğru konumda açılacaktır.
Hepinize kolay gelsin.






