Web Geliştirme
28 dk okuma

MVC, jQuery, JSON, Sayfalama ve mapRoute Hakkında Nasıl Yapılır Serisi

ASP.NET MVC, jQuery ve JSON kullanarak yüksek performanslı web uygulamaları geliştirme teknikleri ve pratik çözümler.

N
Necmettin Demir
21 Temmuz 2023
Yükleniyor...

MVC, jQuery, JSON, Sayfalama ve mapRoute Hakkında Nasıl Yapılır Serisi

MVC, jQuery, JSON, Sayfalama
MVC, jQuery, JSON, Sayfalama

Kaynak Kodu İndir


Giriş

Veritabanı sistemlerindeki büyük miktardaki veri nedeniyle istemci tarafı çalışması çok önemli hale gelmiştir. Klasik ASP.NET ile code-behind yaklaşımında, doğal yöntem çoğu işi ASP.NET bileşenlerini kullanarak code-behind dosyalarında kodlamaktır. Dahası, ASP.NET bileşenlerinin render edilmesi ve viewstate mekanizması artık klasik ASP.NET'in zayıf yetenekleri olarak düşünülmektedir.
Bu nedenle yeni bir paradigma ortaya çıktı. Bu yeni paradigmaya göre geliştirici, performansı düşüren viewstate olmadan ve daha az render ile saf HTML ve JavaScript ile çalışabilir.
MVC eski bir tasarım veya mimari kalıp olarak bilinmesine rağmen, özellikle yukarıda bahsedilen klasik ASP.NET darboğazlarından sonra popüler olmuştur. jQuery ve JSON'un etkili bir şekilde kullanıldığı MVC'de yüksek performanslı uygulamalar geliştirilebilir.

Ön Bilgi

Bu makale, MVC, jQuery ve JSON ile ilgili bazı başlangıç düzeyinde makaleleri okuduktan sonra faydalı olabilir. Aşağıdaki bağlantılar yeni başlayanlar için yararlı olabilir:

Kodu Kullanma

Bu makalede bir "nasıl yapılır serisi" hedeflenmiştir. Bu nedenle tüm scriptler ekteki kaynak koddan verilmiştir. Aslında her "nasıl yapılır" ayrı bir makale olabilirdi. Her neyse, tüm olası cevaplar tek bir örnekte toplanmıştır. Bu makalede teorik bilgiden çok pratik yaklaşımlar vardır. Örneğin basitliği için veritabanı yerine bazı statik listeler kullanılmıştır.
Aşağıdaki sorular yanıtlanmaktadır:
  1. MVC'de iyi performansla CRUD nasıl yapılır?
  2. JavaScript confirm veya alert yerine jQuery dialog nasıl kullanılır?
  3. MVC listesinde sayfalama nasıl yapılır?
  4. jQuery kullanarak MVC'de "daha fazla göster" linki nasıl yapılır?
  5. Link ile özellik (attribute) nasıl kullanılır?
  6. jQuery'de AJAX çağrısı nasıl yapılır?
  7. MVC'de Form koleksiyonu nasıl kullanılır?
  8. Tek seferde birden fazla kayıt nasıl silinir?
  9. MVC'de partial action nasıl kullanılır?
  10. MVC uygulamasında JSON formatı nasıl kullanılır?
  11. Master-detail combobox nasıl doldurulur?
  12. jQuery datepicker nasıl kullanılır?
  13. jQuery dialog ile MVC'de resim nasıl yüklenir?
  14. İstemci tarafında tablo satırı nasıl oluşturulur?
  15. Global.asax'ta mapRoute nasıl özelleştirilir?
  16. Tablonun tüm satırları nasıl checkALL ve uncheckALL yapılır?
  17. "Loading Data" nasıl yapılır?
  18. jQuery ile master-detail grid'ler nasıl yapılır?

1) MVC'de iyi performansla CRUD nasıl yapılır?

Kabaca düşünüldüğünde, tüm iş çözümleri Create-Read-Update-Delete (Oluştur-Oku-Güncelle-Sil) özelliğine sahiptir. Mümkünse, hem "insert" hem de "update" için aynı "kaydetme formunu" kullanmak geliştirici açısından maliyet etkin olabilir. Aynı formu kullanmak, action'a gönderilen parametrelerin yönetilmesiyle mümkündür.
Formda grid benzeri bir listeniz (aslında bir HTML tablosu) ve ayrı bir "new" butonu olduğunu varsayın. Tablonun her satırında o satırla ilgili bir "edit" ve "delete" butonu var.
"New" tıklandıktan sonra yeni bir sayfaya - burada view olarak adlandırılır - yönlendirmek verimli bir yol değildir. Çünkü yönlendirilen sayfada veriler kaydedildikten sonra, kullanıcının veritabanına eklenen verileri görmek için "listeyi göster"e tıklaması gerekir. Bu, liste görünümüne yönlendirme ve değişken seçim maliyetiyle veritabanından veri seçme anlamına gelir!
Yukarıda ifade edilen "new'e tıkla ve tekrar listele" senaryosu yerine daha iyi bir yol uygulanabilir.
Create (Oluştur):
  • Liste görünümünde, "New" tıklandıktan sonra bir "jQuery Save dialog" görünebilir.
  • Create view jQuery dialog'a render edilir.
  • Create formu doldurulur ve "Save" basılır.
  • Save butonuna basıldığı anda, veriler AJAX post ile ilgili controller'a gönderilebilir.
  • Ajax formunun onSuccess JavaScript fonksiyonu vardır.
  • "onSuccess" JavaScript metodunda eklenen yeni satır, "onSuccess"'e parametre olarak gelen JSON, tüm liste yenilenmeden listenin başına eklenir (prepend).
Read (Oku):
Bu bir listeleme işlemidir. Mümkünse, liste formunda sadece gerekli veriler gösterilmelidir. Aşağıdaki teknikler kullanılabilir:
  • combobox veya sayılarla sayfalama,
  • "daha fazla göster" implementasyonu,
  • filtreleme ile listeleme.
Update (Güncelle):
  • Liste görünümünde, listenin herhangi bir satırındaki "Edit"e tıklandıktan sonra, seçili satırın verileriyle aynı "jQuery Save dialog" görünebilir.
  • Tüm adımlar "Create" ile aynı olduğundan, sadece "onSuccess" metodu "update" işlemine göre değiştirilir.
  • Bu durumda, veritabanı güncellemesinden sonra sadece düzenlenen satırdaki veriler görünümde güncellenir. Bu şekilde, son düzenlenen kaydı görmek için tüm listeyi yenilemeye gerek yoktur.
Delete (Sil):
  • Güzel görünümlü bir jQuery dialog ile onaydan sonra, veritabanı silme işleminden sonra sadece seçili satır listeden kaldırılır. Yine, tüm listeyi yenilemeye gerek yoktur.
Hem insert hem de edit için aynı dialog kullanılır.
Yeni Kayıt
Yeni Kayıt
PersonList.cshtml görünümündeki linkler aşağıdaki gibidir:
HTML
@Html.ActionLink("New", "Save", 
  new { personNo = 0 }, new { @class = "newLink" })
 
...
 
@Html.ActionLink("Edit", "Save", new { personNo = item.PersonNo }, new { @class = "editLink" })
  • New: Gösterilecek metin.
  • Save: Controller'daki action.
  • personNo: "Save" action'ına gönderilen parametre. Eğer 0 ise, dialog boş açılır, 0'dan büyükse o id'nin verileri dialog'da gösterilir.
  • newLink: Aşağıdaki jQuery'de kullanılacak hayali className.
JavaScript
<div id="saveDialog" title="Person Information"></div>
 
