Webentwicklung
31 Min. Lesezeit

How-To-Serie über MVC, jQuery, JSON, Paginierung und mapRoute

Techniken und praktische Lösungen für die Entwicklung hochperformanter Webanwendungen mit ASP.NET MVC, jQuery und JSON.

N
Necmettin Demir
21. Juli 2023
Wird geladen...

How-To-Serie über MVC, jQuery, JSON, Paginierung und mapRoute

MVC, jQuery, JSON, Paginierung
MVC, jQuery, JSON, Paginierung

Quellcode herunterladen


Einführung

Aufgrund der großen Datenmengen in Datenbanksystemen ist clientseitige Arbeit sehr wichtig geworden. Im klassischen ASP.NET Code-Behind-Ansatz ist die natürliche Methode, die meiste Arbeit in Code-Behind-Dateien mit ASP.NET-Komponenten zu codieren. Darüber hinaus werden das Rendering von ASP.NET-Komponenten und der ViewState-Mechanismus jetzt als schwache Fähigkeiten des klassischen ASP.NET angesehen.
Daher ist ein neues Paradigma entstanden. Nach diesem neuen Paradigma kann der Entwickler mit reinem HTML und JavaScript arbeiten, ohne ViewState, das die Performance beeinträchtigt, und mit weniger Rendering.
Obwohl MVC als altes Design- oder Architekturmuster bekannt ist, wurde es besonders nach den oben erwähnten klassischen ASP.NET-Engpässen populär. In MVC, wo jQuery und JSON effektiv verwendet werden, können hochperformante Anwendungen entwickelt werden.

Hintergrundinformationen

Dieser Artikel kann nach dem Lesen einiger Einsteiger-Artikel über MVC, jQuery und JSON nützlich sein. Die folgenden Links können für Anfänger hilfreich sein:

Verwendung des Codes

In diesem Artikel wird eine "How-To-Serie" angestrebt. Daher werden alle Skripte aus dem beigefügten Quellcode bereitgestellt. Eigentlich könnte jedes "How-To" ein separater Artikel sein. Jedenfalls sind alle möglichen Antworten in einem einzigen Beispiel zusammengefasst. In diesem Artikel gibt es mehr praktische Ansätze als theoretisches Wissen. Der Einfachheit halber werden anstelle einer Datenbank einige statische Listen verwendet.
Die folgenden Fragen werden beantwortet:
  1. Wie macht man CRUD in MVC mit guter Performance?
  2. Wie verwendet man jQuery-Dialog anstelle von JavaScript confirm oder alert?
  3. Wie macht man Paginierung in einer MVC-Liste?
  4. Wie macht man einen "mehr anzeigen"-Link in MVC mit jQuery?
  5. Wie verwendet man Attribute mit Links?
  6. Wie macht man einen AJAX-Aufruf in jQuery?
  7. Wie verwendet man FormCollection in MVC?
  8. Wie löscht man mehrere Datensätze auf einmal?
  9. Wie verwendet man Partial Action in MVC?
  10. Wie verwendet man das JSON-Format in einer MVC-Anwendung?
  11. Wie füllt man Master-Detail-Comboboxen?
  12. Wie verwendet man den jQuery Datepicker?
  13. Wie lädt man ein Bild in MVC mit jQuery-Dialog hoch?
  14. Wie erstellt man eine Tabellenzeile auf der Client-Seite?
  15. Wie passt man mapRoute in Global.asax an?
  16. Wie macht man checkALL und uncheckALL für alle Zeilen einer Tabelle?
  17. Wie macht man "Loading Data"?
  18. Wie macht man Master-Detail-Grids mit jQuery?

1) Wie macht man CRUD in MVC mit guter Performance?

