Javascript

Web uygulamaları geliştirirken MasterPage kontrolü kullanıldığında içerik sayfalarında kullanılan sunucu kontrolleri istemci tarafında farklı isimlendirilir.
Örneğin, Name özelliği txtAd olan TextBox kontrolünün istemci tarafında aldığı id değeri ctl00_ContentPlaceHolder1_txtAD olacaktır. Bu durumda istemci tarafındaki javascript fonksiyonundan kontrollere erişim çok pratik olmayacaktır.

Şimdi bu durum karşısında nasıl bir tavır takınacağımıza bakalım :)

Örneğimizde, içerik sayfasında bulunan 4 adet TextBox kontrolünün Text özelliğini temizleyen bir javascript fonksiyonumuz olacak.

JavaScript

Html

Nasıl ki MasterPage kontrolü, karışıklığı engellemek için kontrollerin id lerine contentplaceholder ekliyorsa, bizde temizlemek istediğimiz kontrolleri, id özelliği region1 olan bir div içinde kullandık.
Daha sonra div içindeki tüm input kontrollerini aldık ve özelliği text olanları temizledik.

Bazen Asp.Net sayfalarımızın client tarafında durum gereği farklı davranmasını isteyebiliriz. Tabiki javascript kodlarını devreye sokarak.
.NET Framework 2.0 versiyonu ile bunu yapmanın yolu ClientScriptManager Class ının RegisterStartupScript metodunu kullanmak olacaktır.
Bilindiği gibi RegisterStartupScript metodu 1.1 versiyonuda da bulunmaktaydı. Birçok metod gibi 2.0 ile bunun da kullanımı biraz değişmiş :)

Uygulamamızda;

client tarafında
window.open( [sURL] [, sName] [, sFeatures] [, bReplace]) metodunu

kod tarafında ise
public void RegisterClientScriptBlock ( Type type, string key, string script ) metodunu kullanacağız.

Şimdi ise Logon Button' nun Click Olayına ilgili kodu yazalım,

if (logon())
{
   ClientScriptManager csm = Page.ClientScript;
   
StringBuilder sb = new StringBuilder();
   
sb.Append(
"<script language=\"javascript\">");
   
sb.Append(
"window.onload = function()");
   
sb.Append(
"{");
   
sb.Append(
"window.open(\"loading.aspx\",\"load\",\"");
   
sb.Append(
"height=\" + (window.screen.availHeight - 30) + \",");
   
sb.Append(
"width=\" + (window.screen.availwidth - 10) + \",");
   
sb.Append(
"top=0, left=0, menubar=0, location=0, resizable=1, status=0\");");
   
sb.Append(
"if (window.name != \"load\")");
   
sb.Append(
"{");
   
sb.Append(
"this.focus();");
   
sb.Append(
"top.window.opener = top;");
   
sb.Append(
"top.window.open('','_parent','');");
   
sb.Append(
"top.window.close();");
   
sb.Append(
"}");
   
sb.Append(
"}");
   
sb.Append(
"</script>");
   
csm.RegisterClientScriptBlock(
this.GetType(), string.Empty, sb.ToString());
}
else
{
   
//Giriş Başarısız
}

StringBuilder sb = new StringBuilder();
sb.Append("window.onload = function picture()\n{\n"
);
sb.Append("var pictures = new Array();\n"
);
FileInfo[] files = new DirectoryInfo(Server.MapPath("./images/"
)).GetFiles();
for (int i = 0
; i < files.Length; i++)
   sb.Append(string.Format("pictures[{0}] = 'images/{1}';\n"
, i, files[i].Name));
sb.Append("var number = Math.floor(Math.random() * " + files.Length + ");\n"
);
sb.Append("document.getElementById('" + Image1.ClientID + "').src = pictures[number];\n"
);
sb.Append("setTimeout('picture()',1000);\n}"
);

ClientScriptManager
cn = Page.ClientScript;
if (!cn.IsStartupScriptRegistered("picture"
))
   cn.RegisterClientScriptBlock(typeof(Page), string.Empty, sb.ToString(), true
);

Geçenlerde bir soru üzerine araştırırken yaptığım örnek. Javascript ve saop ile web servisini server-side yapı olmadan Html sayfasında göstermek.

