Serie Come Fare su MVC, jQuery, JSON, Paginazione e mapRoute

Scarica Codice Sorgente
Introduzione
A causa della grande quantità di dati nei sistemi di database, il lavoro lato client è diventato molto importante. Nell'approccio code-behind con ASP.NET classico, il metodo naturale è codificare la maggior parte del lavoro nei file code-behind utilizzando i componenti ASP.NET. Inoltre, il rendering dei componenti ASP.NET e il meccanismo viewstate sono ora considerati punti deboli dell'ASP.NET classico.
Per questo motivo è emerso un nuovo paradigma. Secondo questo nuovo paradigma, lo sviluppatore può lavorare con HTML e JavaScript puri senza viewstate che riduce le prestazioni e con meno rendering.
Sebbene MVC sia conosciuto come un vecchio pattern di design o architettura, è diventato popolare specialmente dopo i colli di bottiglia dell'ASP.NET classico menzionati sopra. In MVC, dove jQuery e JSON vengono utilizzati efficacemente, è possibile sviluppare applicazioni ad alte prestazioni.
Prerequisiti
Questo articolo può essere utile dopo aver letto alcuni articoli di livello base su MVC, jQuery e JSON. I seguenti link possono essere utili per i principianti:
Utilizzo del Codice
In questo articolo è stata presa di mira una "serie di come fare". Per questo motivo tutti gli script sono stati forniti dal codice sorgente allegato. In realtà ogni "come fare" potrebbe essere un articolo separato. Comunque, tutte le possibili risposte sono state raccolte in un unico esempio. In questo articolo ci sono approcci pratici piuttosto che informazioni teoriche. Per esempio, sono state utilizzate alcune liste statiche invece del database per semplicità.
Le seguenti domande vengono risposte:
- Come fare CRUD in MVC con buone prestazioni?
- Come usare jQuery dialog invece di confirm o alert JavaScript?
- Come fare la paginazione nella lista MVC?
- Come fare il link "mostra altro" in MVC usando jQuery?
- Come usare gli attributi con i link?
- Come fare una chiamata AJAX in jQuery?
- Come usare la Form collection in MVC?
- Come eliminare più record in una volta sola?
- Come usare partial action in MVC?
- Come usare il formato JSON nell'applicazione MVC?
- Come popolare combobox master-detail?
- Come usare jQuery datepicker?
- Come caricare immagini in MVC con jQuery dialog?
- Come creare righe di tabella lato client?
- Come personalizzare mapRoute in Global.asax?
- Come selezionare e deselezionare tutte le righe della tabella?
- Come fare "Loading Data"?
- Come fare grid master-detail con jQuery?
1) Come fare CRUD in MVC con buone prestazioni?
Pensandoci approssimativamente, tutte le soluzioni aziendali hanno la funzionalità Create-Read-Update-Delete (Crea-Leggi-Aggiorna-Elimina). Se possibile, utilizzare lo stesso "modulo di salvataggio" sia per "insert" che per "update" può essere vantaggioso dal punto di vista dello sviluppatore. Utilizzare lo stesso modulo è possibile gestendo i parametri inviati all'action.
Supponiamo di avere una lista simile a una griglia (in realtà una tabella HTML) nel modulo e un pulsante "new" separato. Ogni riga della tabella ha un pulsante "edit" e "delete" relativi a quella riga.
Dopo aver cliccato "New", reindirizzare a una nuova pagina - qui chiamata view - non è un modo efficiente. Perché dopo che i dati vengono salvati nella pagina reindirizzata, l'utente deve cliccare "mostra lista" per vedere i dati aggiunti al database. Questo significa reindirizzamento alla vista lista e selezione dati dal database con costo di selezione variabile!
Invece dello scenario "clicca new e rilista" espresso sopra, può essere implementato un modo migliore.
Create (Crea):
- Nella vista lista, dopo aver cliccato "New", può apparire un "jQuery Save dialog".
- La Create view viene renderizzata nel jQuery dialog.
- Il form Create viene compilato e si preme "Save".
- Nel momento in cui viene premuto il pulsante Save, i dati possono essere inviati al controller correlato tramite AJAX post.
- Il form Ajax ha una funzione JavaScript
onSuccess. - Nel metodo JavaScript "
onSuccess", la nuova riga aggiunta viene preposta all'inizio della lista con il JSON che arriva come parametro a "onSuccess", senza aggiornare l'intera lista.
Read (Leggi):
Questa è un'operazione di listaggio. Se possibile, nella form lista dovrebbero essere mostrati solo i dati necessari. Possono essere utilizzate le seguenti tecniche:
- paginazione con combobox o numeri,
- implementazione "mostra altro",
- listaggio con filtraggio.
Update (Aggiorna):
- Nella vista lista, dopo aver cliccato "Edit" in qualsiasi riga della lista, può apparire lo stesso "jQuery Save dialog" con i dati della riga selezionata.
- Poiché tutti i passaggi sono gli stessi di "Create", solo il metodo "
onSuccess" viene modificato secondo l'operazione "update". - In questo caso, dopo l'aggiornamento del database, vengono aggiornati solo i dati nella riga modificata nella vista. In questo modo, non è necessario aggiornare l'intera lista per vedere l'ultimo record modificato.
Delete (Elimina):
- Dopo la conferma con un jQuery dialog dall'aspetto gradevole, dopo l'eliminazione dal database, solo la riga selezionata viene rimossa dalla lista. Ancora, non è necessario aggiornare l'intera lista.
Lo stesso dialog viene utilizzato sia per insert che per edit.

