Budoray Budoray - 3 months ago 36
Ajax Question

How to use Ajax to update RenderBody() section with VS 2012 Internet Template?

I've looked at few examples where Ajax can be used to update divs or other elements with ids. I have not been able to find an example that uses Ajax with Razor views to help me with the following.

My page is a standard Menu at the top, body in the middle, and a footer. There is no real need to update the header and footer each time. In fact, my page only requires a section of the Body to be updated based on menu clicks and actionlinks on the page. I'm testing this with the Internet Template that is created using VS 2012 if that helps such that I do not have to clutter this request with a bunch of code snippets. I am using Razor views and C# for coding preferences.

So, given the default _Layout.cshtml file, how would I load the About page i.e. RenderBody() section via Ajax? I've tried adding Ajax.BeginForm(...) to my _Layout.cshtml file around one div with an UpdateTargetId that matches a div that I wrapped around the RenderBody() call, returned a partial view from my controller, but that's not quite right. What I get is my partial view only. (The About page with no menu, footer, etc. just the code on the About page)

Would someone kindly share a link that demonstrates this functionality or kindly share the code that does what I desire i.e. swap index view with about view without a full page refresh? Some explanation of what I'm missing would be nice, but I'm sure I could deduce from a solid example where I went awry. As always, your time is much appreciated.

EDIT: Using Jasen's suggestion
_Layout.cshtml

<nav>
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home")</li>
<li>@Ajax.ActionLink("About", "About", "Home", null, new AjaxOptions { HttpMethod = "get", UpdateTargetId = "body" }, new { })</li>
<li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
</nav>


....

Inside my div id="body"

@RenderSection("featured", required: false)
<section class="content-wrapper main-content clear-fix">
@RenderBody()
</section>


.....
HomeController.cs

public ActionResult About()
{
ViewBag.Message = "Your app description page.";

return PartialView();
}


......

Answer

Here is a simple example with jquery. The About partial gets injected into the div with id="body".

<button>About</button>
<div id="body"></div>

$(function () {
    $("button").on("click", function(e) {
        $.get("Home/About").done(function(result) {
            $("#body").html(result);
        });
    });
));

Controller Action

[HttpGet]
public ActionResult About()
{
    return PartialView("About");
}

About.cshtml

@{ Layout = null }
<h2>Home/About</h2>
<p>Blah... </p>

Edit: Maybe a better example is to use a link instead

@Html.ActionLink("About", "About", "Home", null, new { @class="menu-button" })
<div id="body"></div>

$(function () {
    $(".menu-button").on("click", function(e) {
        e.preventDefault();
        var url = $(this).attr("href");
        $.get(url).done(function(result) {
            $("#body").html(result);
        });
    });
});

Edit: Without jquery you want to use Ajax.ActionLink() instead of Ajax.BeginForm()

@Ajax.ActionLink("About", "About", "Home", null, new AjaxOptions { HttpMethod = "get", UpdateTargetId = "body" }, new { })
<div id="body"></div>
Comments