UpdatePanel.Update JavaScript Muadili

0 dakikada yazıldı

7551 defa okundu

Düzenle

ASP.NET AJAX Extension 1.0 ile beraber gelen UpdatePanel sunucu
kontrolü biz yazılım geliştiricilerin hayatını ciddi şekilde
kolaylaştırdı. Fakat maalesef UpdatePanel'in çok büyük bir eksiği.
UpdatePanel'in UpdateMode özelliği Conditinal olarak
düzenlendiğinde sunucu tarafında UpdatePanel1.Update gibi bir kod
ile herhangi bir UpdatePanel nesnesinin içeriğinin asenkron olarak
yenilenmesini sağlayabilirken bu işlemin istemci tarafından
tetiklenebilmesini sağlayacak hazır bir çözüm yok.

Makalemiz boyunca yukarıda bahsi geçen sorunu çözmek için nasıl bir
teknik kullanabileceğimize ve işimizi kolaylaştırmak için bu teknikleri
bizim için otomatik olarak kullanabilecek bir Control Toolkit
Extender
kontrolünü nasıl programlayabileceğimize değineceğiz.

UpdatePanel JavaScript Extender

Sorunumuzun çözüm tekniklerine girmeden önce gelin makalemiz boyunca
hazırlayacağımız UpdatePanel JavaScript Extender kontrolünün kullanım
şekline bakalım.

      <JS:UpdatePanelJavaScriptExtender TargetControlID="UpdatePanel1"
                                        ClientCommand="Guncelle"
                                        ID="UpdatePanelJavaScriptExtender1"
                                        runat="server">
      </JS:UpdatePanelJavaScriptExtender>

Yukarıdaki kodumuz içerisinde UpdatePanelJavaScriptExtender için
tanımladığımız iki özellik yer alıyor. Bunlardan ilki
TargetControlID özelliği. Sayfamızda JavaScript komutları ile Update
etmek istediğimiz UpdatePanel'in ID bilgisini Extender kontrolümüzün
TargetControlID özelliğine aktarmak durumundayız. İkinci aşamada ise
karşımıza ClientCommand özelliği çıkıyor. JavaScript ile istemci
tarafında UpdatePanel'i Update ederken kullanmak isteyeceğimiz
JavaScript fonksiyonunun adını buraya parametre olarak vermemiz
gerekiyor. Bizim örneğimizde UpdatePanel1'i yenilemek için sayfada
Guncelle JavaScript fonksiyonunu kullanacağız. Kullanacağımız örneğe
ait tam sayfa HTML kodu aşağıdaki şekilde;

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Register Assembly="UpdatePanelJavaScript" Namespace="UpdatePanelJavaScript.UpdatePanelJavaScript"
  TagPrefix="JS" %>
<!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">

    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    <div>
      <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
          <asp:Label
ID="Label1" runat="server" Text="Label"></asp:Label>

        </ContentTemplate>
      </asp:UpdatePanel>
      <JS:UpdatePanelJavaScriptExtender TargetControlID="UpdatePanel1"
                                        ClientCommand="Guncelle"
                                        ID="UpdatePanelJavaScriptExtender1"

                                        runat="server">
      </JS:UpdatePanelJavaScriptExtender>
      <input id="Button1" type="button" value="button" onclick="Guncelle(1);" />
    </div>
  </form>
</body>
</html>

Gördüğünüz gibi sayfamızda, içerisinde bir Label bulunan bir
UpdatePanel ve bir adet HTML Button bulunuyor. HTML buttonun OnClick
özelliğine Guncelle JavaScript fonksiyonumuz yerleştirilmiş. Burada
dikkat etmemiz gereken bir diğer nokta da aslında Guncelle fonksiyonuna
bir de parametre vermiş olmamış. UpdatePanelJavaScriptExtender
kontrolümüz sadece UpdatePanel'i yenilemek ile kalmayacak sunucu
tarafına parametre de aktarabiliyor olacak. Şimdi de sunucu tarafında
yazdığımız koda bakalım.

Partial Class _Default
    Inherits
System.Web.UI.Page

 
    Protected Sub UpdatePanelJavaScriptExtender1_Update
_

                            (ByVal Sender As Object,
_

                            ByVal E As
System.EventArgs, _

                            ByVal parameter As String) _
                            Handles
UpdatePanelJavaScriptExtender1.Update

        Label1.Text = parameter
    End Sub
End Class