I link nella vista PersonList.cshtml sono i seguenti:
HTML
@Html.ActionLink("New", "Save",
new { personNo = 0 }, new { @class = "newLink" })
...
@Html.ActionLink("Edit", "Save", new { personNo = item.PersonNo }, new { @class = "editLink" })
- New: Testo da visualizzare.
- Save: Action nel Controller.
- personNo: Parametro inviato all'action "Save". Se è 0, il dialog si apre vuoto, se è maggiore di 0, i dati di quell'id vengono mostrati nel dialog.
- newLink: className fittizio da usare nel jQuery seguente.
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>
L'action Save nel
PersonController è la seguente: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) Come usare jQuery dialog invece di confirm o alert JavaScript?
La message box personalizzata è possibile nelle applicazioni Windows. Per il web è possibile quando viene utilizzata una libreria di componenti di terze parti. È anche possibile usare jQuery dialog invece dei box JavaScript come segue:

Il link Delete nella vista
PersonList è il seguente:HTML
@Html.ActionLink("Delete", "DeletePerson", new { personNo =
item.PersonNo }, new { @class = "deleteLink", @pkNo = item.PersonNo })
Il codice HTML e jQuery è il seguente:
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) Come fare la paginazione nella lista MVC?
La paginazione è uno dei buoni approcci per listare i dati e minimizzare i costi di trasferimento dati. Ci sono molti modi per visualizzare i dati. In questo "come fare" è stato usato un combobox per la paginazione. Tuttavia, se desiderato, è possibile anche la numerazione in fondo alla pagina. Questo dipende dall'applicazione e dallo sviluppatore. La paginazione con combobox può essere sviluppata come segue.

Prima di tutto, lo spazio per i metadati della paginazione viene organizzato come segue:
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>
...
Quando la pagina viene caricata per la prima volta, il div con id "
paginginfo" viene popolato e la prima pagina dei record viene mostrata utilizzando gli script seguenti.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>
Il codice dell'action nel Controller è il seguente. Come si può vedere, la lista risultato viene parzialmente renderizzata utilizzando il metodo
RenderPartialView e inserita nell'oggetto JSON.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;
}
//..
}
Quando il
selecteditem del combo con id "PageSelect" cambia, viene eseguito il seguente script jQuery.JavaScript
//..
$("#PageSelect").change(function ()
{
var $this = $(this);
var parPageNo = $this.val();
var parPersonNo = $("#paginginfo .pagingPersonNo").text();
fillData(parPersonNo,parPageNo);
});//PageSelect
//..
4) Come fare il link "mostra altro" in MVC usando jQuery?
Questa tecnica viene utilizzata in molti siti web popolari. Dovrebbe essere applicata nelle liste grandi. Il "mostra altro" può essere realizzato come segue:

Nella vista lista c'è un link per "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>
//
Quando viene cliccato "more", viene eseguito il seguente script jQuery.
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
// ..
La seguente action nel Controller restituisce il risultato JSON.
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) Come usare gli attributi con i link?
Questa è una buona capacità da usare specialmente per pulsanti come edit, delete, show detail.
Quando viene creata la lista, la chiave correlata viene aggiunta al link come attributo. Nell'evento click del link, quella chiave viene usata e l'operazione viene eseguita facilmente.
Per esempio, supponiamo che ci sia un link delete in ogni riga di una lista. Quando viene cliccato il link delete nella riga, è possibile usare la chiave come parametro per la "delete action" nel controller.
HTML
@Html.ActionLink("Delete", "DeletePerson", new { personNo = item.PersonNo },
new { @class = "deleteLink", @pkNo = item.PersonNo })
Quando viene controllato il sorgente sul client, si vede la seguente riga.
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>
Nello script jQuery gli attributi vengono usati come segue. Per esempio pkno è 1 e viene usato.
JavaScript
$(".deleteLink").live("click", function (e)
{
e.preventDefault();
var pkNo = $(this).attr("pkNo");
//..
});
6) Come fare una chiamata AJAX in jQuery?
La chiamata AJAX è una capacità molto buona per rendere un'applicazione più veloce. In alcune applicazioni con grandi quantità di dati nel database, lo sviluppatore deve prestare attenzione al trasferimento di basse quantità di dati su due linee dati. La prima linea è tra il database e l'applicazione, la seconda è tra l'applicazione e il browser client. Per tali requisiti la chiamata AJAX è molto utile.
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
//..
L'URL può essere usato anche come segue.
JavaScript
//..
url: "@Url.Action("DeletePerson", "Person")",
// ..
7) Come usare la Form collection in MVC?
Quando viene inviato un form, tutti gli elementi del form vengono inviati come collezione all'action correlata nel controller. Nel controller, ogni coppia chiave-valore può essere usata. Supponiamo di avere un form di salvataggio come segue:
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>
}
I dati nella vista possono essere inviati all'action nel controller come oggetto model o come FormCollection come mostrato di seguito:
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) Come eliminare più record in una volta sola?
In alcune pagine a volte eliminare molti record in una volta sola facilita il lavoro. Eliminare più record è possibile raccogliendo le chiavi di tutti i record selezionati. Dopo che tutte le chiavi vengono inviate al controller, l'eliminazione può essere eseguita come segue.

Prima viene cliccato il pulsante "Delete Selected" con id "deleteALL". Dopo aver premuto Yes, può essere usato il seguente script jQuery. Naturalmente possono essere sviluppati anche script alternativi.
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
//...
Come visto sopra, l'eliminazione di molti record viene fatta con chiamata ajax all'action "DeleteALL" nel controller "Note".
9) Come usare Partial Action in MVC?
In alcune situazioni, è necessario un componente che deve essere usato in molti form. Per esempio, potrebbe essere necessario un "box informazioni persona" in alcuni form separati come mostrato di seguito.

La vista _personinfo può essere come segue.
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>
Per usare partial action in qualsiasi vista, può essere usata la seguente riga di codice.
HTML
//..
<h2>Address List</h2>
<div>
@Html.Action("_personinfo", "Common")
</div>
//..
10) Come usare il formato JSON nell'applicazione MVC?
Il formato JSON può essere usato quando si inviano parametri a un'action nel controller e quando si ricevono risultati da un'action. Come mostrato di seguito, l'action DeleteNote nel controller Note ha il parametro noteNo. Qui pkNo è un parametro chiamato con valore.
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
È possibile ottenere il risultato JSON dall'action nel controller. Lo script seguente restituisce il risultato come oggetto json.
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) Come popolare combobox master-detail?
Alcuni form richiedono di popolare un combobox quando ne viene cambiato un altro. Per esempio, per una coppia paese-città, il paese può essere pensato come master e la città come detail.