<html
>
<
head
>
   <title>Javascript ile Web Servis Tüketmek</title
>
   <script
>
   var
xmlhttp;
   function
get()
   {
      var city = document.getElementById('city'
).value;
      xmlhttp=
N';
      try
      {
         xmlhttp=new ActiveXObject("Msxml2.XMLHTTP"
);
      }
      catch
(e)
      {
         try
         {
            xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"
);
         }
         catch
(oc)
         {
            xmlhttp=N'
;
         }
      }
      if(!xmlhttp&&typeof XMLHttpRequest!="undefined"
)
      {
         xmlhttp=new
XMLHttpRequest();
      }
      if (xmlhttp!=N'
)
      {
         xmlhttp.onreadystatechange=state_Change; 
         xmlhttp.open("POST", "http://www.webservicex.net/WeatherForecast.asmx?op=GetWeatherByPlaceName", true
);
         xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8"
);
         xmlhttp.setRequestHeader("SOAPAction", "http://www.webservicex.net/GetWeatherByPlaceName"
);
         var text = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>'
;
         text += '<GetWeatherByPlaceName xmlns="http://www.webservicex.net"><PlaceName>' + city + '</PlaceName></GetWeatherByPlaceName>'
;
         text += '</soap:Body></soap:Envelope>'
;
         xmlhttp.send(text);
      }
      else
      {
         document.getElementById('dvResult').innerHTML ="Your browser does not support XMLHTTP.";

      }
   }
   function