UpdatePanelJavaScriptExtender kontrolümüzün Update adında bir durumu
(event) var. Bu durum biz istemci tarafında Guncelle fonksiyonumuzu
çalıştırdığımızda gerçekleşiyor olacak. Update durumunun getirdiği
parametrelere bakarsak arada parametre adında bir String değer
bulunduğunu görebiliriz. Bu değer bizim istemci tarafında Guncelle
fonksiyonuna verdiğimiz 1 değeri olacak. Kodumuz içerisinde gelen bu
değeri Label1 içerisine yazıyoruz. Siz projelerinizde farklı
işlemler yapabilir veya farklı dinamik parametreler, hatta JSON olarak
serialize ederek her tür veriyi, objeyi gönderebilirsiniz.

Peki Nasıl?\

Nasıl oluyor da normal şartlarda UpdatePanel'in JavaScript ile Update
edilme özelliği yokken bizim UpdatePanelJavaScript Extender kontrolümüz
bunu yapıyor? Bir düşünelim; biz UpdatePanel içerisine bir TextBox
koysak ve AutoPostBack özelliğini True yapsak bu kontrol
içerisine birşey yazıldığında UpdatePanel'in yenilenmesini ve TextBox
içerisinde yazının da sunucu tarafına gönderilmesini sağlar mı?
Kesinlikle. Bu durumda gidelim UpdatePanel içerisine ekranda görünmeyen,
gizli bir TextBox ekleyelim. İstediğimiz zaman TextBox içine JavaScript
ile bir metin yazıp (parametremizi) sonra da TextBox'ın içeriği
değiştirildiğinde çalışan onchanged durumundaki JavaScript kodunu
çalıştıralım. Sonra da gidip sunucu tarafında TextBox'ın içindeki veriyi
alıp işlemlerimizi yapalım. İşte UpdatePanelJavaScript Extender
kontrolümüzün yaptığı da aslında bu. Ama bunların hepsini bizden gizli
olarak, bizi hiç uğraştırmadan yapıyor.

İş Başına

Kontrolümüzü kullanmak güzeldi, kolaydı ama bizim bu kontrolün nasıl
hazırlandığını ve hazırlanma aşamasında karşılaşılabilecek olası
sorunları da incelememiz şart. Yeni bir ASP.NET AJAX Control Project
açarak kodlarımızı yazmaya başlayabiliriz. İlk olarak gelin kontrolümüz
için yazdığımız JavaScript kodumuza yani kontrol projemizdeki JavaScript
dosyasının içeriğine bakalım.

/**
 * @author Daron Yöndem
 * @web http://daron.yondem.com
 */
Type.registerNamespace('UpdatePanelJavaScript');
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior = function(element) {
   
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.initializeBase(this, [element]);

    //ClientCommand özelliğimiz için
iç bir değişken tanımladık.

    this._ClientCommandValue =
null;

}
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.prototype =
{

    initialize : function()
{

       
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.callBaseMethod(this, 'initialize');

    },
    dispose : function()
{

       
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.callBaseMethod(this, 'dispose');

    },
    //ClientCommand özelliği için Set
ve Get JavaScript metodlarını tanımladık.

     get_ClientCommand : function() {
        return this._ClientCommandValue;
    },
    set_ClientCommand : function(value) {
        this._ClientCommandValue = value;
    }
}
UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.registerClass('UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior',
AjaxControlToolkit.BehaviorBase);

//JavaScript fonksiyonu çalıştırıldığında
burası çalışacak.

//Buradaki Update JavaScript metodu
parametre olarak

//parametremizi ve gizli TextBox'ın ID sini
alıyor.

