Asp.net MVC FileResult Dosyasını JQuery Ajax ile Yakalamak

1 Eyl

Asp.net mvc projelerinde dosya sonuçlarını kullanıcıya dönmek için action sonucunda File() metodu ile dönüş yapılabilmektedir.

Örneğin bir PDF için.

[HttpPos]
public FileContentResult Test(TestViewModel vm)
{
    var stream = new MemoryStream();
    //... add content to the stream.

    return File(stream.GetBuffer(), "application/pdf", "test.pdf");
}

Excel için;

[HttpPost]
public FileContentResult Test(TestViewModel vm)
{
    var stream = new MemoryStream();
    //... add content to the stream.

    return File(stream.GetBuffer(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "File.xlsx");
}

Bu oluşturulan dosyaya javascript tarafından jquery ile request gönderilirken dikkat edilmesi gereken bir husus, jquery’nin dosyayı bozmasıdır. Benzer bir durum burada yaşanmıştır. Dosya indiriliyor fakat bozuk olduğu için excel tarafından açılamıyor.

Bunu düzeltmek için xhrFields alanında responseType olarak arraybufffer değeri verilmelidir.

$.ajax({
    url: '/server/url',
    type: 'POST',
    contentType: "application/json; charset=utf-8",
    xhrFields : {
	   responseType : 'arraybuffer'
    },
    data: JSON.stringify(jsonData),   
    success: function (data) {
        var blob = new Blob([data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
        var downloadUrl = URL.createObjectURL(blob);
        var a = document.createElement("a");
        a.href = downloadUrl;
        a.download = "data.xls";
        a.click();
    },
});

Asp.net MVC web site oluşturma platformu olması dolayısı ile günümüzde çok sık kullanılmasa bile hala günümüzde yaygın olarak kullanılmaktadır. Dosya indirme konusunda internette epeyce aranmış ve çok fazla çözüm gösterilememiş bir konuya açılık getirmek istedim.

JQuery event.stopPropagation() ve event.preventDefault() metodları

23 Ara

JQuery ile event yakalama işlemleri sırasında iç içe geçmiş HTML elementleri sırasında istemeden bazı karışıklıklara neden olabiliriz. Bu karışıklıklardan bir tanesi, bir elementteki event tetiklendiğinde onun üst elementlerinde de olayın tetiklenmesidir.

event.stopPropagation()

Örneğin bir unorderedlist (<ul>) ile çalışırken listedeki bir eleman(<li>) tıklandığında, hemen (<ul>) elementinde de “click” event tetiklenecektir. Çünkü bu ili element iç içe barındırılmaktadır. Eğer (<li>) elementine tıklandığında (<ul>) elementinde bir “click” event gerçekleşmesinin istenmediği durumda event.stopPropagation() metodu kullanılmaktadır.


$("li").click(function(event){
   event.stopPropagation();
   alert("The li element was clicked.");
});

 

event.preventDefault()

Bir diğer durum ise HTML elementlerinin mevcut eylemlerini engelleme isteğidir. Örneğin bir link tıklandığında doğrudan linkin gösterdiği adrese yönlendirme yapılır. Ancak link tıklandığında bu eylemin engellenmesi gerekiyor ise event.preventDefault(); metodu kullanılabilir.


$("a").click(function(event){
   event.preventDefault();
});

Bu durumda link tıklansa da adrese yönlendirme yapılmaz.

Javascript ile sunucuya dosya yükleme sürecini kontrol etmek

21 Nis

Sunucuya doysa yükleme(File Upload) işlemi, küçük boyutlu dosyalar için kısa zamanda sonuçlanan bir işlemdir. Birkaç KB veya MB boyutundaki dosyaların sunucuya  yüklenmesi çok fazla zaman alamayacağından kullanıcı sabrını fazla zorlamaz. Ancak büyük boyutlu dosyaların yüklenmesi sırasında, yükleme işleminin kullanıcıya süreç olarak ifade edilmesi gerekmektedir. Aksi halde sunucudan uzun süre cevap alamayan kullanıcılar, internet tarayıcısının kilitlendiğini zannederek işlemi sonlandırabilir. Bu durumda yüklemi işlemi yarıda kesilir. Böyle durumların yaşanmaması için dosya yükleme sürecini bir şekilde kontrol altına alarak kullanıcıya işlemin hangi aşamada olduğunu grafiksel veya sözel bir şekilde bildirmemiz gerekmektedir. Tam da bu noktada imdadımıza javascript asenkron programlama yetişmektedir.

Javascript kullananların sıkça başvurduğu asenkron işlemler, dosya yükleme işleminde de etkili bir şekilde kullanıldığında geliştiriciye büyük kolaylık sağlamaktadır.

Dosya yükleme işlemini basit bir şekilde ifade edecek olursak bir form yardımıyla bilgisayarımızdan seçilen dosyaların (resim, müzik, video, veri, v.s) sunucuya aktarılmasıdır diyebiliriz. Bu kısa özetin ardından işlemin nasıl yapıldığına dair bir örnek uygulama göstermek faydalı olacaktır.

File Upload
File Upload

Örnek uygulama ile resimden anlaşıldığı üzere dosya yükleme süreci takip edilmektedir.

Kod tarafında Javascript ile yapılan işlem sadece XMLHttpRequest nesnesine ait olayların(events) yakalanmasıdır. XMLHttpRequest  nesnesi süreci asenkron olarak işletmektedir. Belli durumları olaylar yardımıyla bize bildirmektedir. Örneğin Yükleme sürecini progress event ile, işlemin bittiğini load event ile yakalayabilmekteyiz.

  this.ajax = new XMLHttpRequest();
  this.ajax.upload.addEventListener("progress", onProgressChanged, false);
  this.ajax.addEventListener("load", onFileUploadSuccess, false);
  this.ajax.addEventListener("error", onFileUploadFailed, false);

Bu şekilde event’leri sıralayabiliriz. Arayüz (HTML) tarafında belirlenen progress bar, button gibi elementlerin güncellenerek sürecin kullanıcıya yansıtılması bize kalmıştır. Bu noktada çeşitli yöntemlerle çalışmak mümkündür. Doğrudan javascript tarafından DOM elementlere ulaşıp içerik güncellemesi yapabildiğimiz gibi, JQuery gibi kütüphaneler kullanabiliriz. Ben bu uygulamada MVVM(Model View ViewModel) prensibini de etkin şekilde kullanabilmek açısından Knockoutjs kütüphanesini kullandım.

Sunucu tarafında uygulama Asp.net MVC4 ile oluşturulmuştur. Sunucu tarafında dosyaları diske yazma işini şimdilik kodlamadan bıraktım. Zaten yazının konusu değil.

Örnek uygulamayı GitHub hesabıma yükledim.  MVC4-knockoutjs-fileupload adresinden uygulamaya ulaşabilir, isterseniz katkıda bulunabilirsiniz.

ESRI Arcgis Javascript API with Knockout JS MVVM

4 Nis

Yazıya başlamadan önce, yazının başlığında belirtilen kavramları daha önce duymamış olanlar için kısaca açıklamaya çalışayım. Arcgis Javascript API, ESRI firmasının harita tabanlı javascript uygulamaları geliştirmek için sunduğu bir araçtır. Knockout JS ise javascript tarafında MVVM(Model-View-View Model ) tasarım deseninin uygulanabilmesini sağlayan bir kütüphanedir.

Knockout Js Model
Knockout Js Model

Kısaca söylemek gerekirse Javascript kodu ile HTML kodunun arasında aktarım yapabilen, iki taraf arasında köprü vazifesi gören bir kütüphanedir.

Bu yazının konusu, Arcgis Javascript API ve Knockout JS kütüphanesinin bir arada kullanıldığı bir harita uygulamasını göstermektir. GitHub hesabımda oluşturduğum esri-knockout-mvvm repository içerisinde uygulama kodlarını bulabilirsiniz.

Neden Arcgis JS API ile birlikte Knockout JS kullanma ihtiyacı duydum?

Arcgis Javascript API ile uyglamalar geliştirirken Javascript kodu içerisinde HTML elemanlarının kullanılması noktasına takıldım. Örneğin bir butona tıkladığımızda, butonun olay yakalayıcı metodunda bir HTML tablosunu oluşturur ve sayfanın bir yerine yerleştirir. Burada farklı konuların birbirinden ayrılması (Separation of Concerns) prensibini Javascript programlama dilinde ihlal etmiş oluyoruz. Oysa programlama prensipleri genel kavramlar olup uygulama alanına göre değişmez. Bu sebepten dolayı Knockout JS kullanarak HTML ve Javascript kodunu birbiriden ayırdım.

Uygulama Araç Kutusu:

  • Arcgis Javascript API
  • Knockout JS
  • Bootstrap
  • JQuery
  • Dojo

Uygulama Özeti:

Uygulama, harita üzerindeki bir noktaya tıklandığında, tıklanan yerin yakınlarındaki sosyal aktiviteleri, olayları göstermektedir. Bu bilgileri seatgeek.com API üzerinden çekmektedir.

Uygulamanın çalışan halini buradan inceleyebilrsiniz.

Uygulama Görseli
Uygulama Görseli

Javascript ve HTML Dom element etkileşimleri

8 Ara

Javacsript kodu ile HTML Dom elementler arasındaki etkileşimleri genelde elementin ID değeri üzerinden sağlarız. Javascript kodu ile document.getElementById(“elementId”) şeklinde ID aracılığıyla elementin seçilebilmesi mümkündür. Bu aşamadan sonra ise element üzerindeki bir değerin değiştirilmesi veya bir olayın(event) tetiklenmesi gibi işlemeri yapmak daha kolay hale gelmektedir.

HTML elementleri üzerinde tanımlı mevcut nitelikler(attributes), javascript tarafından elemente erişmemizi sağlarlar. Mevcut elementlerin kullanılabildiği gibi kendi tanımlayacağımız özel elementler üzerinden de bağlantı kurmamız mümkündür. Günümüzde kullanılan birçok Javascript kütüphanesi kendi tanımladığı nitelikler üzerinden işlemlerini yürütmektedir. Örneğin AngularJS ile çelışırken “ng-*” şeklinde veya JQuery ile çalışırken “data-*” şeklinde nitelikleri görürüz.

Şimdi bir senaryo geliştirerek biz de kendi tanımladığımız HTML nitelikler aracılığı ile bir uygulama geliştirmeye çalışalım. Bir buton elementi üzerine ekleyeceğimiz netelikleri(attribute) javascript tarafında kullanmaya çalışalım.

<button type="submit"
         data-get-async="true"
         data-url="/products.txt"
         data-attr-target="#getasyncresult">Getir
 </button>

Buton üzerinde data-get-async, data-url, data-attr-target şeklinde tanımladığımız nitelikleri anlamlandırmamız gerekmektedir.

data-get-async: işlemin asenkron gerçekleştirileceğini,
data-url: talebin gönderileceği adresi,
data-attr-target: talep sonrasında dönen cevabın hengi elementi etkileyeceğini belirtiyoruz.

Javascript dosyasını (deneme.js) ise şu şekilde düzenliyoruz:

<script type="text/javascript">

   $(function() {
       var buttonRequest = function () {
       var $button = $(this);
       var options = {
           url: $button.attr("data-url")
      };

      $.ajax(options).done(function(data) {
        console.log(data);
        var $target = $($button.attr("data-attr-target"));
        $target.html(data);
      });
  };

  $("button[data-get-async='true']").click(buttonRequest);
})
</script>

javascript tarafında gerçekleştirdiğimiz işlemi kısaca özetleyecek olursak, yaptığımız şey data-get-async niteliğini barındıran buton tıklandığında yapılacak işlemi belirlemektir.

$(“button[data-get-async=’true’]”).click(buttonRequest);

Bu örnekte “data-*” şeklinde nitelikler tanımlamamın sebebi yardımcı olarak JQuery kütüphanesini kullanıyor olmamdır.

JQuery ajax sorgusu için gerekli url gibi seçenekleri de yine buton üzerinde tanımlanan niteliklere tanımlıyoruz. Geriye kalan ise javascript işlemleridir.

Bu şekilde bir uygulama ile HTML tarafı ile Javascript kod tarafı birbirinden ayrılmış olmaktadır. Yani ön yüz(front end) geliştirme tarafında, Model ve View şeklinde bir ayrım yapılmış olmaktadır. Javascript MVC geliştirme araçlarının yaptığı işlem de bu şekildedir aslında. Direktifleri HTML nitelikeri(attributes) aracılığı ile alır ve komutları çalıştırırlar.

Bir sonraki yazıda görüşmek dileğiyle.

Asp.Net MVC 4 ve Jquery Datepicker uygulaması

26 Ara

Asp.Net MVC 4 uygulamalarında tarih biçimli form elemanlarını seçenekli bir şekilde kullanıcıya sunmak için en etkili yöntem JQuery datepicker UI elementini kullanmaktır. JQuery datepicker elementi ile detaylı bilgiye buradan ulaşabilirsiniz. Dil seçeneklerine kadar bir çok özelliği bu siteden bulabilrsiniz.

date1

Asp.net MVC 4 uygulamamızda tarih biçimindeki bir form elemanına nasıl datepicker özelliği eklendiğini incelemeye çalışacağız.

Hemen bir MVC 4 projesi oluşturarak işe başlayabiliriz. Uygulamımızda formu temsil etmek için rezervasyon adında bir Model tanımlıyoruz.


namespace DatepickerJQueryDemo.Models
{
     public class Reservation
     {
       public string Name { get; set; }
       public DateTime Date { get; set; }
     }
}

Modelimizi kullanmak adına ReservationController adında bir controller ekleyerek devam edebiliriz.


public class ReservationController : Controller
{
     public ActionResult Create()
     {
      return View();
     }
}

ReservationController sınıfımınız Create action metodu bir view döndürmektedir. Bu view içerisinde de create formu ve içierisinde de Name ve Date şeklinde iki metin kutusu olacaktır. Bundan sonraki adımınız Date şeklindeki metin kutusuna datepicker özelliğini katmak olacaktır.

editor

Yapacağımız ilk hamle SolutionExplorer penceresindeki projemizin Views dizinindebulunan Shared dizini içerisine EditorTemplates adında bir klasör ekleyip içerisine DateTime adında bir PartialView eklemek olacaktır.

partialview

EditorRemplates ve DisplayTemplates hakkında daha önceden yazılmış makaleleri buradan inceleyebilirsiniz. Bu işlemi yaptığımızda artık bütün view sayfalarındaki DateTime tipinde olan form elemanları (Html.EditorFor extension metodundan) tanımladığımız bu editör template dosyasını kullanır. Burada dikkat edecek olursak “model DateTime?” şeklinde modelin Nullable tipinde olduğunu belirtiyoruz. Bu belirtimi yapmadığımızda karşılaşacağımız hata mesajı şu şeklide olacaktır.

Hata: The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type ‘System.DateTime’.

Bu hatanın sebebi Create action metodunun view sayfası bir reservation modeline bağlı olamsı, ancak create view sayfasına herhangi bir model nesnesi gönderilmediğinden modelin null olmasıdır. Bu sebeple Datetime nesnesi null şeklinde bir hata mesajı karşımıza çıkar.

Bu ince noktayı belirttikten sonra artık ikinci hamleye geçebiliriz. Bu hamlemiz ise formumuzdaki Date tipindeki text kutusuna JQuery datepicker tarafından kullanılacak olan “data-datepicker” adında bir class eklemek olacaktır. JQuery UI scripti bir elementte bu sınıfı gördüğünde, o elemente datepicker özelliğini yapıştırır.

javascript

Bu javascript kodu, input tipinde olan ve “data-datepicker” sınıfını içieren elementlere datepicker özelliğini ekler. Bir önceki adımımızda TextBox tipine “new{data_datepicker=true}” şeklinde sınıf eklemesini yapmıştık.

Bu javascript kodunu bir js dosyasına kaydedip  Create viewe sayfasına refereans olarak gösterebilirsiniz. Ya da direk Create sayfası içerisine yazabilirsiniz.

Son adımda ise Create view sayfasına jquery.ui dosyasını referens olarak vermek gerekmektedir. Bu dosya isteğe göre _Layout.cshtml sayfasına da referans verebilirsiz. Jquery datepicker  elementinin rengi ve şekline bağlı görünüm özellikleri de Content/themes/base/ jquery-ui.css dosyasında bulunmaktadır. Bu dosyayı da refereans olarak eklemeliyiz.

<link href=”~/Content/themes/base/jquery-ui.css” rel=”stylesheet” />

<script src=”~/Scripts/myscripts.js”></script>

<script src=”~/Scripts/jquery-ui-1.8.20.js”></script>

son

Not: Eğer jquery-ui.js refereansını eklemeyi unutursanız aşağıdaki gibi javascript hataları alabilirsiniz.

Hata: 0x800a01b6 – Microsoft JScript çalışma hatası: Nesne, ‘datepicker’ özelliğini veya yöntemini desteklemez.

Çalışan örnek uygulamaya buradan ulaşabilirsiniz.

Bir sonraki yazıda görüşmek dileğiyle.

Ajax Loader Spinner Gifleri

10 Tem

Ajax destekli sitelerde “işlem devam ediyor” ya da “yükleniyor” gibi efektlerin hareketli  (gif uzantılı) resimlerle ifade edilmesini çoğumuz görmüşüzdür. Özellikle de sosyal paylaşım sitelerinin vazgeçilmez ifadeleridir bu resimler. Buradaki siteden siz de istedğiniz şekilde bir spinner oluşturabilirsiniz.

Spinner resimlerin şeklini, arka plan ve hareketli kısmın renklerini de seçmek tamamen size kalmış.

Birkaç örnek indirdim bile.

Tekrar görüşmek dileğiyle.

Asp.net MVC Jquery UI autocomplete

3 Tem

JQuery kütüphanesinin sunduğu güzel bir özelikte autocoplete özelliğidir.  Yani bir html input text içerisine yazmaya başladığımızda bize bazı öneriler sunan bir özelliktir. Arama motorlarında sıklıkla gördüğümüz öneri listeleri, bize fikir verebilir.

Bu işlemi gerçekleştirmek için öncelikle, JQuery tarafından kullanılacak olan action metodun hazırlanması gerekmektedir.


public class HomeController : Controller
{
     public ActionResult Index()
     {
          return View();
     }

     public ActionResult Search(string term)
     {
         var data = names.Where(m => m.Contains(term))
                         .Select(m => new { label = m });

         return Json(data, JsonRequestBehavior.AllowGet);
     }

     private List<string> names = new List<string>
     {
         "adana",
         "antalya",
         "ankara",
         "trabzon",
         "tokat",
         "istanbul",
         "izmir",
         "içel",
     };
}

Bizim kullanacağımız metod Search action metodudur.  Yani text kutusuna bir giriş yaptığımızda, JQuery otomatikmen Search() metoduna gelerek, girdiğimiz yazıyı names listesinden arayarak bize sonuçları getirecektir. Canlı uygulamalar için buradaki gibi bir listeyi kullanmak yerine, veritabanına erişerek gerçek verileri alabiliriz.

Şimdi de Index view sayfasına giderek bir text kutusu oluşturarak devam edelim.


<h2>Test Page</h2>

<script type="text/javascript">

$(function () {

       $(":input[data-autocomplete]").each(function () {

            $(this).autocomplete({
                source: $(this).attr("data-autocomplete")
            })
      });

});

</script>

<div>
<label>Arama</label>
<input type="text" data-autocomplete="@Url.Action("Search","Home")" />
</div>

Index view sayfamızın içeriği yukarıdaki gibi olmalıdır. Ne yaptığımıza biraz değinelim.

Öncelikle $(“:input[data-autocomplete]”) şeklinde bir multiple selector kullanarak tüm autocomplete property olan elementleri aldık. Daha sonra, bu elementlerin içerisinde each() metodu ile gezintiye çıktık. Autocomplete mekanizması, source(veri kaynağı) ihtiyacı olan bir kontrol olduğundan, hangi text input’a autocomplete özelliği vereceksek ona data-autocomplete adına bir property tanımlıyoruz. Ardından bu özelliğe vermek istediğimiz kaynağı belirtiyoruz. Biz burada Home controller sınıfının Search action metodunu belirtiyoruz. Bu sayede input texte yazmaya aşladığımızda Search metodu otomatikmen tetikleniyor.

Yukardaki şekildeki sonucu elde etmiş oluyoruz.

JQuery Bildirim Paneli Hazırlama İşlemi

3 Tem

Web dünyasına Javascript’in gücünü gösteren kütüphane olan JQuery, artık geliştiricilerin gözdesi. JQuery sayesinde neler yapılmıyor ki. Özellikle sosyal paylaşım sitelerinde sıklıkla göze çarpan bildirim panelleri benim de dikkatimi çekmedi diyemem. Hemen klavyenin başına geçerek bir iki deneme yapmaya karar verdim ve güzel bir sonuç çıktı ortaya. Dilerseniz beraber inceleyelim.

Web sayfalarında sağ veya sol panellerde, son bildirimleri kayan yazılar şeklinde efektlendiren bir demo yapmaya çalışalım.

Bu işlem için gereksinimimiz bir jquery kütüphanesi referansı ve kodlama için bir ortam. Ben bu uygulama için notepad aracını seçtim. Notepad içerisine html döküman oluşturacak kodları girerek işe başladım ve ardından jquery kodlarını akledim.


<script>

   $(function () {
       setInterval("updateShouts()", 3000);
   });

    function updateShouts() {
       $('#foo').prepend('<div style="display: none;">Yeni içerik.'+Math.random()+'<p><a href="#">İçerik linki</a></p></div>');

       $('#foo').find(".newContent:first").slideDown();

       $('#foo .newContent:gt(5)').remove();
}

</script>

<div id="foo"></div>

JQuery ile bir timer nesnesi kullanılarak, 3 saniyede bir yeni içerik oluşturularak,  panel içerisine eklenmektedir.

Buraya kadar olan işlemler, html bilgisi ve javascript bilgisi ile halledilebilecek şeklide gelişmiştir. Veriler elle üretilmiş ve animasyona sunulmuştur. Tabi gerçek hayat hikayelerinde, yukarıda tanımlanan updateShouts() metodu bir action metoda giderek veri alacak şekilde düzenlenip canlı bir uygulama da hazırlanabilir. Hatta action metod, outputcache mekanizmasıyla desteklenip, gereksiz yere veritabınına gitmeden, direk cache verilerine erişilebilir. Bu da hızda ciddi bir artış sağlar.

Sonuç olarak  yukarıdaki şekildeki gibi bir panel elde edilebilmektedir.

Jquery slide bildirim paneli çalışan uygulamasına buradan ulaşabilirsiniz.

Javascript ile Doğrulama Uyarısı

8 Ara

Microsoft .Net platformunda desktop veya silverlight ile uygulamalar yaparken kullanıcıya evet/hayır tarzı seçimleri yaptırmak gerekebiliyor. Bu seçimleri bir mesaj kutusu yardımıyla halletmek mümkün olabilmektedir. Ancak web ortamında sunucu tabanlı uygulamalarda bu tarz seçenekler olmadığından en uygun yöntem javascript nimetlerinden yararlanmak olacaktır.

Örneğin bir linke veya butona tıkladığımızda “Bunu yapmak istediğinizden emin misiniz?” gibi uyarılar  verdirmek isteyebiliriz. Aşağıdaki örnekte işleme devam etmek veya etmemek konusunda kararı verdirip ikinci adımı belirleyebileceğimiz bir örnek verilmiştir.


<html>
<head>
<script type="text/javascript">

    function ShowConfirm() {
        var confirmation = confirm("Emin misiniz?");
        if (confirmation) {
          alert("Kayıt Silinmiştir.");
        }
        return confirmation;
    };

</script>

</head>
<body>

<h1>Alert uygulaması</h1>

<a href="http://www.bayramucuncu.com"  onclick="return ShowConfirm();">KAYDI SİL</a>

</body>
</html>

Yukardaki örnekte Kaydı sil adında bir link bulunmakta ve linke tıklandığında kullanıcıya
emin olup olmadığı sorulmaktadır.

Umarım faydalı olmuştur herkese iyi çalışmalar.