state_Change()
   {
      document.getElementById("picture").style.display = 'inline'
;
      if (xmlhttp.readyState == 4

      { 
         document.getElementById('status').innerHTML = 'OK!'
;
         document.getElementById("picture").style.display = 'none'
;
         var nodes = xmlhttp.responseXML.getElementsByTagName("WeatherData"
);
         var htmlR = ''
;
         htmlR = '<table border=1>'
;
         htmlR += '<tr>'
;
         htmlR += '<th>Day</th><th>WeatherImage</th><th>MaxTemperatureC</th><th>MinTemperatureC</th>'
;
         htmlR += '</tr>'
;
      for(var i = 0
;i<nodes.length;i++)
      {
         try
         {
            htmlR += '<tr>'
;
            htmlR += '<td>' + nodes[i].childNodes.item(0).text + '</td>'
;
            htmlR += '<td><img src=' + nodes[i].childNodes.item(1).text + ' /></td>'
;
            htmlR += '<td>' + nodes[i].childNodes.item(4).text + '</td>'
;
            htmlR += '<td>' + nodes[i].childNodes.item(5).text + '</td>'
;
            htmlR += '</tr>'
;
         }
         catch
(e)
         {
            ;
         }
      }
      htmlR += '</table>'
;
      document.getElementById('dvResult'
).innerHTML = htmlR;
      }
   }
   </script
>
</
head
>
<
body
>
   <b>Şehir :</b
>
   <input type="text" id="city" value="alabama"
/>
   <input type="button" value="Hava Durumu" onclick="get()"
/>
   <br
/>
   <div id
="dvResult">
   </div
>
   <img alt="wait" src="circle.gif" id="picture" style="display: none;"
/>
   <span id="status"></span
>
   <br
/>
</
body
>
</
html
>

İkinci basit Web Part'ımız.

string getWeatherFromChache(string Sehir)
{
   if (HttpContext.Current.Cache[Sehir] == N'
)
   {
      try
      {
         string servis = "http://www.webservicex.net/globalweather.asmx/GetWeather?CityName=" + Sehir + "&CountryName=turkey"
;
         WebClient client = new WebClient
();
         string
data = client.DownloadString(servis);
         XmlDocument doc = new XmlDocument
();
         doc.LoadXml(data);
         string nodes = doc.GetElementsByTagName("string")[0
].InnerText;
         doc.LoadXml(nodes);
         string Temperature = doc.SelectSingleNode("/CurrentWeather/Temperature"
).InnerText;
         string RelativeHumidity = doc.SelectSingleNode("/CurrentWeather/RelativeHumidity"
).InnerText;
         StringBuilder sb = new StringBuilder
();
         sb.Append("<table style=font-family:verdana;font-size:12px; border=0 width=100%><tr>"
);
         sb.Append("<td width=20%><b>Sıcaklık : </b></td>"
);
         sb.Append("<td width=80%>"
);
         sb.Append(Temperature);
         sb.Append("</td></tr>"
);
         sb.Append("<td><b>Nem : </b></td>"
);
         sb.Append("<td>"
);
         sb.Append(RelativeHumidity);
         sb.Append("</td></tr>"
);
         sb.Append("</table>"
);
         HttpContext.Current.Cache.Insert(Sehir, sb.ToString(), N', DateTime.Now.AddHours(5), TimeSpan
.Zero);
      }
      catch
      {
         HttpContext.Current.Cache.Insert(Sehir, "Bilgi alınamıyor.", N', DateTime.Now.AddSeconds(5), TimeSpan
.Zero);
      }
   }
   return HttpContext
.Current.Cache[Sehir].ToString();
}

Şehir Listesi:

<?xml version="1.0" encoding="utf-8" ?>
<
Sehirler
>
   <
Sehir>Istanbul / Ataturk</Sehir
>
   <
Sehir>Ankara / Esenboga</Sehir
>
   <
Sehir>Ankara / Etimesgut</Sehir
>
   <
Sehir>Murted Tur-Afb</Sehir
>
   <
Sehir>Adana / Sakirpasa</Sehir
>
   <
Sehir>Adana / Incirlik</Sehir
>
   <
Sehir>Afyon</Sehir
>
   <
Sehir>Antalya</Sehir
>
   <
Sehir>Gaziantep</Sehir
>
   <
Sehir>Iskenderun</Sehir
>
   <
Sehir>Konya</Sehir
>
   <
Sehir>Merzifon</Sehir
>
   <
Sehir>Samsun</Sehir
>
   <
Sehir>Sivas</Sehir
>
   <
Sehir>Zonguldak</Sehir
>
   <
Sehir>Malatya / Erhac</Sehir
>
   <
Sehir>Kayseri / Erkilet</Sehir
>
   <
Sehir>Sivrihisar</Sehir
>
   <
Sehir>Tokat</Sehir
>
   <
Sehir>Aydin</Sehir
>
   <
Sehir>Bursa</Sehir
>
   <
Sehir>Balikesir</Sehir
>
   <
Sehir>Bandirma</Sehir
>
   <
Sehir>Canakkale</Sehir
>
   <
Sehir>Eskisehir</Sehir
>
   <
Sehir>Izmir / Adnan Menderes</Sehir
>
   <
Sehir>Isparta</Sehir
>
   <
Sehir>Usak</Sehir
>
   <
Sehir>Dalaman</Sehir
>
   <
Sehir>Akhisar</Sehir
>
   <
Sehir>Corlu</Sehir
>
   <
Sehir>Bodrum</Sehir
>
   <
Sehir>Elazig</Sehir
>
   <
Sehir>Diyarbakir</Sehir
>
   <
Sehir>Erzincan</Sehir
>
   <
Sehir>Erzurum</Sehir
>
   <
Sehir>Kars</Sehir
>
   <
Sehir>Trabzon</Sehir
>
   <
Sehir>Urfa</Sehir
>
   <
Sehir>Van</Sehir
>
   <
Sehir>Batman</Sehir
>
</
Sehirler
>

Küçük bir globalization sorunu. Gridview içinde silme işlemi için client taraflı uyarı ama hem Türkçe hem İngilizce;

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
   CultureInfo turkish = new CultureInfo("tr-TR"
);
   CultureInfo thisCulture = Thread
.CurrentThread.CurrentCulture;
   if (e.Row.RowType == DataControlRowType
.DataRow)
   {
      if
(turkish.Name == thisCulture.Name)
         (e.Row.FindControl("LinkButton1") as LinkButton).Attributes.Add("onclick", "return confirm('Eleman silinecek ?');"
);
      else
         (e.Row.FindControl("LinkButton1") as LinkButton).Attributes.Add("onclick", "return confirm('Item will be deleted ?');"
);
   }
}

TextBox lar arasında Enter ile dolaşmak için Javascript kodu