I codici delle action sono come segue. Le liste vengono incorporate nell'oggetto json.
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);
}
//..
}
Questa tecnica può essere usata per qualsiasi elemento html nella vista form.
12) Come usare jQuery datepicker?
Il tipo data viene usato in quasi tutte le applicazioni aziendali. A causa della diversità delle culture, a volte usare questo tipo significa problema per lo sviluppatore. Tuttavia jQuery datepicker facilita l'uso del tipo data.

Per mostrare la data nel formato desiderato nella lista, può essere usata la seguente riga.
HTML
<span class="BirthDate"> @String.Format("{0:dd.MM.yyyy}", item.BirthDate) </span>
jQuery Datepicker può funzionare con @Html.TextboxFor nella stessa pagina con il seguente script.
JavaScript
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$(".BirthDateSave").datepicker({
changeMonth: true,
changeYear: true,
dateFormat: 'dd.mm.yy',
showOn: 'both'
});
});
</script>
13) Come caricare immagini in MVC con jQuery dialog?
Un'immagine può essere caricata facilmente in una vista separata. Tuttavia, reindirizzare a una vista separata solo per caricare un'immagine e poi reindirizzare alla vista lista può essere inefficiente. Invece, nella vista lista, cliccando il link upload in ogni riga, può essere aperto un jQuery dialog, sfogliata e caricata un'immagine.

L'action di upload file nel controller è la seguente:
C#
[HttpPost]
public JsonResult SavePersonPic(HttpPostedFileBase file, int personNo)
{
string message = string.Empty;
bool success = false;
string imgPath = "";
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;
message = "File uploaded successfully";
imgPath = Url.Content(String.Format("~/Content/images/{0}", file.FileName));
success = true;
}
catch (Exception ex)
{
message = ex.Message;
}
return Json(new { Success = success, Message = message, PersonNo=personNo, ImagePath = imgPath }, JsonRequestBehavior.AllowGet);
}
14) Come creare righe di tabella lato client?
Un record aggiunto al database deve essere mostrato nella lista lato client. Questo può essere fatto in molti modi. Dopo che un record viene aggiunto, la lista può essere completamente aggiornata dal database ma questa è un'operazione pesante. Tuttavia, usando javascript o jquery, può essere aggiunta una nuova riga alla vista senza aggiornare tutti gli elementi nella vista.
L'action restituisce un risultato json che include il tipo di operazione. Secondo l'operazione, cioè INSERT o UPDATE, la tabella nella vista viene modificata. Quando viene aggiunto un nuovo record al database, viene aggiunta (prepend) una nuova riga alla tabella. Quando viene aggiornato un record esistente nel database, viene cambiata solo la riga correlata nella tabella.
15) Come personalizzare mapRoute in Global.asax?
Nell'applicazione ASP.NET classica, le operazioni urlRewrite venivano realizzate facilmente con alcuni assembly di terze parti. Nell'applicazione MVC, è possibile personalizzare i mapRoute usando Global.asax.
Il seguente mapRoute è il default in Global.asax:
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
);
}
// ..
}

Per questo motivo, è possibile aggiungere una regola mapRoute personalizzata a Global.asax come segue.
C#
//..
routes.MapRoute(
"AddressSave",
"Address/Save/{addressNo}/{personNo}",
new { controller = "Address", action = "Save",
addressNo = UrlParameter.Optional, personNo = UrlParameter.Optional }
);
//..
Può essere usata una delle due tecniche descritte sopra.
16) Come selezionare e deselezionare tutte le righe della tabella?
In molte applicazioni, potrebbe essere desiderato selezionare o deselezionare tutti i check in una tabella in una volta sola.