<script type="text/javascript">
 
    var linkObj;
 
    //.....

    $(document).ready(function () {
 
       //...

        $('#saveDialog').dialog({
            autoOpen: false,
            width: 400,
            resizable: false,
            modal: true,
            buttons: {
                "Save": function () {
                    $("#update-message").html('');
                    $("#savePersonForm").submit();
                },
                "Cancel": function () {
                    $(this).dialog("close");
                }
            }
        });
 
 
       //....

       setLinks();
 
    });
 
    // ....
  
    function setLinks() 
    {
 
        $(".editLink, .newLink, uploadPicLink").unbind('click');

        $(".editLink, .newLink").click
        (
            function () 
            {
                linkObj = $(this);
                var dialogDiv = $('#saveDialog');
                var viewUrl = linkObj.attr('href');
                $.get(viewUrl, function (data) 
                {
                    dialogDiv.html(data);
                    //validation
                    var $form = $("#savePersonForm");
                    $form.unbind();
                    $form.data("validator", null);
                    $.validator.unobtrusive.parse(document);
                    $form.validate($form.data("unobtrusiveValidation").options);

                    dialogDiv.dialog('open');
                });

                return false;

            }
        );
 
        //...

 
    } //end setLinks
</script>
PersonController'daki Save action'ı aşağıdaki gibidir:
C#
// ...

[HttpGet]
public ActionResult Save(int personNo)
{
            
  Person person= new Person();
  person.BirthDate = DateTime.Today;
  person.PersonNo = 0;
            
  if (personNo > 0)
  {
     person = Repository.GetPersonList().Where(c => c.PersonNo == personNo).FirstOrDefault();
  }
 
  return PartialView(person);
 
}
 
 // ...  

[HttpPost]
public JsonResult Save(Person p)
{
     //...
}

// ...

2) JavaScript confirm veya alert yerine jQuery dialog nasıl kullanılır?

Özelleştirilmiş mesaj kutusu Windows uygulamasında mümkündür. Web için üçüncü parti bileşen kütüphanesi kullanıldığında mümkündür. Aşağıdaki gibi JavaScript kutuları yerine jQuery dialog kullanmak da mümkündür:
Silme Onayı
Silme Onayı
PersonList görünümündeki Delete linki aşağıdaki gibidir:
HTML
@Html.ActionLink("Delete", "DeletePerson", new { personNo = 
item.PersonNo }, new { @class = "deleteLink", @pkNo = item.PersonNo })
HTML ve jQuery kodu aşağıdaki gibidir:
JavaScript
<div id="confirmDialog" title="Warning"></div>
 
<script type="text/javascript">
//...
 
 $(".deleteLink").live("click", function (e) {
        e.preventDefault();

        // ..
        
        $("#confirmDialog").html('<br/><br/>sure?');

        $("#confirmDialog").dialog({
            resizable: false,
            height: 200,
            width: 300,
            modal: true,
            buttons: {
                "Yes": function () {
                    // ..

                 }, // end of yes button
                "No": function () {
                    $(this).dialog("close");
                }
            } //end buttons
        }); //end modal 
    });     //end delete
 
//...  
</script>

3) MVC listesinde sayfalama nasıl yapılır?

Sayfalama, verileri listeleme ve veri aktarım maliyetini minimize etme için iyi yaklaşımlardan biridir. Verileri görüntülemenin birçok yolu uygulanabilir. Bu "nasıl yapılır"da sayfalama için bir combobox kullanılmıştır. Ancak istenirse, sayfanın altında numaralama da mümkündür. Bu, uygulamaya ve geliştiriciye bağlıdır. Combobox ile sayfalama aşağıdaki gibi geliştirilebilir.
Sayfalama
Sayfalama
Öncelikle, sayfalama meta verileri için yer aşağıdaki gibi düzenlenir:
HTML
@model AddressBook_mvc3_jQuery.Models.Paginginfo

...
 
<div id="paginginfo">
<hr />
    <select id="PageSelect"></select>
    
    <span class="pagingPersonNo" style="visibility:hidden">@Model.id</span>
    <span class="pagingTotalCount" style="visibility:hidden">@Model.TotalCount</span>
    <span class="pagingPageSize" style="visibility:hidden">@Model.PageSize</span>
 
    <span class="pagingSummary">aaa</span>
 
<hr/>
</div>
 
<div id="content"></div>
 
...
Sayfa ilk yüklendiğinde "paginginfo" id'li div doldurulur ve kayıtların ilk sayfası aşağıdaki scriptler kullanılarak gösterilir.
JavaScript
<script type="text/javascript">
 
//...

  function initializePaging()
  {
       var PersonNo = $("#paginginfo .pagingPersonNo").text();
       var TotalCount = $("#paginginfo .pagingTotalCount").text();
       var PageSize = $("#paginginfo .pagingPageSize").text();
       
       var PageSelect = $("#PageSelect");
 
       if (TotalCount==0)
       {
            PageSelect.html("");
            $("#paginginfo").hide();
       }
       else
       {
             PageSelect.html("");
 
             var num = Math.ceil(TotalCount/PageSize);
 
             for (var i = 1; i <= num; i++) 
             {             
                 if (i==1)
                    PageSelect.append($("<option selected></option>").val(i).text(i));
                else
                    PageSelect.append($("<option></option>").val(i).text(i));
             }
      }
        
      fillData(PersonNo, 1); 
 
  }
 
//.. 

 function fillData(parPersonNo, parPageNo) 
 { 
    if (parPageNo) 
    {
        $.ajax({
            type: "POST", 
            url: "@Url.Action("GetAddressList", "Address")",
            data: { personNo: parPersonNo, pageNo: parPageNo },
            cache: false,
            dataType: "json",
            success: function (data) 
            {                                  
                if (data.Html) 
                {                       
                    $("#content").html(data.Html);
                    
                    buttonizeALL();
                    setLinkAbilites();
                    
                    setPagingSummary(parPageNo);
                }
                else 
                {
                    alert('opps!'); 
                }
            },
            error: function(exp)        
            {
                     alert('Error address : ' + exp.responseText);
            }                
        }); //end ajax call
    } // if (parPageNo) 

  }//fillData

//...

</script>
Controller'daki action kodu aşağıdaki gibidir. Görüldüğü gibi, sonuç listesi RenderPartialView metodu kullanılarak kısmen render edilir ve JSON nesnesine konulur.
C#
public class AddressController : Controller
{
  //..

  public JsonResult GetAddressList(int personNo, int pageNo)
  {
        
        int pageSize = 5; //it could be parameter
        int skipCnt = ((pageNo - 1) * pageSize);

        List<Address> list = (from x in Repository.GetAddressList() where x.PersonNo == 
          personNo orderby x.AddressNo descending select x).Skip(skipCnt).Take(pageSize).ToList();
       
        JsonResult jr = Json(new
        {
            Html = this.RenderPartialView("AddressList", list),
            Message = "OK"
        }, JsonRequestBehavior.AllowGet);

        return jr;
  }
  //..

}
"PageSelect" id'li combo'nun selecteditem'ı değiştiğinde aşağıdaki jQuery scripti çalışır.
JavaScript
//..

    $("#PageSelect").change(function () 
    {
 
        var $this = $(this);
        var parPageNo = $this.val();
 
        var parPersonNo = $("#paginginfo .pagingPersonNo").text();
 
        fillData(parPersonNo,parPageNo);
                      
    });//PageSelect

//..

4) jQuery kullanarak MVC'de "daha fazla göster" linki nasıl yapılır?

Bu teknik birçok popüler web sitesinde kullanılır. Büyük listelerde uygulanmalıdır. "Daha fazla göster" aşağıdaki gibi gerçekleştirilebilir:
Daha Fazla Göster
Daha Fazla Göster
Liste görünümünde "more" için bir link vardır.
HTML
//
 
<table id="NoteTable"></table>
 
<br />
<a href="#"  style="display:none"  id="more">more</a>
 