UpdatePanelJavaScript.Update = function(HiddenBoxID, parameter) {
  //Gizli TextBox kontrolünü
buluyoruz.

       var HiddenBox
=$get(HiddenBoxID);

  //Parametre yoksa rastgele bir sayı
döndürelim.

       if (typeof(parameter)=="undefined")
       {
             parameter = "RANDOMPARAM" + Math.random();
       };
       //Eğer bir önceki aktarılan
parametre ile

       //şimdiki aynı ise
parametremizin sonuna rastgele bir sayı ekliyoruz.

       if (HiddenBox.value ==
parameter)

       {
             parameter = parameter + "RANDOMPARAM" + Math.random();
       };
       //Parametremizi TextBox'ın
içine koyuyoruz.

       HiddenBox.value = parameter;
       //TextBox'ın onchange
özelliğinde JavaScript kodunu alıyoruz ve temizliyoruz.

       var MyCommand =
String(HiddenBox.onchange).replace('function anonymous()\n{\n','');

       MyCommand = MyCommand.replace('\n}','');
       MyCommand = MyCommand.replace('function onchange(event)
{\njavascript:\n'
,'');

       //onchange durumundaki
JavaScript kodunu çalıştırıyoruz.

       eval(MyCommand);
};\

Olabildiğince satır arası yorumlar ile kodumuzda neler yaptığımıza
anlatmaya çalıştım. Özellikle birkaç önemli noktaya değinmekte fayda
var. JavaScript kodlarımız içerisinde UpdatePanelJavaScript Extender
kontrolümüz için Update adında bir fonksiyon tanımlıyoruz. Bu
fonksiyon içerisinde direk elimizdeki TextBox kontrolüne
ulaşamıyoruz. Eğer sayfamızda birden çok UpdatePanel JavaScript Extender
kontrolü varsa yukarıdaki JavaScript kodu sayfaya sadece bir defa
ekleniyor. Yani yukarıdaki kodun değişkenlere bağımlı olması şart. Bu
durumda biz de TextBox kontrolümüzün adını Update JavaScript
fonksiyonumuza parametre olarak vermeye karar verdik. Söz konusu Update
fonksiyonunu kullanacak başka bir JavaScript fonksiyonu oluşturmayı ve
TextBox kontrolümüzü UpdatePanel'in içerisine eklemeyi sunucu
tarafındaki kodumuzla bir sonraki aşamada yapıyor olacağız.

JavaScript kodumuz ayrıca kendisine verilen parametrenin bir önceki
parametre ile yani TextBox kontrolünün içeriği ile aynı olup olmadığını
da kontrol ediyor. Eğer aynı ise sonuna rastgele bir sayı ekliyor, bu
rastgele sayıyı da sunucu tarafında siliyor olacağız. Neden böyle birşey
yapmaya ihtiyaç duyduğumuza gelince; maalesef TextBox'ın içeriği
değişmez ise onchange durumunu çalıştıramıyoruz. O nedenle aynı
parametre gönderildiğinde de bir Update sağlayabilmek için sonuna
rastgele bir sayı ekleyerek değiştirmiş gibi davranmamız gerekiyor. Son
olarak kodumuzla gizli TextBox'ımızın onchange JavaScript kodunu
alarak ve temizleyerek kendimiz çalıştırıyoruz.

Şimdi geçelim sunucu tarafındaki Extender kodumuza.

Imports System
Imports
System.ComponentModel

Imports System.Web.UI
Imports
System.Web.UI.WebControls

Imports
AjaxControlToolkit

 
#Region "Assembly Resource Attribute"
<Assembly: System.Web.UI.WebResource("UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.js",
"text/javascript")>

#End Region
 
Namespace
UpdatePanelJavaScript

 
    <Description("Creates
JavaScript interface simulating UpdatePanel.Update()"
)>
_

    <Designer(GetType(UpdatePanelJavaScriptDesigner))>
_

    <ClientScriptResource("UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior",
"UpdatePanelJavaScript.UpdatePanelJavaScriptBehavior.js")>
_

    <TargetControlType(GetType(UpdatePanel))> _
    Public Class UpdatePanelJavaScriptExtender
        Inherits
ExtenderControlBase

 
        'Durumları ile beraber
UpdatePanel içerisine ekleyeceğimiz

        'TextBox'ı
yaratıyoruz.

        WithEvents MyTextBox
As New
System.Web.UI.WebControls.TextBox

        'Extender kontrolümüze ait
Update durumunu tanımlıyoruz.

        Public Event Update(ByVal Sender As Object,
ByVal E As EventArgs, ByVal parameter As String)

 
        'ClientCommand özelliğine ait
Get ve Set metodları.

        <ExtenderControlProperty()> _
        <DefaultValue("Update")> _
        Public Property ClientCommand() As String
            Get
                Return
GetPropertyValue("ClientCommand",
"")

            End Get
            Set(ByVal value As String)
                SetPropertyValue("ClientCommand", value)
            End Set
        End Property
 
        'Extender Render edildiğinde
ilk çalıştırılan kodlar.

        Private Sub
UpdatePanelJavaScriptExtender_Init(ByVal sender As Object,
ByVal e As System.EventArgs) Handles Me.Init

            'TextBox AutoPostBack
olsun.

            MyTextBox.AutoPostBack = True
            'TextBox sayfada görünmez
olsun

            MyTextBox.Style.Add("visibility", "hidden")
            MyTextBox.Style.Add("display", "none")
            'Hedef UpdatePanel'i
bulalım.

            Dim TargetPanel
As System.Web.UI.UpdatePanel = Me.TargetControl

            'TextBox'ı
ekleyelim.

           
TargetPanel.ContentTemplateContainer.Controls.Add(MyTextBox)

            'OnClientCommand
özelliğine verilen JavaScript fonksiyonunu yaratalım.

            Dim script As New
System.Web.UI.HtmlControls.HtmlGenericControl("script")

            script.Attributes.Add("type", "text/javascript")
            script.Attributes.Add("language", "javascript")
            Dim builder As New
System.Text.StringBuilder

            builder.Append("function
"
)

            builder.Append(Me.ClientCommand)
            builder.AppendLine("(parameter) {")
            builder.Append("UpdatePanelJavaScript.Update('")
            builder.Append(MyTextBox.ClientID)
            builder.AppendLine("',
parameter);"
)

            builder.AppendLine("};")
            script.InnerHtml = builder.ToString
            'JavaScript fonksiyonumuzu