Per tale funzione può essere usato il seguente script.
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 cb = row.find('span#cboxSpan').find('input.cboxDELclass');
if (state==true)
cb.attr('checked',true);
else
cb.attr('checked',false);
}
}
//..
17) Come fare "Loading Data"?
Quando vengono caricate più righe di dati, il messaggio "loading data" dovrebbe essere mostrato agli utenti.

Il seguente div può essere personalizzato secondo il messaggio richiesto.
HTML
..
<div id="loadMessage"></div>
..
La seguente funzione javascript può essere usata per personalizzare l'area div.
JavaScript
..
function showLoader(root, txt) {
$("#loadMessage").html("");
$("#loadMessage").show();
var loader = '<img src="' + root + '/ajax-loader.gif" align="absmiddle"> <span><br/>' + txt + '...</span>';
$("#loadMessage").fadeIn(100).html(loader);
}
function hideLoader() {
$("#loadMessage").hide();
}
..
18) Come fare grid master-detail con jQuery?
Quando viene cliccata la riga master, le righe detail vengono mostrate sotto la grid master come mostrato di seguito.

Le seguenti tabelle vengono usate come grid.
HTML
..
<table id="CountryTable" class="hovertable2"></table>
<br />
<br />
<table id="CityTable" class="hovertable"></table>
..
Le seguenti funzioni javascript vengono usate per simulare l'approccio master-detail.
JavaScript
..
function setTableRowClick()
{
$("#CountryTable tr td.clickable").unbind('click');
$('#CountryTable tr td.clickable').click(function ()
{
var row = $(this).parent();
setRow(row);
});
}
function setRow(row)
{
var rowid = row.attr('id');
var higlightedCountryTableRowid = $("#pageinfo .higlightedCountryTableRowid").text();
$("#pageinfo .higlightedCountryTableRowid").html(rowid.toString());
if ((rowid==0) || (rowid!=higlightedCountryTableRowid))
{
row.siblings().removeClass('diffColor');
row.addClass("diffColor");
fillCityData(rowid);
}
}
..
Dovrebbero essere incluse le seguenti righe all'inizio del .cshtml appropriato.
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) Come caricare un'immagine in MVC con jQuery dialog?
Un'immagine può essere facilmente caricata in una vista separata. Tuttavia, reindirizzare a una vista separata solo per caricare un'immagine e poi reindirizzare alla vista elenco potrebbe essere inefficiente in termini di costi. Invece, nella vista elenco, cliccando sul link di caricamento in ogni riga, può essere aperto un dialog jQuery, un'immagine può essere sfogliata e caricata.

