In MVC Application, I want to render some parts of form dynamically (which are like PartialView on Controller Side)
In the partial view, i dont have Html.BeginForm()
If you want the data validation tags to be there, you need to be in a FormContext
. Hence, if you're dynamically generating parts of your form, you need to include the following line in your partial view:
@{ if(ViewContext.FormContext == null) {ViewContext.FormContext = new FormContext(); }}
You then need to make sure you dynamically rebind your unobtrusive validation each time you add/remove items:
$("#form").removeData("validator");
$("#form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("#form");
you're correct in assuming that this is by design. if you check the source you'll see the following:
// Only render attributes if unobtrusive client-side validation is enabled, and then only if we've
// never rendered validation for a field with this name in this form. Also, if there's no form context,
// then we can't render the attributes (we'd have no <form> to attach them to).
public IDictionary<string, object> GetUnobtrusiveValidationAttributes(string name, ModelMetadata metadata)
To fix this we can write an extension method for use in our partial view:
public static class HtmlExtentions
{
public static void EnablePartialViewValidation(this HtmlHelper helper)
{
if (helper.ViewContext.FormContext == null)
{
helper.ViewContext.FormContext = new FormContext();
}
}
}
And then use it in our partial view:
@model Introduction.Models.Human
@{ Html.EnablePartialViewValidation(); }
<div>
@Html.EditorFor(model => model.MarriageInformation.SpouseDetails)
<div class="editor-label">
@Html.LabelFor(model => model.MarriageInformation.DOM)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.MarriageInformation.DOM)
@Html.ValidationMessageFor(model => model.MarriageInformation.DOM)
</div>
</div>
The last step is to handle parsing the new validation attributes in our ajax callback:
$(function () {
$('button').click(function (e) {
e.preventDefault();
$.get('@Url.Action("AddSpouse")', function (resp) {
var $form = $('form');
$form.append(resp);
$form.removeData("validator").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse($form);
})
})
});