function tabor(e)
{
   var inputs = document.getElementsByTagName('input');
   var len = inputs.length;
   if(e.keyCode == 13)
   {
      for(var i = 0;i<len;i++)
      {
         if(inputs[i].type == 'text' && inputs[i].sourceIndex == document.activeElement.sourceIndex)
         {
            try
            {
               inputs[i+1].focus();
               break;
            }
            catch(f)
            {
               ;
            }
         }
      }
   }
}

<script>
   window.onload=
   function
easyClock()
   {
      var Tarih = new
Date();
      spSaat.innerText = Tarih.toLocaleTimeString();
      setTimeout('easyClock()',1000
);
   }
</script>
<span id="spSaat"></span>

Asp.Net ve Focus

11.Temmuz.2007 Javascript Asp.net

Webform larında bulunan kontrollere odaklanmak için bir sürü yöntem varmış inceledik;

Asp.Net 2.0 ile gelen 2 yeni form özelliği

//odaklanacak bir TextBox ise
<form id="form1" runat="server" defaultfocus
="txtSname">
//Button ise
<form id="form1" runat="server" defaultbutton
="btnSend">

//Asp.Net 1.1 olsaydı
<body onload
="document.form1.txtSname.focus()">
//yada
<body onload
="document.form1.txtSname.select()">

Programatik yapmak istersek

protected void Page_Load(object sender, EventArgs e)
{
   if
(!IsPostBack)
   {
      xtSname.Focus();
      //yada
      
SetFocus(txtSname);
      //yada
      RegisterStartupScript("sFocus", "<scrip>document.getElementById('" + txtSname.ClientID + "').focus();</script>");

   }
}

Web Forum'u içinde ki varsayılan Button'u değiştirmek için JavaScript kodu aramaya gerek yok. Sunucu tarafında dinamik olarak üretilen WebResource içinde ki WebForm_FireDefaultButton fonksiyonunu çağırmak yeterli olacaktır .

txtSearch.Attributes.Add("onkeypress", "javascript:return WebForm_FireDefaultButton(event, '" + LinkButton1.ClientID + "')");

Sayfa içerisindeki Div elemanının genişliğini tarayıcı genişliği ile dinamik olarak eşitleyen javascript kodu.

<html>
<
head
>
<title>Dinamik Div</title
>
   <script type
="text/javascript">
   function
getWidthFromClient()
   {
      width();
   }
   window.onresize = function
setWidthFromClient()
   {
      width();
   }
   function
width()
   {
      var
width = window.innerWidth;
      document.getElementById('diva'
).style.width = width;
   }
</script
>
</
head
>
<
body onload
="getWidthFromClient()">
   <div id="diva" style="background-color: Red; height: 100px;
">
   </div
>
</
body
>
</
html
>

Bu aralar dersler de örnek olsun diye webpart uygulaması yapıyorum. Bazı çıkarımlar olmadı değil. Sürü ile kontrol hazırladım. İyi kötü yazıyorum birkaç tanesini :)

//google.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeFile
="googleSearch.ascx.cs"
Inherits="googleSearch"
%>
<script type
="text/javascript">
   var
req= N'
;
   function
GetXmlHttpObject()
   {
      try
      
{
         req = new
XMLHttpRequest();
      }
      catch
(e)
      {
         try
         {
            req = new ActiveXObject("Msxml2.XMLHTTP"
);
         }
         catch
(e)
         {
            req = new ActiveXObject("Microsoft.XMLHTTP"
);
         }
      }
   }

   function
stateChange()
   {
      document.getElementById('calImg').style.display = 'inline'
;
      if(req.readyState == 4
)
      {
         document.getElementById('calImg').style.display = 'none'
;
         document.getElementById('calDiv'
).innerHTML = req.responseText;
      }
   }

   function
search()
   {
      var url = './resources/search.aspx?text=' + document.getElementById("txtSearch"
).value;
      GetXmlHttpObject();
      req.onreadystatechange = stateChange;
      req.open("post",url,true
);
      req.send(N'
);
   }
</script
>
<
table
>
   <tr
>
      <td align
="center">
         <img src="images/google.gif" style="width: 200px; height: 68px" alt="google"