<div id="saveDialog" title="Notes Information"></div>
<div id="confirmDialog" title="Warning"></div>
 
//
"more" tıklandığında aşağıdaki jQuery scripti çalışır.
JavaScript
//..

   //load more results
    $(function () 
    {
        $("#more").click(function (e) 
        {
            e.preventDefault();
                       
            var lastNoteNo = $("#NoteTable tr:last .noteNo").text();

            if (lastNoteNo) 
            {
                var PersonNo = $("#paginginfo .pagingPersonNo").text();
                fillData(PersonNo, lastNoteNo); 
            }
 
            //--- scroll to bottom of page ---
            var $target = $('html,body'); 
            $target.animate({scrollTop: $target.height()}, "slow");
            //--- /scroll to bottom of page ---

            return false;
        });
    });
 
//..

 
   function fillData(parPersonNo, parLastNoteNo) 
    {                 
        if (parPersonNo) 
        {
            $.ajax({
                type: "POST",                
                url: "@Url.Action("GetNoteList", "Note")",
                data: { personNo: parPersonNo,  lastNoteNo: parLastNoteNo} ,
                cache: false,
                dataType: "json",
                success: function (data) 
                {
                    if (data.Html) 
                    {
                        $("#NoteTable").append(data.Html);
                        
                        buttonizeALL();
                        setLinkAbilites();
                        
                        if (data.HasMore)
                            $("#more").show();
                        else                        
                            $("#more").hide();
                    }
                    else 
                    {
                        alert('opps!'); 
                    }
                },                
                error: function(exp)        
                {
                        alert('Error address : ' + exp.responseText);
                }                
            }); //end ajax call
        } // if 
    }//func

// ..
Controller'daki aşağıdaki action JSON sonucunu döndürür.
C#
public class NoteController : Controller
{
   //...

    public JsonResult GetNoteList(int personNo,  int lastNoteNo)
    {
        int pageSize = 5; //it could be parameter
        bool hasMore = false;

        List<Note> list = null;

        if (lastNoteNo == 0)
        {            
            list = (from x in Repository.GetNoteList() where x.PersonNo == personNo 
              orderby x.NoteNo descending select x).Take(pageSize).ToList();
            hasMore = (from x in Repository.GetNoteList() where x.PersonNo == 
              personNo select x.NoteNo).Take(pageSize + 1).Count() - pageSize > 0;
        }
        else
        {
            list = (from x in Repository.GetNoteList() where x.NoteNo < lastNoteNo && 
              x.PersonNo == personNo orderby x.NoteNo descending select x).Take(pageSize).ToList();
            hasMore = (from x in Repository.GetNoteList() where x.NoteNo < lastNoteNo && 
              x.PersonNo == personNo select x.NoteNo).Take(pageSize + 1).Count() - pageSize > 0;
        }
        
        JsonResult jr = Json(new
        {
            Html = this.RenderPartialView("_NoteList", list),
            Message = "OK",
            HasMore = hasMore
        }, JsonRequestBehavior.AllowGet);

        return jr;
    }

  // ...
}

5) Link ile özellik (attribute) nasıl kullanılır?

Bu, özellikle edit, delete, show detail gibi butonlar için kullanılması iyi bir yetenektir.
Liste oluşturulurken, ilgili anahtar link'e bir özellik olarak eklenir. Link'in click olayında o anahtar kullanılır ve işlem kolayca yapılır.
Örneğin, bir listenin her satırında delete linki olduğunu varsayın. Satırdaki delete linkine tıklandığında, controller'daki "delete action" için parametere olarak anahtarı kullanmak mümkündür.
HTML
@Html.ActionLink("Delete", "DeletePerson", new { personNo = item.PersonNo }, 
  new { @class = "deleteLink", @pkNo = item.PersonNo })
İstemcide kaynak kontrol edildiğinde aşağıdaki satır görülür.
HTML
<a role="button" class="deleteLink ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" 
  href="/Person/DeletePerson/1" pkno="1"><span class="ui-button-text">Delete</span></a>
jQuery scriptinde özellikler aşağıdaki gibi kullanılır. Örneğin pkno 1'dir ve kullanılır.
JavaScript
$(".deleteLink").live("click", function (e) 
{
      e.preventDefault();
      var pkNo = $(this).attr("pkNo");
      //..
});

6) jQuery'de AJAX çağrısı nasıl yapılır?

AJAX çağrısı, bir uygulamayı daha hızlı yapmak için çok iyi bir yetenektir. Veritabanında büyük miktarda veri olan bazı uygulamalarda, geliştirici iki veri hattında düşük miktarda veri aktarımına dikkat etmelidir. İlk hat veritabanı ile uygulama arasında, ikincisi ise uygulama ile istemci tarayıcısı arasında. Bu tür gereksinimler için AJAX çağrısı çok kullanışlıdır.
JavaScript
//..

  $.ajax({
            type: "POST",
            url: "/Person/DeletePerson", 
            data: { personNo: pkNo },
            cache: false,
            dataType: "json",
            success: function () 
            {
                       //.. 
            },
            error: function (jqXHR, exception) 
            {
                 alert('Uncaught Error.\n' + jqXHR.responseText);
            }
         }); //end ajax call

//..
URL aşağıdaki gibi de kullanılabilir.
JavaScript
//..

url: "@Url.Action("DeletePerson", "Person")",
 
// ..

7) MVC'de Form koleksiyonu nasıl kullanılır?

Bir form post edildiğinde, tüm form elemanları controller'daki ilgili action'a koleksiyon olarak gönderilir. Controller'da her anahtar-değer çifti kullanılabilir. Aşağıdaki gibi bir kaydetme formunuz olduğunu varsayın:
HTML
@model AddressBook_mvc3_jQuery.Models.Address
@{ViewBag.Title = "Address"; }
 
@using (Ajax.BeginForm("Save", "Address", new AjaxOptions
                            {
                                InsertionMode = InsertionMode.Replace,
                                HttpMethod = "POST",
                                OnSuccess = "saveSuccess"
                            }, new { @id = "saveForm" }))
{
    @Html.ValidationSummary(true)
    <input style="visibility:hidden" type="text" name="TBPersonNo" 
      id="idTBPersonNo" value="@Model.PersonNo"/>
    <input style="visibility:hidden" type="text" name="TBAddressNo" 
      id="idTBAddressNo" value="@Model.AddressNo"/>
    
    <br />        
    <fieldset>       
        <table>        
        <tr>
        <td>Address Type</td>
        <td>        
          <select name="CBAddressType" id="idCBAddressType" style="width:120px">
          </select>
        </td>
        </tr>
        <tr>
        <td>Country</td>
        <td>            
            <select name="CBcountry" id="idCBcountry" style="width:120px">
            </select>
        </td>
        </tr>
        <tr>
        <td>City</td>
        <td>            
            <select name="CBcity" id="idCBcity" style="width:120px">
            </select>
        </td>
        </tr>
        <tr>
        <td>AddressText</td>
        <td>        
        <textarea rows="4" cols="25" name="TBAddressText" 
          id="idTBAddressText">@Model.AddressText</textarea>            
        </td>
        </tr>
        </table>        
    </fieldset>
}
Görünümdeki veri, model nesnesi veya aşağıda gösterildiği gibi FormCollection olarak controller'daki action'a gönderilebilir:
C#
//..
 