Grob betrachtet haben alle Geschäftslösungen die Create-Read-Update-Delete (Erstellen-Lesen-Aktualisieren-Löschen) Funktion. Wenn möglich, kann die Verwendung desselben "Speicherformulars" sowohl für "insert" als auch für "update" aus Entwicklersicht kosteneffektiv sein. Die Verwendung desselben Formulars ist durch die Verwaltung der an die Action gesendeten Parameter möglich.
Angenommen, Sie haben eine grid-ähnliche Liste (eigentlich eine HTML-Tabelle) im Formular und einen separaten "New"-Button. Jede Zeile der Tabelle hat einen "Edit"- und "Delete"-Button für diese Zeile.
Nach dem Klicken auf "New" ist es nicht effizient, auf eine neue Seite - hier View genannt - weiterzuleiten. Denn nach dem Speichern der Daten auf der weitergeleiteten Seite muss der Benutzer auf "Liste anzeigen" klicken, um die zur Datenbank hinzugefügten Daten zu sehen. Das bedeutet Weiterleitung zur Listenansicht und Datenauswahl aus der Datenbank mit variablen Auswahlkosten!
Anstelle des oben beschriebenen "klicke auf New und liste erneut"-Szenarios kann ein besserer Weg implementiert werden.
Create (Erstellen):
  • In der Listenansicht kann nach dem Klicken auf "New" ein "jQuery Save Dialog" erscheinen.
  • Die Create-View wird in den jQuery-Dialog gerendert.
  • Das Create-Formular wird ausgefüllt und "Save" wird gedrückt.
  • Beim Drücken des Save-Buttons können die Daten per AJAX-Post an den entsprechenden Controller gesendet werden.
  • Das Ajax-Formular hat eine onSuccess JavaScript-Funktion.
  • In der "onSuccess" JavaScript-Methode wird die hinzugefügte neue Zeile, als JSON als Parameter an "onSuccess" kommend, am Anfang der Liste eingefügt (prepend), ohne die gesamte Liste zu aktualisieren.
Read (Lesen):
Dies ist ein Listenvorgang. Wenn möglich, sollten nur die notwendigen Daten im Listenformular angezeigt werden. Die folgenden Techniken können verwendet werden:
  • Paginierung mit Combobox oder Zahlen,
  • "mehr anzeigen"-Implementierung,
  • Auflistung mit Filterung.
Update (Aktualisieren):
  • In der Listenansicht kann nach dem Klicken auf "Edit" in einer beliebigen Zeile der Liste derselbe "jQuery Save Dialog" mit den Daten der ausgewählten Zeile erscheinen.
  • Da alle Schritte die gleichen wie bei "Create" sind, wird nur die "onSuccess"-Methode entsprechend dem "update"-Vorgang geändert.
  • In diesem Fall werden nach dem Datenbank-Update nur die Daten in der bearbeiteten Zeile in der Ansicht aktualisiert. Auf diese Weise muss die gesamte Liste nicht aktualisiert werden, um den zuletzt bearbeiteten Datensatz zu sehen.
Delete (Löschen):
  • Nach der Bestätigung mit einem schön aussehenden jQuery-Dialog wird nach dem Datenbank-Löschvorgang nur die ausgewählte Zeile aus der Liste entfernt. Auch hier muss die gesamte Liste nicht aktualisiert werden.
Für sowohl Insert als auch Edit wird derselbe Dialog verwendet.
Neuer Datensatz
Neuer Datensatz
Die Links in der PersonList.cshtml-Ansicht sind wie folgt:
HTML
@Html.ActionLink("New", "Save", 
  new { personNo = 0 }, new { @class = "newLink" })
 
...
 
@Html.ActionLink("Edit", "Save", new { personNo = item.PersonNo }, new { @class = "editLink" })
  • New: Der anzuzeigende Text.
  • Save: Die Action im Controller.
  • personNo: Der an die "Save"-Action gesendete Parameter. Wenn 0, öffnet sich der Dialog leer, wenn größer als 0, werden die Daten dieser ID im Dialog angezeigt.
  • newLink: Der fiktive className, der im folgenden jQuery verwendet wird.
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>
Die Save-Action im PersonController ist wie folgt:
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) Wie verwendet man jQuery-Dialog anstelle von JavaScript confirm oder alert?