Quando si clicca "Upload Pic", viene eseguito il seguente script.
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;
}
);
//..
Il form SavePersonPic caricato nel dialog jQuery è il seguente. Per caricare file nel dialog jQuery viene utilizzato un iframe.
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>
L'action di caricamento file nel Controller è la seguente:
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 --------
// ..
}
La funzione JavaScript "onload" dell'iframe è la seguente. L'immagine caricata viene mostrata nella riga relativa dell'elenco senza refresh della riga.
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) Come creare una riga di tabella lato client?
Un record aggiunto al database dovrebbe essere mostrato nell'elenco lato client. Questo può essere fatto in molti modi. Dopo l'aggiunta di un record, l'elenco può essere completamente aggiornato dal database ma sarebbe un'operazione pesante. Tuttavia, usando javascript o jquery, è possibile aggiungere una nuova riga alla vista senza refreshare tutti gli elementi nella vista. Qui vengono menzionati due modi.
Nel primo, sotto, la riga e le celle della riga vengono create una per una con javascript. Come visibile negli script seguenti, la funzione JavaScript saveSuccess dopo il submit di questo form viene usata per tale scenario.
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)
..
}
..
Il metodo javascript saveSuccess è il seguente. L'action restituisce un risultato json che include il tipo di operazione. A seconda dell'operazione, cioè INSERT o UPDATE, viene modificata la tabella nella vista. Quando viene aggiunto un nuovo record al database, viene aggiunta una nuova riga alla tabella (prepend). Quando viene aggiornato un record esistente nel database, viene modificata solo la riga relativa nella tabella.
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();
}
}
Il primo modo menzionato sopra può sembrare un approccio vecchio. Pertanto, il secondo modo seguente potrebbe essere più applicabile. In questo modo, viene utilizzato l'html renderizzato per aggiungere o aggiornare la riga della tabella. Supponiamo di avere una tabella come segue.
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>
Quando si clicca "new", il seguente script viene caricato nel dialog jQuery.
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>
}
Quando il form viene inviato, viene eseguita la seguente action nel controller.
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);
}
// ..
}
Viene utilizzato il metodo RenderPartialView per ottenere lo script html richiesto.
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();
}
}
//..
La funzione saveSuccess del post ajax nel form saveAddress è la seguente:
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>
Qualsiasi delle due tecniche sopra descritte può essere utilizzata.
15) Come personalizzare mapRoute in Global.asax?
Nelle applicazioni asp.net classiche, le operazioni urlRewrite venivano facilmente realizzate con alcune assembly di terze parti. Nell'applicazione MVC, è possibile personalizzare i mapRoute usando Global.asax.
Il seguente mapRoute è il default in Global.asax:
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
);
}
// ..
}
Secondo lo script seguente,
**/Save/{addressNo}/{personNo}** viene usato come link.HTML
@Html.ActionLink("Edit", "Save",
new { addressNo = item.AddressNo, personNo = item.PersonNo }, new { @class = "editLink" })
Lo screenshot del link sopra è il seguente.

Pertanto, è possibile aggiungere una regola mapRoute personalizzata a Global.asax come segue.
C#
//..
routes.MapRoute(
"AddressSave",
"Address/Save/{addressNo}/{personNo}",
new { controller = "Address", action = "Save",
addressNo = UrlParameter.Optional, personNo = UrlParameter.Optional }
);
//..
Qualsiasi delle due tecniche sopra descritte può essere utilizzata.
16) Come checkALL e uncheckALL di tutte le righe di una tabella?
In molte applicazioni, potrebbe essere desiderabile selezionare o deselezionare tutti i check in una tabella in una volta sola.

Per tale funzione può essere usato il seguente script.
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) Come fare "Loading Data"?
Quando vengono caricate più righe di dati, un messaggio "loading data" deve essere mostrato agli utenti.

Il seguente div può essere personalizzato secondo il messaggio richiesto.
HTML
..
<div id="loadMessage"></div>
..
Per personalizzare l'area div può essere usata la seguente funzione javascript.
JavaScript
..
function showLoader(root, txt) {
$("#loadMessage").html("");
$("#loadMessage").show();
var loader = '<img src="' + root + '/ajax-loader.gif" align="absmiddle">&nbsp;<span><br/>' + txt + '...</span>';
$("#loadMessage").fadeIn(100).html(loader);
}
function hideLoader() {
$("#loadMessage").hide();
}
..
18) Come creare grid master-detail con jQuery?
Quando si clicca sulla riga master, le righe detail vengono mostrate sotto il grid master come mostrato di seguito.

Come grid vengono usate le seguenti tabelle.
HTML
..
<table id="CountryTable" class="hovertable2"></table>
<br />
<br />
<table id="CityTable" class="hovertable"></table>
..
Per simulare l'approccio master-detail vengono usate le seguenti funzioni javascript.
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
..
Conclusione
Spero che questo sia stato un articolo utile.
Servizi di Cloud Computing
Offriamo servizi di progettazione dell'infrastruttura, migrazione, gestione e ottimizzazione su piattaforme AWS, Azure e Google Cloud.
Scopri il Nostro ServizioContattaci
Contatta il nostro team per informazioni dettagliate sulle nostre soluzioni AWS e cloud computing.
Contatto