[HttpPost]
public JsonResult Save(FormCollection fc)
{
    object obj = null;

                
    Address addrTmp = new Address();
    addrTmp.AddressNo = Convert.ToInt32(fc["TBAddressNo"].ToString());
    addrTmp.AddressTypeNo = Convert.ToInt32(fc["CBAddressType"].ToString());
    addrTmp.AddressText = fc["TBAddressText"].ToString();
    addrTmp.CityNo = Convert.ToInt32(fc["CBcity"].ToString()); ;
    addrTmp.PersonNo = Convert.ToInt32(fc["TBPersonNo"].ToString()); 
    
    if (ModelState.IsValid)
    {
        if (addrTmp.AddressNo == 0)
        {
            //find last person 
            //if it is database system no need to this line. Probably the AddressNo would be autoincrement
            addrTmp.AddressNo = Data.Repository.GetAddressList().OrderBy(x => x.AddressNo).Last().AddressNo + 1;

            Data.Repository.GetAddressList().Add(addrTmp);
            

            obj = new { Success = true, 
                        Message = "Added successfully", 
                        Object = addrTmp, 
                        operationType = "INSERT", 
                        Html = this.RenderPartialView("_addressLine", addrTmp )
                      };
        }
        else
        {
            Address addr = Repository.GetAddressList().Where(c => c.AddressNo == addrTmp.AddressNo).FirstOrDefault();
            addr.AddressTypeNo = addrTmp.AddressTypeNo;
            addr.AddressText = addrTmp.AddressText;
            addr.CityNo = addrTmp.CityNo;
            addr.PersonNo = addrTmp.PersonNo;

            obj = new { Success = true, 
                        Message = "Updated successfully", 
                        Object = addr, 
                        operationType = "UPDATE",
                        Html = this.RenderPartialView("_addressLine",  addr )
                      };
        }                

    }
    else
    {
        obj = new { Success = false, Message = "Please check form" };
    }

    return Json(obj, JsonRequestBehavior.DenyGet);
}
 
//..

8) Tek seferde birden fazla kayıt nasıl silinir?

Bazı sayfalarda bazen tek seferde birçok kaydı silmek işi kolaylaştırır. Birden fazla kaydı silmek, seçilen tüm kayıtların anahtarlarını toplayarak mümkündür. Tüm anahtarlar controller'a gönderildikten sonra silme aşağıdaki gibi gerçekleştirilebilir.
Çoklu Silme
Çoklu Silme
Önce "deleteALL" id'li "Delete Selected" butonuna tıklanır. Yes'e bastıktan sonra aşağıdaki jQuery scripti kullanılabilir. Elbette alternatif scriptler de geliştirilebilir.
JavaScript
//..

$("#deleteALL").live("click", function (e) 
{
    e.preventDefault();
    
    var len = $("#NoteTable tr").length;
    
    $("#confirmDialog").html('<br/><br/>deleting all selecteds.. sure?');

    $("#confirmDialog").dialog({
        resizable: false,
        height: 200,
        width: 300,
        modal: true,
        buttons: 
        {
            "Yes": function () 
            {
                $(this).dialog("close");
                
                    var strSelecteds = '';
                    var rows = $("#NoteTable tr");

                    for(var i=0; i< rows.length; i++)
                    {                               
                        var row = $(rows).eq(i);

                        var span = row.find('span#cboxSpan');
                        var cb = row.find('span#cboxSpan').find('input.cboxDELclass');
                        
                        var checked=(cb.is(':checked'));

                        var pkno =  cb.attr("pkno"); 

                        if (checked)
                        {
                            strSelecteds = strSelecteds + pkno + ',';
                        }
                    }//
                            
                    if (strSelecteds.length>0)
                    {
                        strSelecteds = strSelecteds.substring(0,strSelecteds.length-1);
                    }
                    
                    if (strSelecteds.length>0)
                    {
                        $.ajax({
                            type: "POST",
                            url: "/Note/DeleteALL",   
                            data: { noteNOs: strSelecteds },
                            cache: false,
                            dataType: "json",
                            success: function (data) 
                            {
                                var  strSelectedsArr = strSelecteds.split(',');
                                for (var i = 0; i < strSelectedsArr.length; i++) 
                                {
                                    var rowNo = '#row-' + strSelectedsArr[i];
                                    $(rowNo).remove();  
                                    //alert(strSelectedsArr[i]);

                                }//for
                                

                                $('#saveDialog').dialog('close');
                                $('#Message').html(data.Message);
                                $('#Message').delay(300).slideDown(300).delay(1000).slideUp(300);
                            },                          
                            error: function(jqXHR, exception) 
                            {
                                alert('Uncaught Error.\n' + jqXHR.responseText);
                            }

                        }); //end ajax call
                    }
                    else
                        alert('No row selected');

            }, // end of yes button
            "No": function () 
            {
                $(this).dialog("close");
            }
        } //end buttons
    }); //end modal 

});    //end deleteALL
 
//...
Yukarıda görüldüğü gibi, birçok kaydın silinmesi "Note" controller'daki "DeleteALL" action'ına ajax çağrısı ile yapılır.

9) MVC'de Partial Action nasıl kullanılır?

Bazı durumlarda, birçok formda kullanılması gereken bir bileşen gerekir. Örneğin, aşağıda gösterildiği gibi bazı ayrı formlarda bir "kişi bilgi kutusu" gerekebilir.
HTML Action
HTML Action
_personinfo görünümü aşağıdaki gibi olabilir.
HTML
@model AddressBook_mvc3_jQuery.Models.Person
 
@{ ViewBag.Title = "_personinfo"; }
           
<fieldset>
    <legend>Person info</legend>
 
    <table>
<tr><td><b><span> @Model.FirstName @Model.LastName </span></b>(@String.Format("{0:dd.MM.yyyy}", 
  Model.BirthDate))</td><td>(@Model.CategoryName)</td></tr>
    </table>
 
</fieldset>
Herhangi bir görünümde partial action kullanmak için aşağıdaki kod satırı kullanılabilir.
HTML
//..
 
<h2>Address List</h2>
<div> 
    @Html.Action("_personinfo", "Common") 
</div> 
 
//..

10) MVC uygulamasında JSON formatı nasıl kullanılır?

JSON formatı, controller'daki bir action'a parametre gönderirken ve bir action'dan sonuç alırken kullanılabilir. Aşağıda gösterildiği gibi, Note controller'daki DeleteNote action'ı noteNo parametresine sahiptir. Burada pkNo, değer ile çağrılan bir parametredir.
JavaScript
$(".deleteLink").live("click", function (e) 
{
    e.preventDefault();

    var pkNo = $(this).attr("pkNo");

    //..

    $.ajax({
             type: "POST",
             url: "/Note/DeleteNote",
             data: { noteNo: pkNo },
             cache: false,
             dataType: "json",
             success: function () 
             {
               $(rowNo).remove();
             },
             error: function(jqXHR, exception) 
             {
                alert('Uncaught Error.\n' + jqXHR.responseText);
             }
            }); //end ajax call

    //.. 

});    //end delete
Controller'daki action'dan JSON sonucu almak mümkündür. Aşağıdaki script sonucu json nesnesi olarak döndürür.
C#
//..
 
[HttpPost]
public JsonResult DeleteNote(int noteNo)
{

    string message = string.Empty;

    try
    {
        Note n = Data.Repository.GetNoteList().Where(c => c.NoteNo == noteNo).FirstOrDefault();

        if (n != null)
        {
            Data.Repository.GetNoteList().Remove(n);
            message = "Deleted";
        }
        else
        {
            message = "Note not found!";
        }

    }
    catch (Exception ex)
    {
        message = ex.Message;
    }

    return Json(new { Message = message }, JsonRequestBehavior.AllowGet);
}

 
//..

11) Master-detail combobox nasıl doldurulur?

Bazı formlar, bir combobox'ı başka birini değiştirdiğinde doldurmayı gerektirir. Örneğin, bir ülke-şehir çifti için, ülke master ve şehir detail olarak düşünülebilir.
Master-Detail Combobox
Master-Detail Combobox
"Kaydet formunun" görünümündeki html aşağıdaki gibidir.
HTML
@model AddressBook_mvc3_jQuery.Models.Address
@{ViewBag.Title = "Address"; }
 
