Render a View or Template Using JavaScript
This post builds off my previous one ASP.NET MVC Model Binding to a List. This post is about how to render a partial view when you make an AJAX call. This will also work with an EditorTemplate or a DisplayTemplate. I personally recommend using a partial view as you can take advantage of model binding for your templates better, as you will see, doing this from an AJAX call is a little different.
The Setup
Not much has changed from the original post’s setup. I can say we have changed the view and the controller a little and of course added a partial view. I know my original post did not show any source for the view, but I will do that here so you can see how things are setup.
The View
@model MVC451Sandbox.ViewModels.VehicleList @{ ViewBag.Title = "List"; } <h2>List</h2> @if (Model != null) { using (Html.BeginForm()) { @Html.LabelFor(m => m.Color)<text>: </text>@Html.EditorFor(m => m.Color) @Html.LabelFor(m => m.Year)<text>: </text>@Html.EditorFor(m => m.Year) @Html.EditorFor(m => m.Model) @Html.HiddenFor(m => m.Id) <input type="submit" value="Save" /> <button id="showOwners">Display Owners divOwners"> } } @section Scripts { @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/jqueryval")<script> function testClick() { $.ajax({ type: 'get', url: "@Url.Action("GetOwnersPartialView", "Test")", data: { vId: @Model.Id }, success: function(result){ //Success $(divOwners).html(''); $(divOwners).html(result); }, error: function(xhr) { //Error alert("Error! " + xhr.responseText); } }); return false; } $(document).ready(function () { $(showOwners).on("click", testClick); }); }
The Partial View (_EditOwners.cshtml)
@model List<MVC451Sandbox.Models.Owner> <h3>Current and Previous Owners</h3> @{ if (Model != null && Model.Count > 0) { for (int i = 0; i < Model.Count; i++) { @Html.LabelFor(m => Model[i].Name) @: @Html.TextBox(String.Format("Owners[{0}].Name", i), Model[i].Name) @Html.LabelFor(m => Model[i].PurchaseYear) @: @Html.TextBox(String.Format("Owners[{0}].PurchaseYear", i), Model[i].PurchaseYear) @Html.Hidden(String.Format("Owners[{0}].Id", i), Model[i].Id) @Html.Hidden(String.Format("Owners[{0}].VehicleId", i), Model[i].VehicleId) } } else { No previous or current owners on record. } }
The Controller Method
public ActionResult GetOwnersPartialView(int vId) { List owners = (from o in db.Owners where o.VehicleId == vId select o).OrderByDescending(o => o.PurchaseYear).ToList(); return PartialView("_EditOwners", owners); }
The Goal
The goal here is to render some information that will then be submitted back to the controller as part of the View Model’s binding.
To achieve this goal the key is to have our AJAX method call the GetOwnersPartialView method. That method will then return a partial view using the _EditOwners.cshtml partial view. The JavaScript will then take that resulting HTML and plug it into the the div we called divOwners In order to get the model binding to work you can see what I did in the partial view.
In the partial view had to use the TextBox helpers instead of EditorFor. If you use the EditorFor and just try to use the model the HTML will have an id like [0].Name, and the binding will not work.
Summary
With a little extra work we can have an AJAX call render a partial view on our page. That information can then be sent up using the model binding to the controller. This might be useful when you have some other back-end processing that needs to be done before the user actually saves their work, but you need the results of that back-end to be part of the submit.
I forgot to point out one thing if you plan to use something like a specific editor template. You need to be sure you provide that path in your PartialView call. Please see the snippet below.
return PartialView("~/Views/Shared/EditorTemplates/Owners.cshtml", owners);
Posted on October 30, 2015, in Learning, MVC and tagged MVC. Bookmark the permalink. Leave a comment.
Leave a comment
Comments 0