Angepasste Nachrichtenboxen sind in Windows-Anwendungen möglich. Für das Web ist es bei Verwendung einer Drittanbieter-Komponentenbibliothek möglich. Es ist auch möglich, jQuery-Dialog anstelle von JavaScript-Boxen wie folgt zu verwenden:
Löschbestätigung
Löschbestätigung
Der Delete-Link in der PersonList-Ansicht ist wie folgt:
HTML
@Html.ActionLink("Delete", "DeletePerson", new { personNo = 
item.PersonNo }, new { @class = "deleteLink", @pkNo = item.PersonNo })
Der HTML- und jQuery-Code ist wie folgt:
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) Wie macht man Paginierung in einer MVC-Liste?

Paginierung ist einer der guten Ansätze zur Auflistung von Daten und zur Minimierung der Datenübertragungskosten. Es können viele Möglichkeiten zur Datenanzeige implementiert werden. In diesem "How-To" wurde eine Combobox für die Paginierung verwendet. Bei Bedarf ist jedoch auch eine Nummerierung am Ende der Seite möglich. Dies hängt von der Anwendung und dem Entwickler ab. Paginierung mit Combobox kann wie folgt entwickelt werden.
Paginierung
Paginierung
Zunächst wird der Platz für Paginierungs-Metadaten wie folgt eingerichtet:
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>
 
...
Beim ersten Laden der Seite wird das div mit der ID "paginginfo" gefüllt und die erste Seite der Datensätze wird mit den folgenden Skripten angezeigt.
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>
Der Action-Code im Controller ist wie folgt. Wie zu sehen ist, wird die Ergebnisliste mit der RenderPartialView-Methode teilweise gerendert und in das JSON-Objekt eingefügt.
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;
  }
  //..

}
Wenn das selecteditem der Combo mit der ID "PageSelect" geändert wird, wird das folgende jQuery-Skript ausgeführt.
JavaScript
//..

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

//..

4) Wie macht man einen "mehr anzeigen"-Link in MVC mit jQuery?

Diese Technik wird auf vielen beliebten Websites verwendet. Sie sollte bei großen Listen angewendet werden. "Mehr anzeigen" kann wie folgt realisiert werden:
Mehr anzeigen
Mehr anzeigen
In der Listenansicht gibt es einen Link für "more".
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>
 
//
Wenn auf "more" geklickt wird, wird das folgende jQuery-Skript ausgeführt.
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

// ..
Die folgende Action im Controller gibt das JSON-Ergebnis zurück.
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) Wie verwendet man Attribute mit Links?

Dies ist besonders für Buttons wie Edit, Delete, Show Detail eine gute Fähigkeit.
Beim Erstellen der Liste wird der entsprechende Schlüssel dem Link als Attribut hinzugefügt. Im Click-Event des Links wird dieser Schlüssel verwendet und die Operation kann leicht durchgeführt werden.
Angenommen, jede Zeile einer Liste hat einen Delete-Link. Wenn auf den Delete-Link in der Zeile geklickt wird, ist es möglich, den Schlüssel als Parameter für die "delete action" im Controller zu verwenden.
HTML
@Html.ActionLink("Delete", "DeletePerson", new { personNo = item.PersonNo }, 
  new { @class = "deleteLink", @pkNo = item.PersonNo })
Wenn die Quelle auf dem Client überprüft wird, ist die folgende Zeile zu sehen.
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>
Im jQuery-Skript werden Attribute wie folgt verwendet. Zum Beispiel ist pkno 1 und wird verwendet.
JavaScript
$(".deleteLink").live("click", function (e) 
{
      e.preventDefault();
      var pkNo = $(this).attr("pkNo");
      //..
});

6) Wie macht man einen AJAX-Aufruf in jQuery?