@using (Ajax.BeginForm("Save", "Address", new AjaxOptions
                            {
                                InsertionMode = InsertionMode.Replace,
                                HttpMethod = "POST",
                                OnSuccess = "saveSuccess"
                            }, new { @id = "saveForm" }))
{
    @Html.ValidationSummary(true)
    <input style="visibility:hidden" type="text" name="TBPersonNo" 
      id="idTBPersonNo" value="@Model.PersonNo"/>
    <input style="visibility:hidden" type="text" name="TBAddressNo" 
      id="idTBAddressNo" value="@Model.AddressNo"/>
    
    <br />        
    <fieldset>       
        <table>        
        <tr>
        <td>Address Type</td>
        <td>        
          <select name="CBAddressType" id="idCBAddressType" style="width:120px">
          </select>
        </td>
        </tr>
        <tr>
        <td>Country</td>
        <td>            
            <select name="CBcountry" id="idCBcountry" style="width:120px">  
            </select>
        </td>
        </tr>
        <tr>
        <td>City</td>
        <td>            
            <select name="CBcity" id="idCBcity" style="width:120px"> 
            </select>
        </td>
        </tr>
        <tr>
        <td>AddressText</td>
        <td>        
        <textarea rows="4" cols="25" name="TBAddressText" 
          id="idTBAddressText">@Model.AddressText</textarea>
        </td>
        </tr>
        </table>        
    </fieldset>
}
İlk yüklemede, idCBCountry combobox'ı Address controller'daki "GetCountryList" action'ı kullanılarak doldurulur. Daha sonra ülke combobox'ı değiştiğinde, şehir combobox'ı aşağıdaki gibi doldurulur.
JavaScript
<script type="text/javascript">
 
    $(document).ready(function () {  
 
    //...
    //-----------------------------------------------------
    
                
   $.ajax({
        type: "POST",
        url: "@Url.Action("GetCountryList", "Address")",
        data: {},
        cache: false,
        dataType: "json",
        success: function (data) 
        {                               
             var idCBcountry = $("#idCBcountry");
             idCBcountry.html("");
                    
              if (@Model.AddressNo>0)
              {
                 for (var i = 0; i < data.List.length; i++) 
                 {
                    var item = data.List[i];

                    if (item.CountryNo == @Model.CountryNo)
                    {                                
                        idCBcountry.append($("<option selected></option>").val(item.CountryNo).text(item.CountryName));
                        fillCity(item.CountryNo);
                    }
                    else
                    {
                        idCBcountry.append($("<option />").val(item.CountryNo).text(item.CountryName));
                    }
                 }  //for   
              }      
              else
              {
                    for (var i = 0; i < data.List.length; i++) 
                     {
                        var item = data.List[i];
                        if (i==0)
                        {
                            idCBcountry.append($("<option selected></option>").val(item.CountryNo).text(item.CountryName));
                            fillCity(item.CountryNo);
                        }
                        else
                        {
                            idCBcountry.append($("<option />").val(item.CountryNo).text(item.CountryName));
                        }
                     }  //for
              }//else
            },  
            error: function(exp)        
            {
                 alert('ErrorCountry : ' + exp.responseText);
            }
        });
 
        //-----------------------------------------------------

            $("#idCBcountry").change(function () {
                var $this = $(this);
                var CountryNo = $this.val();
                if (CountryNo) 
                {
                    fillCity(CountryNo);

                }//if
            });

            //-----------------------------------------------------

});//end of function
 
function fillCity(parCountryNo)
{

    $.ajax({
        type: "POST",
        url: "@Url.Action("GetCityList", "Address")",
        data: {CountryNo: parCountryNo},
        cache: false,
        dataType: "json",
        success: function (data) 
        {
             var idCBcity = $("#idCBcity");
             idCBcity.html("");

             for (var i = 0; i < data.List.length; i++) 
             {
                var item = data.List[i];

                if (item.CityNo == @Model.CityNo)
                {
                    idCBcity.append($("<option selected></option>").val(item.CityNo).text(item.CityName));
                }
                else
                {
                    idCBcity.append($("<option />").val(item.CityNo).text(item.CityName));
                }
             }
        },
        error: function(exp)        
        {
             alert('ErrorCity : ' + exp.responseText);
        }
    });
}//fillCity

</script>
Action kodları aşağıdaki gibidir. Listeler json nesnesine gömülür. Daha sonra, yukarıda gösterilen jQuery scriptinde, liste elemanları index ile kullanılır.
C#
public class AddressController : Controller
{
    //..

    public JsonResult GetCountryList()
    {
        object obj = null;
        List<Country> list = Repository.GetCountryList();
        obj = new { Success = true, Message = "OK", List = list };

        return Json(obj, JsonRequestBehavior.AllowGet);
    }
   
    public JsonResult GetCityList(int CountryNo)
    {
        object obj = null;

        List<City> list = Repository.GetCityList().Where(c => c.CountryNo == CountryNo).ToList(); ;
        obj = new { Success = true, Message = "OK", List = list };

        return Json(obj, JsonRequestBehavior.AllowGet);
    }

   //..
}
Bu teknik, görünüm formundaki herhangi bir html elemanı için kullanılabilir.

12) jQuery datepicker nasıl kullanılır?

Tarih tipi hemen hemen tüm iş uygulamalarında kullanılır. Kültürlerin farklılığı nedeniyle, bazen bu tipi kullanmak geliştirici için sorun anlamına gelir. Ancak jQuery datepicker tarih tipini kullanmayı kolaylaştırır.
jQuery Datepicker
jQuery Datepicker
Listede tarihi istenen formatta göstermek için aşağıdaki satır kullanılabilir.
HTML
<span class="BirthDate"> @String.Format("{0:dd.MM.yyyy}", item.BirthDate) </span>
Kaydetme formunda aşağıdaki html scripti kullanılır.
HTML
  ...
       
    <div class="editor-label">
        @Html.LabelFor(model => model.BirthDate)
    </div>
    <div class="editor-field">         
        @Html.TextBoxFor(model => model.BirthDate, 
                new { @class = "BirthDateSave", 
                      @id = "TBBirthDate",
                      @Value = Model.BirthDate.ToString("dd.MM.yyyy") 
                    })
    </div>

   ...
jQuery Datepicker, aynı sayfada aşağıdaki script ile @Html.TextboxFor ile çalışabilir.
JavaScript
<script language="javascript" type="text/javascript">
 
 $(document).ready(function () {
    $(".BirthDateSave").datepicker({  
             changeMonth: true,
             changeYear: true,  
             dateFormat: 'dd.mm.yy',
             showOn: 'both'
                   });  
                });

</script>
Uygun .cshtml'in başında aşağıdaki satırlar dahil edilmelidir.
HTML
..
  <link href="@Url.Content("~/Content/themes/base/jquery.ui.all.css")" rel="stylesheet" type="text/css" />
  <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>    
  <script src="@Url.Content("~/Scripts/jquery-ui-1.8.11.min.js")" type="text/javascript"></script>
..

13) jQuery dialog ile MVC'de resim nasıl yüklenir?

Bir resim ayrı bir görünümde kolayca yüklenebilir. Ancak sadece bir resim yüklemek için ayrı bir görünüme yönlendirmek ve sonra liste görünümüne yönlendirmek maliyet açısından verimsiz olabilir. Bunun yerine, liste görünümünde, her satırdaki yükleme linkine tıklanarak bir jQuery dialog açılabilir, bir resim gözatılabilir ve yüklenebilir.
Resim Yükleme
Resim Yükleme
"Upload Pic" tıklandığında aşağıdaki script çalışır.
JavaScript
//..