/>
      </td
>
   </tr
>
   <tr
>
      <td align
="center">
         <input id="txtSearch" style="font-family: arial, Helvetica, sans-serif; font-size: 12px
;
border: 1px solid #808080" type="text" />
         <
input onclick="search()" id="Button1" style="font-family: arial, Helvetica, sans-serif
;
font-size: 12px; border: 1px solid gray; height: 19px; width: 66px;" type
="button"
value="Ara"
/>
      </td
>
   </tr
>
   <tr
>
      <td
>
         <img src="images/circle.gif" id="calImg" alt="aranyor" style="display: none;"
/>
         <br
/>
         <div id
="calDiv">
         </div
>
      </td
>
   </tr
>
</
table
>

//search.aspx.cs

protected void Page_Load(object sender, EventArgs
e)
{
   string kelime = Request["text"
];
   string adres = @"http://www.google.com.tr/search?hl=tr&q=" + kelime + "&meta="
;
   WebClient client = new WebClient
();
   DateTime dt1 = DateTime
.Now;
   string
data = client.DownloadString(adres);
   DateTime dt2 = DateTime
.Now;
   TimeSpan
ts = dt2 - dt1;
   string pattern = "<h2 class=r>(?<Link>.*?)</h2>"
;
   Regex myRegex = new Regex
(pattern);
   MatchCollection
myCol = myRegex.Matches(data);
   int counter = 0
;
   StringBuilder sb = new StringBuilder
();
   sb.Append("<b>Sonuçlar</b> (<i>"
);
   sb.Append(ts.TotalMilliseconds);
   sb.Append(" toplam Milisaniye</i>)<br />"
);
   sb.Append("<table border=0 width=100% style=font-family:arial;font-size:10px;>"
);
   foreach (Match m in
myCol)
   {
      if ((m.Groups[0].ToString().IndexOf("aramalar:")) == -1
)
      {
         counter++;
         sb.Append("<tr><td width=10%>"
);
         sb.Append(counter.ToString());
         sb.Append("</td>"
);
         sb.Append("<td>"
);
         sb.Append(m.Groups["Link"
].Value);
         sb.Append("</td></tr>"
);
      }
   }
   sb.Append("</table>"
);
   Response.Write(sb.ToString());
}

Geçenlerde 70-528 kitabını karıştırıken aklıma geldi, yazayım dedim.

Javascript Split Join

html

Ara ara web tabanlı WYSIWYG editorleri incelerim. Geçenlerde Fck Editor ile oyalandım. Gerçekten de çok başarılı bir editor olduğunu rahatlıkla söyleyebilirim. Gerçi indirip hemen kullanamıyorsunuz ama biraz ilgi ve alaka ile bunu başarıyorsunuz.

Azıcık araştırdım birazcık kurcaladım ufak tefek te eklemeler yaptım. Amacım Asp.Net Web Form' larında hızlı bir şekilde kullanmak.

Neler yaptım bir bakalım;

  • Editörün config dosyasını Asp.Net için ayarladım.
  • Sadece Asp.Net içinde kullanılacağı için gerekli olmayan dosya ve klasörleri sildim.
  • ToolBar' ı basitleştirdim.
  • Tek tema kullandım, diğerlerini sildim.
  • FileBrowser' ın dört faklı upload tipi için ayrı klasörler ayarladım.
  • Rar uzantı için resim dosyası ekledim.
  • FileBrowser ile dosya listelerken alternatif satır rengi ekledim.
  • FileBrowser' a resimler için önizleme ekledim.

Proje dosyası, fckApplication.

Resimler

Toolbar optimizasyonu Fck Editor Toolbar

Dosya gösterimi için alternatif satır rengi Fck Editor Filebrowser Alternatif

Resimler için ön izleme Fck Editor Filebrowser Image

Geçenlerde Javascript ile bir fonksiyon yazarken, string içerisindeki boşluk karakterlerini başka bir değer ile değiştirmem gerekiyordu ki ilginç bir durum ile karşılaştım (sanırım çok geç kalmışım bunu keşfetmek için).

replace metotunun sadece ilk boşluk için işlem yaptığını gördüm. Çok fazla araştırma gereği duymadım açıkcası.
Basit bir arama algoritması ile çözüm getirdim;

