Har du en formular i dit MVC3 projekt hvor du ønsker at
lave en delvis sideopdatering via AJAX, men har lidt problemer med
at få standard valideringstekster fra MVC3 til at fungere, så tjek
nedenstående...
Controlleren skal udformes som normalt for postback. Jeg vælger
typisk at benytte standard dataannotations, dvs. således:
public class PersonController : Controller
{
[Authorize]
public ActionResult Edit()
{
return View(new EditPersonViewModel());
}
[Authorize]
[HttpPost]
public ActionResult Edit(EditPersonViewModel model)
{
if(ModelState.IsValid)
{
var person = new Person();
person.Name = model.Name;
person.Address = model.Address;
person.Save();
}
return View(model)
}
}
Min ViewModel ser således ud:
public class EditPersonViewModel
{
[Required]
public string Name { get; set; }
[Required]
public string Address { get; set; }
}
Min klientkode ser således ud:
$(function() {
function postPerson($frm) {
var action = $frm.attr("action"),
params = $frm.serializeArray();
$("#editPersonContainer").load(action, params);
}
$("#editPersonContainer input[type=submit]")
.live("click", function() {
postPerson($(this.form));
return false;
});
});
Submit-knappen kalder postPerson og returnerer derefter false,
for at undgå formularen sendes på normal vis (dvs. som en fuldside
postback). Jeg benytter .live for at fastholde eventhandleren til
submit-knappen efter formularen genindlæses fra serveren i
editPersonContainer-elementet (ellers ville handleren gå tabt, når
formularen sendes til serveren). I jQuery v 1.7+ burde man nok
benytte den nye on-funktion i stedet
for live.
$frm.serializeArray benyttes fordi .load-funktionen forventer et
objekt når der er tale om et postback. Så almindelig
name/value-strenge kan ikke bruges (det er i det mindste min
erfaring).
Selve formularen/view ser således ud:
@model EditPersonViewModel
@{
Layout = null;
}
<div id="editPersonContainer">
@using(Html.BeginForm("Edit", "Profile"))
{
@Html.LabelFor(m => m.Name)
@Html.EditorFor(m => m.Name)
@Html.ValidationMessageFor(m => m.Name)<br/>
@Html.LabelFor(m => m.Address)
@Html.EditorFor(m => m.Address)
@Html.ValidationMessageFor(m => m.Address)<br/>
<input type="submit" value="Gem">
}
</div>
Layout sættes til null for at undgå evt. implicitte master
layouts bliver renderet.
Med ovenstående på plads, kan jeg indsætte formularen på en
given side med:
@Html.Action("Edit", "Person")