Ein AJAX-Aufruf ist eine sehr gute Fähigkeit, um eine Anwendung schneller zu machen. In einigen Anwendungen mit großen Datenmengen in der Datenbank sollte der Entwickler auf geringe Datenübertragung in zwei Datenleitungen achten. Die erste Leitung ist zwischen Datenbank und Anwendung, die zweite zwischen Anwendung und Client-Browser. Für solche Anforderungen ist der AJAX-Aufruf sehr nützlich.
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

//..
Die URL kann auch wie folgt verwendet werden.
JavaScript
//..

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

7) Wie verwendet man FormCollection in MVC?

Wenn ein Formular gepostet wird, werden alle Formularelemente als Sammlung an die entsprechende Action im Controller gesendet. Im Controller kann jedes Schlüssel-Wert-Paar verwendet werden. Angenommen, Sie haben ein Speicherformular wie folgt:
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>
}
Die Daten in der Ansicht können als Model-Objekt oder als FormCollection wie unten gezeigt an die Action im Controller gesendet werden:
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) Wie löscht man mehrere Datensätze auf einmal?

Auf einigen Seiten erleichtert das Löschen vieler Datensätze auf einmal manchmal die Arbeit. Das Löschen mehrerer Datensätze ist möglich, indem die Schlüssel aller ausgewählten Datensätze gesammelt werden. Nachdem alle Schlüssel an den Controller gesendet wurden, kann das Löschen wie folgt durchgeführt werden.
Mehrfachlöschung
Mehrfachlöschung
Zuerst wird auf den Button "Delete Selected" mit der ID "deleteALL" geklickt. Nach dem Drücken von Yes kann das folgende jQuery-Skript verwendet werden. Natürlich können auch alternative Skripte entwickelt werden.
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
 
//...
Wie oben zu sehen ist, wird das Löschen mehrerer Datensätze durch einen Ajax-Aufruf an die "DeleteALL"-Action im "Note"-Controller durchgeführt.

9) Wie verwendet man Partial Action in MVC?

In einigen Fällen wird eine Komponente benötigt, die in vielen Formularen verwendet werden soll. Zum Beispiel kann in einigen separaten Formularen eine "Personen-Infobox" wie unten gezeigt erforderlich sein.
HTML Action
HTML Action
Die _personinfo-Ansicht kann wie folgt sein.
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>
Um Partial Action in einer beliebigen Ansicht zu verwenden, kann die folgende Codezeile verwendet werden.
HTML
//..
 
<h2>Address List</h2>
<div> 
    @Html.Action("_personinfo", "Common") 
</div> 
 
//..

10) Wie verwendet man das JSON-Format in einer MVC-Anwendung?

Das JSON-Format kann verwendet werden, wenn Parameter an eine Action im Controller gesendet und Ergebnisse von einer Action empfangen werden. Wie unten gezeigt, hat die DeleteNote-Action im Note-Controller den Parameter noteNo. Hier ist pkNo ein Parameter, der mit Wert aufgerufen wird.
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
Es ist möglich, ein JSON-Ergebnis von der Action im Controller zu erhalten. Das folgende Skript gibt das Ergebnis als JSON-Objekt zurück.
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) Wie füllt man Master-Detail-Comboboxen?

Einige Formulare erfordern das Befüllen einer Combobox, wenn eine andere geändert wird. Zum Beispiel kann für ein Land-Stadt-Paar das Land als Master und die Stadt als Detail betrachtet werden.
Master-Detail Combobox
Master-Detail Combobox
Das HTML im "Speicherformular"-View ist wie folgt.
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>
}
Beim ersten Laden wird die idCBCountry-Combobox mit der "GetCountryList"-Action im Address-Controller gefüllt. Später, wenn die Länder-Combobox geändert wird, wird die Stadt-Combobox wie folgt gefüllt.
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>
Die Action-Codes sind wie folgt. Die Listen werden in das JSON-Objekt eingebettet. Später werden die Listenelemente im oben gezeigten jQuery-Skript mit Index verwendet.
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);
    }

   //..
}
Diese Technik kann für jedes HTML-Element im Ansichtsformular verwendet werden.