IndexOf

Zon zamanlarda Asp.Net Mvc ile uğraşıyorum. Asp.Net uygulamaları geliştiriken code-behind çalışan biriyseniz ilk etapta belli alışkanlıkları değiştirmek gerekiyor. Bunun yanısıra alışkanlık kazanmış olduğunuz bazı kontrolleride yer yer kullanamamakta ayrı bir problem teşkil ediyor. Buna örnek olarak WYSIWYG editorleri gösterilebilir.

Fck ve TinyMCE olmak üzere sürü ile editör mevcut fakat basit ve hafif bir editör ihtiyacınız varsa htmlArea benim favorim.

Editör dosyalarını buradan örnek projeyi şuradan indirebilirsiniz.

Gelelim projeye adapte etme kısmına;
- Öncelikle editor klasörünü Content klasörüne kopyalıyoruz.

htmlArea

- creator.js dosyasında ki 2. satırı şu şekilde değiştiriyoruz.

editor url

- creator.js dosyasını editörü kullanacağımız sayfaya link verdikten sonra sayfaya 1 adet texteara ekliyoruz.

editor generate

artık sayfamızı test edebiliriz.

htmlArea

Geçenlerde bir web proje için resim kırpma ve yeniden boyutlandırma gibi işlemleri yapmam gerekti. Asp.Net'in yapısı gereği illaki JavaScript kullanmak kaçınılmaz bir durum. Günümüzde de oturup deli gibi JavaScript yazılmaz. O yüzden JQuery' den yardım almaya karar verdim.

ClientSide işlemler için Jquery eklentisi olan Jcrop kullandım. Diğer eklentiler arasından en beğendiğim bu oldu. Geri kalan kısımları ile GDI+ ile hallettim.

image crop

Uygulama.

Asp.Net sunucu kontrollerinden TextBox kontrolünü TextMode="Multiline" özelliği ile kullanıldığında MaxLength özelliği çalışmamaktadır. Buraya çözüm için alternatif yöntemler yazacağım zaman zaman.

İlk çözüm yine sunucu kontrollerinden CustomValidator ile olacak.

CustomValidator;
textarea

devam edecek...

Geçenlerde Asp.Net sunucu kontrollerinden Takvim (Calendar) üzerine uygulama geliştiriyorduk. Önemli günleri vurgulamak çok klasik bir örnektir. Bizde bu örnek üzerinden yola çıktık. Farklı olarak, gün seçildiğinde sonuçları popup pencere ile göstermeye karar verdik.

Örneği besleyecek basit bir xml verisi hazırladık. Veriyi kodda kullanmayı sağlayan basitte bir class yazdık. Gerisi Takvim kontrolünü kullanamaya kaldı.

Sonuçları popup pencerede nasıl göstereceğimizi anlamak için Takvim kontrolünü biraz irdelemek gerekir. Kontrol tarayıcı penceresine basıldığında (Render) html tarafında bir table etiketine karşılık gelir. Varsayılan olarakta herbir hücredeki (td) gün ifadesi anchor etiketi içinde gösterilir. Hücerelere tıklandığında ise dopostback fonksiyonu tetiklenerek işlem yapılır. Fakat bizim uygulamamızda anchor' a ihtiyaç yok.

Calendar Render

O yüzden kontrolün SelectionMode özelliğini None olarak ayarlıyoruz. Böylece hücre içlerine sadece gün değerleri eklenir.

Calendar

Detayları göstereceğimiz popup penceresini açmak için basit bir JavaScript fonksiyonu hazırlıyoruz.

Day Render

Önemli günleri vurgulayacak kodlarımızı Takvim kontrolünün DayRender adlı olayına yazıyoruz. Bu olay, her bir gün  için bir kez tekrarlanır.
Uygun günü yakaladığımızda, hücre içini temizleyip yerine openPen JavaScript fonksiyonunu çağıran bir HyperLink kontrolü ekliyoruz.
Bundan sonra çeşitlendirmek mümkün.

Calendar Result
Uygulamayı daha iyi anlamak için aşağıdaki projeyi indirip bakmanızda fayda var.

Proje