I've been fighting this for a while and I think I'm close. I am new to MVC and am after the mcguffin of web design, all the model handling (including validation) with partial views (not update the whole page). My current method (below) 'works' until there is an ajax postback (I get the partial back using ajax). The problem is the client validation works before I press the Create button and repopulate the Partial View. I test this by clearing out the 'Age' textbox and pressing Create. I get the message saying the field is required. Then I enter a valid value int the field and press Create again and 'post' back. Now, when I clear the Age box again, the error message does not show up and it lets me post with an invalid value showing. Can anyone tell me why it will not work after I hit the 'Create' (id=yourSubmitButtonID) button?
Also, if anyone knows a better way to do this please let me know.
PartialController.cs
using StuffTesterMVC.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace StuffTesterMVC.Controllers
{
public class PartialController : Controller
{
// GET: Partial
public ActionResult Partials()
{
return View();
}
public PartialViewResult GetModel01()
{
PartialViewModel01 model = new PartialViewModel01();
model.Birthday = DateTime.Parse("9/10/1964");
return PartialView("PartialViewModel01", model);
}
}
}
Partials.cshtml
@{
Layout = null;
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Partials</title>
</head>
<body>
<div id="divPartial01">
@Html.Partial("PartialViewModel01", new StuffTesterMVC.Models.PartialViewModel01())
</div>
@*<div id="divPartial02">
@Html.Partial("PartialViewModel02", new StuffTesterMVC.Models.PartialViewModel02())
</div>*@
<!-- SCRIPTS -->
<script>
function saveSampleModel01() {
alert('posting');
$.ajax({
url: "@Url.Action("GetModel01", "Partial")",
type: "post", // make this "get" to get data
data: $("#divPartial01").serialize(),
success: function (result) {
$("#divPartial01").html(result);
alert('success');
},
error: function (result) {
err: alert("Failed");
}
});
}
</script>
</body>
</html>
PartialViewModel01.cshtml
@model StuffTesterMVC.Models.PartialViewModel01
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>PartialViewModel01</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Age, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Age, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Age, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Birthday, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Birthday, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Birthday, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" id="yourSubmitButtonID" value="Create" class="btn btn-default" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" value="Save" onclick="saveSampleModel01();" class="btn btn-default" />
</div>
</div>
</div>
<script>
$(function () {
$("#yourSubmitButtonID").click(function (e) {
e.preventDefault();
var _this = $(this);
var _form = _this.closest("form");
alert('validating');
var validator = $("form").validate(); // obtain validator
var anyError = false;
_form.find("input").each(function () {
if (!validator.element(this)) { // validate every input element inside this step
anyError = true;
}
});
if (anyError) {
alert('found errors');
return false; // exit if any error found
}
alert('no errors - do "post"');
saveSampleModel01();
//$.post(_form.attr("action"), _form.serialize(), function (data) {
//check the result and do whatever you want
})
});
</script>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>