12) Wie verwendet man den jQuery Datepicker?

Der Datumstyp wird in fast allen Geschäftsanwendungen verwendet. Aufgrund der Unterschiede der Kulturen bedeutet die Verwendung dieses Typs manchmal ein Problem für den Entwickler. Der jQuery Datepicker erleichtert jedoch die Verwendung des Datumstyps.
jQuery Datepicker
jQuery Datepicker
Um das Datum im gewünschten Format in der Liste anzuzeigen, kann die folgende Zeile verwendet werden.
HTML
<span class="BirthDate"> @String.Format("{0:dd.MM.yyyy}", item.BirthDate) </span>
Im Speicherformular wird das folgende HTML-Skript verwendet.
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>

   ...
Der jQuery Datepicker kann mit @Html.TextboxFor auf derselben Seite mit dem folgenden Skript funktionieren.
JavaScript
<script language="javascript" type="text/javascript">
 
 $(document).ready(function () {
    $(".BirthDateSave").datepicker({  
             changeMonth: true,
             changeYear: true,  
             dateFormat: 'dd.mm.yy',
             showOn: 'both'
                   });  
                });

</script>
Am Anfang der entsprechenden .cshtml sollten die folgenden Zeilen eingefügt werden.
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) Wie lädt man ein Bild in MVC mit jQuery-Dialog hoch?

Ein Bild kann einfach in einer separaten Ansicht hochgeladen werden. Für nur ein Bild auf eine separate Ansicht umzuleiten und dann zur Listenansicht umzuleiten, kann jedoch in Bezug auf die Kosten ineffizient sein. Stattdessen kann in der Listenansicht durch Klicken auf den Upload-Link in jeder Zeile ein jQuery-Dialog geöffnet werden, ein Bild kann durchsucht und hochgeladen werden.
Bild-Upload
Bild-Upload
Wenn auf "Upload Pic" geklickt wird, wird das folgende Skript ausgeführt.
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;
    }
);

//..
Das SavePersonPic-Formular, das in den jQuery-Dialog geladen wird, ist wie folgt. Für das Hochladen von Dateien im jQuery-Dialog wird iframe verwendet.
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>
Die Datei-Upload-Action im Controller ist unten:
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 --------
    // ..
}
Die JavaScript-"onload"-Funktion des iframe ist unten. Das hochgeladene Bild wird in der entsprechenden Zeile der Liste angezeigt, ohne die Zeile zu aktualisieren.
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) Wie erstellt man eine Tabellenzeile auf der Client-Seite?

Ein zur Datenbank hinzugefügter Datensatz sollte auf der Client-Seite in der Liste angezeigt werden. Dies kann auf viele Arten erfolgen. Nach dem Hinzufügen eines Datensatzes kann die Liste vollständig aus der Datenbank aktualisiert werden, aber das ist eine schwere Operation. Mit JavaScript oder jQuery kann jedoch eine neue Zeile zur Ansicht hinzugefügt werden, ohne alle Elemente in der Ansicht zu aktualisieren. Hier werden zwei Wege erwähnt.
Erstens werden unten die Zeile und die Zellen der Zeile einzeln mit JavaScript erstellt. Wie in den folgenden Skripten zu sehen ist, wird die saveSuccess JavaScript-Funktion nach dem Submit dieses Formulars für ein solches Szenario verwendet.
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)    
    
    ..        
}
 