$(".uploadPicLink").click
(
    function () 
    {

        linkObj = $(this);

        var dialogDiv = $('#savePicDialog');
        var viewUrl = linkObj.attr('href');
        $.get(viewUrl, function (data) {
            dialogDiv.html(data);
            //validation
            var $form = $("#savePersonPicForm");
            $form.unbind();
            $form.data("validator", null);
            $.validator.unobtrusive.parse(document);
            $form.validate($form.data("unobtrusiveValidation").options);

            dialogDiv.dialog('open');
        });

        return false;
    }
);

//..
jQuery dialog'a yüklenen SavePersonPic formu aşağıdaki gibidir. jQuery dialog'da dosya yüklemek için iframe kullanılır.
HTML
@model AddressBook_mvc3_jQuery.Models.Person            
@{ViewBag.Title = "Save image";}

@using (Html.BeginForm("SavePersonPic", "Person", FormMethod.Post,
             new
             {
                enctype = "multipart/form-data",        
                id = "savePersonPicForm",
                name = "savePersonPicForm",
                target = "UploadTarget"
              }))        
{
    @Html.ValidationSummary(true)    
    
    <div id="update-message" class="error invisible"></div>    
    <fieldset>
        <legend>Person Picture</legend> 
        <div class="editor-label">
            <label for="file">Upload Image:</label>
        </div>
        <div class="editor-field">
            <input type="file" name="file" id="file"/>        
        </div>      
 
    </fieldset>        
}

<iframe id="UploadTarget" 
   name="UploadTarget" onload="UploadImage_Complete();" 
        style="position: absolute; left: -999em; top: -999em;">
</iframe>
Controller'daki dosya yükleme action'ı aşağıdadır:
C#
public class PersonController : Controller
{
    //..
    //-------------- image -----

    [HttpGet]
    public ActionResult SavePersonPic(int personNo)
    {

        Person person = new Person();
                    
        if (personNo > 0)
        {
            person = Repository.GetPersonList().Where(c => c.PersonNo == personNo).FirstOrDefault();
        }

        return PartialView(person);
    }
 
    [HttpPost]        
    public JsonResult SavePersonPic(HttpPostedFileBase file,   int personNo)
    {                
        string message = string.Empty;
        bool success = false;
        string imgPath = "";
        string fileName = "";
        try
        {
            string path = System.IO.Path.Combine(Server.MapPath("~/Content/images"), 
                            System.IO.Path.GetFileName(file.FileName));
            file.SaveAs(path);

            Person p = Data.Repository.GetPersonList().Where(r => r.PersonNo == personNo).FirstOrDefault();
            p.imgFileName = file.FileName;
            ViewBag.Message = "File uploaded successfully";
            message = ViewBag.Message;

            fileName = file.FileName;
            imgPath = Url.Content(String.Format("~/Content/images/{0}", fileName)); 
            
            success = true;

        }
        catch (Exception ex)
        {
            message = ex.Message;
            success = true;
            imgPath = "";
            fileName = "";
        }
 
        return Json(
                        new { Success = success, 
                              Message = message, 
                              PersonNo=personNo,
                              ImagePath = imgPath,
                              FileName = fileName
                            }, 
                        JsonRequestBehavior.AllowGet
                    );

    }

    //------------- /image --------
    // ..
}
iframe'in JavaScript "onload" fonksiyonu aşağıdadır. Yüklenen resim, satır yenilenmeden listenin ilgili satırında gösterilir.
JavaScript
//..

function UploadImage_Complete() 
{            
    //Check first load of the iFrame
    if (isFirstLoad == true) 
    {
        isFirstLoad = false;
        return;
    }

    try 
    {            
        //Reset the image form
        document.getElementById("savePersonPicForm").reset();
    
        var jsonTxt = ($('#UploadTarget').contents()).text();            
        var jsonObj = JSON.parse(jsonTxt);
        
        var rowid = '#row-' + jsonObj.PersonNo;            
        var row = $('#personTable ' + rowid);           
        var imgid = "#img-" + jsonObj.PersonNo;
        var img = row.find(imgid);
            $(img).attr("src", jsonObj.ImagePath);

       
        $('#Message').html(jsonObj.Message);
        $('#Message').delay(300).slideDown(300).delay(1000).slideUp(300)


        $('#savePicDialog').dialog('close');
    }
    catch (err) 
    {
        alert(err.get_Message());
    }
}
 
//..

14) İstemci tarafında tablo satırı nasıl oluşturulur?

Veritabanına eklenen bir kayıt, istemci tarafında listede gösterilmelidir. Bu birçok şekilde yapılabilir. Bir kayıt eklendikten sonra, liste veritabanından tamamen yenilenebilir ancak bu ağır bir işlem olur. Ancak, javascript veya jquery kullanarak, görünümdeki tüm elemanlar yenilenmeden görünüme yeni bir satır eklenebilir. Burada iki yol bahsedilir.
Birincisi, aşağıda satır ve satırın hücreleri javascript ile tek tek oluşturulur. Aşağıdaki scriptlerde görüldüğü gibi, bu formun submit'inden sonra saveSuccess JavaScript fonksiyonu böyle bir senaryo için kullanılır.
HTML
..
 
@model AddressBook_mvc3_jQuery.Models.Person
            
@{  ViewBag.Title = "Save Person"; }
 
..
 
@using (Ajax.BeginForm("Save", "Person", new AjaxOptions
{
    InsertionMode = InsertionMode.Replace,
    HttpMethod = "POST",
    OnSuccess = "saveSuccess"    
}, new { @id = "savePersonForm" }))
{
    @Html.ValidationSummary(true)    
    
    ..        
}
 
..
saveSuccess javascript metodu aşağıdaki gibidir. Action, işlem tipini içeren bir json sonucu döndürür. İşleme göre, yani INSERT veya UPDATE, görünümdeki tablo değiştirilir. Veritabanına yeni bir kayıt eklendiğinde, tabloya yeni bir satır eklenir (prepend). Veritabanındaki mevcut bir kayıt güncellendiğinde, tablodaki sadece ilgili satır değiştirilir.
JavaScript
function saveSuccess(data) 
{
    if (data.Success == true) 
    {
        if (data.operationType == 'UPDATE') 
        {
            //we update the table's row info
            var parent = linkObj.closest("tr");
            
            $(parent).animate({ opacity: 0.3 }, 200, function () 
            {;});

            parent.find(".FirstName").html(data.Object.FirstName);
            parent.find(".LastName").html(data.Object.LastName);
            parent.find(".CategoryName").html(data.Object.CategoryName);

            var date = new Date(parseInt(data.Object.BirthDate.substr(6)));
            var dateStr = FormatDate(date);                                     
            parent.find(".BirthDate").html(dateStr);


            $(parent).animate({ opacity: 1.0 }, 200, function () {
                ;
            });

        }
        else 
        {  //INSERT

            //we add the new row to table
            //we do not refresh all records on screen
            
            try 
            {                    
                var personTable = document.getElementById("personTable");
                var row = personTable.insertRow(1); //row 0 is header
                row.setAttribute("id", 'row-' + data.Object.PersonNo.toString());
                                                                 
                var buttonsLinks =
                '<a role="button" class="editLink ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only ui-state-hover ui-state-focus" href="/Person/Save/' + data.Object.PersonNo.toString() + '"><span class="ui-button-text">Edit</span></a> ' +
                '<a role="button" class="adressLink ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" href="/Address/Index/' + data.Object.PersonNo.toString()  + '"><span class="ui-button-text">Addresses</span></a> ' +
                '<a role="button" class="noteLink ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" href="/Note/Index/' + data.Object.PersonNo.toString() + '"><span class="ui-button-text">Notes</span></a> ' +
                '<a role="button" class="deleteLink ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" href="/Person/Delete/' + data.Object.PersonNo.toString() + '" pkno="' + data.Object.PersonNo.toString()  + '"><span class="ui-button-text">Delete</span></a>';

        
                var cellButtons = row.insertCell(0);
                cellButtons.innerHTML = buttonsLinks;

                var cellPersonNo = row.insertCell(1);
                cellPersonNo.innerHTML = "<span  class=\"PersonNo\">" + data.Object.PersonNo + "</span>";


                var cellCategoryName = row.insertCell(2);
                cellCategoryName.innerHTML = "<span  class=\"CategoryName\">" + data.Object.CategoryName + "</span>";

                var cellFN = row.insertCell(3);
                cellFN.innerHTML = "<span  class=\"FirstName\">" + data.Object.FirstName + "</span>";
                
                var cellLN= row.insertCell(4);
                cellLN.innerHTML = "<span  class=\"LastName\">" + data.Object.LastName + "</span>";

                var cellBirthDate = row.insertCell(5);
                var date = new Date(parseInt(data.Object.BirthDate.substr(6)));
                var dateStr = FormatDate(date);
                cellBirthDate.innerHTML = "<span  class=\"BirthDate\">" + dateStr + "</span>";

                var cellimgFileName = row.insertCell(6);
                cellimgFileName.innerHTML =
                    "<img id=\"img-" + data.Object.PersonNo.toString() + "\" alt=\"" + data.Object.ImgFileName + "\" src=\"/content/images/" + "noimg.jpg" + "\" height=\"35px\" width=\"50px\"><br><a class=\"uploadPicLink\" href=\"/Person/SavePersonPic/" + data.Object.PersonNo.toString() + "\" pkno=\"" + data.Object.PersonNo.toString() + "\" style=\"font-size:9px;\">Upload Pic</a>";

                
                setLinks();
                                 
            }
            catch (err) {
                alert(err.Message);
            }                               
        }
        
        $('#saveDialog').dialog('close');
        $('#Message').html(data.Message);
        $('#Message').delay(300).slideDown(300).delay(1000).slideUp(300);

    }
    else {
        $("#update-message").html(data.ErrorMessage);
        $("#update-message").show();
    }
}
Yukarıda bahsedilen birinci yol eski bir yaklaşım gibi görünebilir. Bu nedenle, aşağıdaki ikinci yol daha uygulanabilir olabilir. Bu yolda, tabloya satır eklemek veya güncellemek için render edilmiş html kullanılır. Aşağıdaki gibi bir tablo olduğunu varsayın.
HTML
@model IEnumerable<AddressBook_mvc3_jQuery.Models.Address>