Extender'a ekleyelim.

            Me.Controls.Add(script)
        End Sub
 
        'UpdatePanel içerisine eklediğimiz
TextBox'a ait TextChanged durumunu kontrol ediyoruz..

        Sub
Control_TextChanged(ByVal sender
As Object, ByVal e As
System.EventArgs) Handles
MyTextBox.TextChanged

            Dim SenderControl
As System.Web.UI.WebControls.TextBox =
sender

         'RANDOMPARAM'ın varlığını kontrol ederek RaiseEvent
ile kendi Update durumumuzu çalıştırıyoruz.

            If
SenderControl.Text.IndexOf("RANDOMPARAM") <> -1 Then

                If
SenderControl.Text.IndexOf("RANDOMPARAM") = 0 Then

                    RaiseEvent
Update(Me, e, "")

                Else
                    RaiseEvent
Update(Me, e,
SenderControl.Text.Substring(0, SenderControl.Text.IndexOf("RANDOMPARAM")))

                End If
            Else
                RaiseEvent
Update(Me, e,
SenderControl.Text)

            End If
        End Sub
    End Class
 
End Namespace

Yukarıdaki kod içerisinde önemli noktalardan birincisi UpdatePanel
içerisine ekleyeceğimiz TextBox kontrolümüzü WithEvents ile
yaratıyor olmak. Böylece söz konusu TextBox'a ait TextChanged
durumunu Extender içerisinde kontrol edebileceğiz ve kendi
Extender'ımızın Update durumunu çalıştırabileceğiz. İkincisi ise
kendi Update durumumuzu (event) tanımlıyor olmamız.

Extender ilk olarak web sayfasına eklendiğinde ve sayfa ilk olarak
istemcide çalıştırıldığında Extender'a ait Inıt durumu çalışacaktır.
Biz Inıt durumunda kendi TextBox'ımızı CSS özellikleri ile
görünmez yaparak AutoPostBack özelliğini de ayarladıktan sonra hedef
UpdatePanel içerisine ekliyoruz. Sonraki adımda da Extender kontrolüne
verilen ClientCommand özelliğine göre Extender JavaScript
kodlarımızdaki Update metodunu kullanacak sayfa içi JavaScript
kodunu yaratmalıyız. Bunun için de bir StringBuilder ve
HTMLGenericControl kullandık. Son olarak JavaScript kodumuzu
Extender'a ekledik.

Gelelim TextBox'a ait TextChanged durumuna. TextBox içerisine
JavaScript ile yerleştirilen metni kontrol etmemiz gerekiyor. Eğer
RANDOMPARAM var ise silmemiz gerek. Bu işlemleri de tamamladıktan
sonra RaiseEvent ile kendi Update durumumuzu çalıştırıyoruz. Böylece
Extender'ı kullananlar Update durumu üzerinde direk parametreyi
alabilecekler.

Altenatif Teknikler

Yukarıdaki kontrolü kullanmak veya kontrolün işleyiş mantığına uymanın
haricinde farklı teknikler de söz konusu. Örneğin aşağıdaki kodu
kullanarak herhangi bir HTML objesinden direk başka bir .NET objesinin
PostBack JavaScript kodunu alarak çalıştırabilirsiniz.

<input id="Button1" type="button" value="button" onclick="<%=
ClientScript.GetPostBackEventReference(new PostBackOptions(TextBox1,
"")) %>" />

Tabi yukarıdaki kod içerisinde TextBox'ın içeriğine bir parametre koyma
şansınız olmayacaktır. Farklı bir şekilde düzeneyerek böyle bir özellik
eklemek de mümkün. Extender kontrolümüzün güzel yanı bize tüm bu
işlevleri kolayca kullanabileceğimiz istediğimiz isimde JavaScript
fonksiyonları ve sunucu taraflı durum kontrolü sağlaması.

Hepinize kolay gelsin.

UpdatePanel JavaScript Extender Kaynak Kodu - 04092007_1.zip (493,15
KB)