..
Die saveSuccess JavaScript-Methode ist wie folgt. Die Action gibt ein JSON-Ergebnis zurück, das den Operationstyp enthält. Je nach Operation, d.h. INSERT oder UPDATE, wird die Tabelle in der Ansicht geändert. Wenn ein neuer Datensatz zur Datenbank hinzugefügt wird, wird eine neue Zeile zur Tabelle hinzugefügt (prepend). Wenn ein vorhandener Datensatz in der Datenbank aktualisiert wird, wird nur die entsprechende Zeile in der Tabelle geändert.
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();
    }
}
Der oben erwähnte erste Weg mag wie ein alter Ansatz erscheinen. Daher kann der folgende zweite Weg praktikabler sein. Bei diesem Weg wird gerendertes HTML verwendet, um eine Zeile zur Tabelle hinzuzufügen oder zu aktualisieren. Angenommen, es gibt eine Tabelle wie folgt.
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>
Wenn auf "new" geklickt wird, wird das folgende Skript in den jQuery-Dialog geladen.
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>
}
Wenn das Formular gesendet wird, wird die folgende Action im Controller ausgeführt.
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);
    }

    // .. 

}
Die RenderPartialView-Methode wird verwendet, um das gewünschte HTML-Skript zu erhalten.
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();
    }
}

//..
Die saveSuccess-Funktion im saveAddress-Formular des Ajax-Posts ist wie folgt:
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>
Jede der beiden oben beschriebenen Techniken kann verwendet werden.

15) Wie passt man mapRoute in Global.asax an?

In der klassischen ASP.NET-Anwendung wurden urlRewrite-Operationen mit einigen Drittanbieter-Assemblies leicht durchgeführt. In der MVC-Anwendung ist es möglich, mapRoutes mit Global.asax anzupassen.
Die folgende mapRoute ist in Global.asax Standard:
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
        );

    }

    //  .. 
}
Gemäß dem folgenden Skript wird **/Save/{addressNo}/{personNo}** als Link verwendet.
HTML
@Html.ActionLink("Edit", "Save", 
  new { addressNo = item.AddressNo, personNo = item.PersonNo }, new { @class = "editLink" })
Der Screenshot des obigen Links ist unten.
MapRoute
MapRoute
Daher ist es möglich, eine angepasste mapRoute-Regel wie folgt zu Global.asax hinzuzufügen.
C#
//..
 
routes.MapRoute(
    "AddressSave",
    "Address/Save/{addressNo}/{personNo}",
    new { controller = "Address", action = "Save", 
         addressNo = UrlParameter.Optional, personNo = UrlParameter.Optional }
);
 
//.. 
Jede der beiden oben beschriebenen Techniken kann verwendet werden.

16) Wie macht man checkALL und uncheckALL für alle Zeilen einer Tabelle?

In vielen Anwendungen kann es gewünscht sein, alle Checks in einer Tabelle auf einmal zu markieren oder zu demarkieren.
Check/Uncheck ALL
Check/Uncheck ALL
Für eine solche Funktion kann das folgende Skript verwendet werden.
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) Wie macht man "Loading Data"?

Beim Laden mehrerer Datenzeilen sollte den Benutzern eine "Loading Data"-Nachricht angezeigt werden.
Loading Data
Loading Data
Das folgende div kann entsprechend der erforderlichen Nachricht angepasst werden.
HTML
..
<div id="loadMessage"></div>
..   
Die folgende JavaScript-Funktion kann verwendet werden, um den div-Bereich anzupassen.
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) Wie macht man Master-Detail-Grids mit jQuery?

Wenn auf die Master-Zeile geklickt wird, werden die Detail-Zeilen wie unten gezeigt unter dem Master-Grid angezeigt.
Master-Detail Grids
Master-Detail Grids
Die folgenden Tabellen werden als Grids verwendet.
HTML
..
<table id="CountryTable" class="hovertable2"></table>
<br />
<br />

<table id="CityTable" class="hovertable"></table>
..    
Die folgenden JavaScript-Funktionen werden verwendet, um den Master-Detail-Ansatz zu simulieren.
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

.. 

Fazit

Ich hoffe, es war ein nützlicher Artikel.

Cloud-Computing-Services

Wir bieten Infrastrukturdesign, Migration, Verwaltung und Optimierungsservices auf AWS-, Azure- und Google Cloud-Plattformen.

Unseren Service entdecken

Kontaktieren Sie uns

Kontaktieren Sie unser Team für detaillierte Informationen über unsere AWS- und Cloud-Computing-Lösungen.

Kontakt