<table id="AddressTable">
    <tr>
        <th></th>
        <th>
            #
        </th>       
        <th>
            AddressType
        </th>
        <th>
            City/Country
        </th>
        <th>
            Address Text
        </th>        
    </tr>
 
@foreach (var item in Model) 
{
    <tr id="row-@item.AddressNo">
        <td>            
            @Html.ActionLink("Edit", "Save", 
              new { addressNo = item.AddressNo, personNo = item.PersonNo }, new { @class = "editLink" })
            @Html.ActionLink("Delete", "DeleteAddress", 
              new { addressNo = item.AddressNo }, new { @class = "deleteLink", @pkNo = item.AddressNo })
        </td>
        <td>            
            <span class="AddressNo">@item.AddressNo</span>
        </td>       
        <td>            
            <span class="AddressTypeName">@item.AddressTypeName</span>
        </td>
        <td>            
            <span class="CityName">@item.CityName/@item.CountryName</span>
        </td>
        <td>            
            <span class="AddressText">@item.AddressText</span>
        </td>       
    </tr>
}
 
</table>
"new" tıklandığında aşağıdaki script jQuery dialog'a yüklenir.
HTML
@model AddressBook_mvc3_jQuery.Models.Address
@{ViewBag.Title = "Address"; }
 
@using (Ajax.BeginForm("Save", "Address", new AjaxOptions
                            {
                                InsertionMode = InsertionMode.Replace,
                                HttpMethod = "POST",
                                OnSuccess = "saveSuccess"
                            }, new { @id = "saveForm" }))
{
    @Html.ValidationSummary(true)
    <input style="visibility:hidden" type="text" 
      name="TBPersonNo" id="idTBPersonNo" value="@Model.PersonNo"/>
    <input style="visibility:hidden" type="text" 
      name="TBAddressNo" id="idTBAddressNo" value="@Model.AddressNo"/>
    
    <br />        
    <fieldset>       
        <table>        
        <tr>
        <td>Address Type</td>
        <td>        
          <select name="CBAddressType" id="idCBAddressType" style="width:120px">
          </select>
        </td>
        </tr>
        <tr>
        <td>Country</td>
        <td>            
            <select name="CBcountry" id="idCBcountry" style="width:120px">
            </select>
        </td>
        </tr>
        <tr>
        <td>City</td>
        <td>            
            <select name="CBcity" id="idCBcity" style="width:120px">
            </select>
        </td>
        </tr>
        <tr>
        <td>AddressText</td>
        <td>        
        <textarea rows="4" cols="25" name="TBAddressText" 
              id="idTBAddressText">@Model.AddressText</textarea>
        </td>
        </tr>
        </table>        
    </fieldset>
}
Form gönderildiğinde, controller'daki aşağıdaki action çalışır.
C#
public class AddressController : Controller
{

    //..

    [HttpPost]
    public JsonResult Save(FormCollection fc)
    {
        object obj = null;

        Address addrTmp = new Address();
        addrTmp.AddressNo = Convert.ToInt32(fc["TBAddressNo"].ToString());
        addrTmp.AddressTypeNo = Convert.ToInt32(fc["CBAddressType"].ToString());
        addrTmp.AddressText = fc["TBAddressText"].ToString();
        addrTmp.CityNo = Convert.ToInt32(fc["CBcity"].ToString()); ;
        addrTmp.PersonNo = Convert.ToInt32(fc["TBPersonNo"].ToString()); 
        
        if (ModelState.IsValid)
        {
            if (addrTmp.AddressNo == 0)
            {
                //find last person 
                //if it is database system no need to this line. Probably the AddressNo would be autoincrement
                addrTmp.AddressNo = Data.Repository.GetAddressList().OrderBy(x => x.AddressNo).Last().AddressNo + 1;

                Data.Repository.GetAddressList().Add(addrTmp);

                obj = new { Success = true, 
                            Message = "Added successfully", 
                            Object = addrTmp, 
                            operationType = "INSERT", 
                                Html = this.RenderPartialView("_addressLine", addrTmp )
                          };
            }
            else
            {
                Address addr = Repository.GetAddressList().Where(c => c.AddressNo == addrTmp.AddressNo).FirstOrDefault();
                addr.AddressTypeNo = addrTmp.AddressTypeNo;
                addr.AddressText = addrTmp.AddressText;
                addr.CityNo = addrTmp.CityNo;
                addr.PersonNo = addrTmp.PersonNo;

                obj = new { Success = true, 
                            Message = "Updated successfully", 
                            Object = addr, 
                            operationType = "UPDATE", 
                                Html = this.RenderPartialView("_addressLine",  addr )
                          };
            }                

        }
        else
        {
            obj = new { Success = false, Message = "Please check form" };
        }

        return Json(obj, JsonRequestBehavior.DenyGet);
    }

    // .. 

}
İstenen html scripti almak için RenderPartialView metodu kullanılır.
C#
//..

