1

I have built an mvc 4 website, and I built it so that the main layout page doesn't refresh if a different section is loaded with jQuery. I put the navigator and jQuery script in _Layout.cshtml:

<ul id="menu" class="menu-items">
                <li><a id="Item1" href="#" onclick="loadPage(this.id)">Item1</a></li>
                <li><a id="Item2" href="#" onclick="loadPage(this.id)">Item2</a></li>
                <li><a id="Item3" href="#" onclick="loadPage(this.id)">Item3</a></li>
                <li><a id="Item4" href="#" onclick="loadPage(this.id)">Item4</a></li>
            </ul>

</body>

<script>

    function loadPage(action) {

        $.post("/Home/" + action, function (data) {
            $(content).html(data);
        });
    }
</script>

Then I have my controller:

namespace MyApp.Controllers
{
public class HomeController : Controller
{

    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Item1()
    {
        if (Request.IsAjaxRequest())
        {
            return PartialView();
        }
        return View();
    }

    [HttpPost]
    public ActionResult Item2()
    {
        if (Request.IsAjaxRequest())
        {
            return PartialView();
        }
        return View();
    }

Etc, etc.

Everything works fine, except that I don't know how to use just one main content view (which is index.cshtml when the website loads in the browser). I'm forced to put the same content that's in index.cshtml into item1.cshtml so that when I trigger onlick for item1, it will go back to the main content. The only route config I have is for the Default, which initially set to Index:

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }

What I want, is to be able to use just one main content page, but have the ajax call still get me back to the main content when I click Item1. Does anyone know what I need to do? It seems to be a little overkill to have to update both views when I want to update the main content.

Also, I think other web devs will like this code. Especially if you're building a band's website like I'm doing. It allows me to put the demo song media player in the _layout.cshtml page so that it won't refresh when the user is clicking to the other sections (i.e. if it refreshes, the media player stops). With this design, the user can navigate the whole website while the songs continue to play.

I'm rather new to javascript, so I'm sure I could have made a better onclick handler rather than using anchor tags, so if anyone want to show me a better way, please do. But my main problem is the index.cshtml vs item1.cshtml dilemma.

1
  • If my answer solved your issue please set it as the answer. Commented Jan 16, 2013 at 3:30

1 Answer 1

3

Correct me if I'm wrong: you want to refresh part of your page when clicking on ItemX link and the controller methods ItemX are only used via Ajax (as you're building a single page app).

In this case you could do something like this:

Cshtml

<ul id="menu" class="menu-items">
    <li><a id="Item1" href="#" onclick="loadPage(this.id)">Item1</a></li>
    <li><a id="Item2" href="#" onclick="loadPage(this.id)">Item2</a></li>
    <li><a id="Item3" href="#" onclick="loadPage(this.id)">Item3</a></li>
    <li><a id="Item4" href="#" onclick="loadPage(this.id)">Item4</a></li>
</ul>

<div id="container">
</div>

</body>

<script>
    function loadPage(action) {
        $.post("/Home/" + action, function (data) {
            $("#container").html(data);
        });
    }
    // Will load Item1 via Ajax on page load
    loadPage('Item1');
</script>

Home Controller

[HttpPost]
public ActionResult Item1()
{
    return PartialView();
}

Your PartialViews should only contain the HTML specific to the current item.

Update

If you wish to avoid the Ajax call you could do this also in your cshml

...
</ul>

<div id="container">
    @Html.Partial("Item1PartialView")
</div>

</body>
...
Sign up to request clarification or add additional context in comments.

4 Comments

I have the refreshing part worked out. The problem is when the site is loaded, it loads index.cshtml wrapped with _layout.cshtml with the main content, and I need a menu item that will load the contents of index.cshtml using ajax. So far, I haven't been able to treat index the same way as the other partial views. So I had to create another file called item1.cshtml that has the same contents as index.cshtm, and I don't want to duplicate the data every time I need to make content change on the main page.
Write this inside your script block: loadPage('Item1'); This way the user will load the layout first and item1 via Ajax.
Now the the problem comes down to the index.cshtml. What do I do with it? It's not even really needed, but the website won't load without it.
In this case keep it empty. If it ain't broke, don't fix it :) I would also recommend you to read more about Single Page Application using ASP.NET MVC. It'll most likely answer this kind of question and help you structure your application better.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.