public static string RenderPartialView(this Controller controller, string viewName, object model)
{
    if (string.IsNullOrEmpty(viewName))
        viewName = controller.ControllerContext.RouteData.GetRequiredString("action");

    controller.ViewData.Model = model;
    using (var sw = new StringWriter())
    {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
        var viewContext = new ViewContext(controller.ControllerContext, 
               viewResult.View, controller.ViewData, controller.TempData, sw);
        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}

//..
saveAddress formundaki ajax post'un saveSuccess fonksiyonu aşağıdaki gibidir:
JavaScript
<script type="text/javascript">
 
    //...

    function saveSuccess(data) 
    {
        if (data.Success == true) 
        {            
            $("#paginginfo").show();       
 
            if (data.operationType == 'UPDATE') 
            {                           
                var row = linkObj.closest("tr");
                
                // the following line can also be used  to get related row
                //$('#AddressTable #row-' + data.Object.AddressNo); 

                row.replaceWith(data.Html);  
                //..
            }
            else 
            {  //INSERT

                try 
                {                                
                      $("#AddressTable tr:first").after(data.Html);
 
                     //..

                }
                catch (err) 
                {
                       alert(err.Message);
                }
            }
            
            //..

        }
        else 
        {
           //..
        }
    }
 
    //..
    
</script>
Yukarıda açıklanan iki teknikten herhangi biri kullanılabilir.

15) Global.asax'ta mapRoute nasıl özelleştirilir?

Klasik asp.net uygulamasında, urlRewrite işlemleri bazı üçüncü parti assembly'ler ile kolayca gerçekleştirilirdi. MVC uygulamasında, Global.asax kullanarak mapRoute'ları özelleştirmek mümkündür.
Aşağıdaki mapRoute Global.asax'ta varsayılandır:
C#
public class MvcApplication : System.Web.HttpApplication
{

    //..

    public static void RegisterRoutes(RouteCollection routes)
    {

       // all new customized maproute rules can be put here
        

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
        );

    }

    //  .. 
}
Aşağıdaki script'e göre **/Save/{addressNo}/{personNo}** link olarak kullanılır.
HTML
@Html.ActionLink("Edit", "Save", 
  new { addressNo = item.AddressNo, personNo = item.PersonNo }, new { @class = "editLink" })
Yukarıdaki linkin ekran görüntüsü aşağıdadır.
MapRoute
MapRoute
Bu nedenle, Global.asax'a aşağıdaki gibi özelleştirilmiş bir mapRoute kuralı eklemek mümkündür.
C#
//..
 
routes.MapRoute(
    "AddressSave",
    "Address/Save/{addressNo}/{personNo}",
    new { controller = "Address", action = "Save", 
         addressNo = UrlParameter.Optional, personNo = UrlParameter.Optional }
);
 
//.. 
Yukarıda açıklanan iki teknikten herhangi biri kullanılabilir.

16) Tablonun tüm satırları nasıl checkALL ve uncheckALL yapılır?

Birçok uygulamada, bir tablodaki tüm check'lerin tek seferde işaretlenmesi veya işaretinin kaldırılması istenebilir.
Check/Uncheck ALL
Check/Uncheck ALL
Bu tür bir fonksiyon için aşağıdaki script kullanılabilir.
HTML
..

<br />
| <a href="#" class="checkALLRecords" id="checkALL">Check ALL</a> | <a href="#" class="unCheckALLRecords" id="unCheckALL">Uncheck ALL</a> |
<br />

..

<table id="NoteTable"></table>
..  
JavaScript
//..
 

        //check ALL records
        $("#checkALL").live("click", function (e) 
        {
                e.preventDefault();                                           
                CheckALL(true);
        });    
   
        //uncheck ALL records
        $("#unCheckALL").live("click", function (e) 
        {
                e.preventDefault();                                           
                CheckALL(false);
        });   


//..  

    function CheckALL(state)
    {
                            var rows = $("#NoteTable tr");
                                                       

                            for(var i=0; i< rows.length; i++)
                            {                               
                                var row = $(rows).eq(i);
                                                                                                                               
                                var span = row.find('span#cboxSpan');
                                var cb = row.find('span#cboxSpan').find('input.cboxDELclass');
                                
                                if (state==true)                                                                                                    
                                    cb.attr('checked',true);
                                else                                    
                                    cb.attr('checked',false);
                            }                           
    }



//..  

17) "Loading Data" nasıl yapılır?

Birden fazla veri satırı yüklenirken "loading data" mesajı kullanıcılara gösterilmelidir.
Loading Data
Loading Data
Aşağıdaki div gerekli mesaja göre özelleştirilebilir.
HTML
..
<div id="loadMessage"></div>
..   
Div alanını özelleştirmek için aşağıdaki javascript fonksiyonu kullanılabilir.
JavaScript
..

function showLoader(root, txt) {
       
    $("#loadMessage").html("");
    $("#loadMessage").show();
    var loader = '<img src="' + root + '/ajax-loader.gif" align="absmiddle">&amp;nbsp;<span><br/>' + txt + '...</span>';
    $("#loadMessage").fadeIn(100).html(loader);
}

function hideLoader() {
    $("#loadMessage").hide();
}

..   

18) jQuery ile master-detail grid'ler nasıl yapılır?

Master satıra tıklandığında, detail satırlar aşağıda gösterildiği gibi master grid'in altında gösterilir.
Master-Detail Grids
Master-Detail Grids
Grid'ler olarak aşağıdaki tablolar kullanılır.
HTML
..
<table id="CountryTable" class="hovertable2"></table>
<br />
<br />

<table id="CityTable" class="hovertable"></table>
..    
Master-detail yaklaşımını simüle etmek için aşağıdaki javascript fonksiyonları kullanılır.
JavaScript
..

 function setTableRowClick()
   {        

        $("#CountryTable tr  td.clickable").unbind('click');
        
        $('#CountryTable  tr  td.clickable').click(function ()         
        {           
             var row = $(this).parent();             
             setRow(row);

        });

        //-------------        




   }//func 


   function setRow(row)
   {   
              var rowid = row.attr('id'); //current
                            
              var higlightedCountryTableRowid = $("#pageinfo .higlightedCountryTableRowid").text();               

               $("#pageinfo .higlightedCountryTableRowid").html(rowid.toString());

              if ((rowid==0) || (rowid!=higlightedCountryTableRowid))
              {
                  //------
                    row.siblings().removeClass('diffColor');                                              
                    row.addClass("diffColor");
                  //-------

                 fillCityData(rowid);
             }

   }


..   

    function fillCountryData() 
    {                         
            $.ajax({
                type: "POST",                
                url: "@Url.Action("GetCountryList", "Country")",
                data: {},
                cache: false,
                dataType: "json",
                success: function (data) 
                {                                  
                    if (data.Html) 
                    {                                        
                        $("#CountryTable").html(data.Html); 
                        
                        buttonizeALL();
                        
                        setLinkAbilitesCountry();  
                        setLinkAbilitesCity();

                                              
                        setTableRowClick();

                    }
                    else 
                    {
                        alert('opps-- country list error!'); 
                    }
                },                
                error: function(exp)        
                {
                         alert('Error address : ' + exp.responseText);
                }                
            }); //end ajax call
     

    }//func


    function fillCityData(parCountryNo) 
    {                         
            $.ajax({
                type: "POST",                
                url: "@Url.Action("GetCityList", "Country")",
                data: { countryNo: parCountryNo},                
                cache: false,
                dataType: "json",
                success: function (data) 
                {                                  
                    if (data.Html) 
                    {                                       
                        $("#CityTable").html(data.Html);        

                        
                        buttonizeALL();
                        setLinkAbilitesCity();                        
                        setTableRowClick();

                    }
                    else 
                    {
                        alert('opps-- city list error!'); 
                    }
                },                
                error: function(exp)        
                {
                         alert('Error address : ' + exp.responseText);
                }                
            }); //end ajax call
     

    }//func

.. 

Sonuç

Umarım faydalı bir makale olmuştur.

Bulut Bilişim Hizmetleri

AWS, Azure ve Google Cloud platformlarında altyapı tasarımı, migrasyon, yönetim ve optimizasyon hizmetleri sunuyoruz.

Hizmetimizi İncele

Bizimle İletişime Geçin

AWS ve bulut bilişim çözümlerimiz hakkında detaylı bilgi almak için ekibimizle görüşün.

İletişim