What is the best practice for maintain a menu after a page reload? I have this custom code which feels wrong

231 views Asked by At

I have a custom Menu which loads a new MVC View for each click as I want. I load the new View by setting window.location.href. To make it work I have to set the baseURL (the name of the website) each time. To Store the state of the menu I use URL's querystring.

My concerns is in the use of:

  1. '/WebConsole53/' // hardcode baseurl i have to apply each time manually
  2. Setting window.location.href to load the new View from JavaScript // Is this the best way or should I use some URL/Html helpers instead?
  3. I store the state of the selected menuItem in the querystring ("menu") // Is it more common to store that kind in Session/Cookie?

Any thoughts, corrections and suggestions would be much appriciated - thanks.

_Layout.cshtml

var controller = $self.data('webconsole-controller');
var action = $self.data('webconsole-action');
var menu = "?menu=" + $self.attr('id');
var relUrl = controller + "/" + action + menu;
var url = urlHelper.getUrl(relUrl);
window.location.href = url;

UrlHelper.js

var urlHelper = function () {
    var getBaseUrl = '/WebConsole53/',

        buildUrl = function(relUrl) {
            return getBaseUrl + relUrl;
        };

    var getUrl = function(relUrl) { // relUrl format: 'controller/action'
        return buildUrl(relUrl);
    };

    return {
        getUrl: getUrl
    };
}();

I Use MVC 5.

2

There are 2 answers

1
DAG On

You can save this problem using Route. Through the route you know exactly where you are located in you application.

_Layout.cshtml is definetely not the place to have this javascript. Maybe you are missing some MVC concepts, I would recommend you to read a bit more about routes and routelinks

I hope this helps you a bit: RouteLinks in MVC

8
fdomn-m On

'/WebConsole53/' // hardcode baseurl I have to apply each time manually

sometimes you need to access your root from javascript where you don't have access to server-side code (eg @Html). While refactoring may be the best option you can get around this by storing the baseurl once, using server-side code, eg in _layout.cshtml:

<head>
    <script type="text/javascript">
        var basePath = '@Url.Content("~")';  // includes trailing /
    </script>
    ... load other scripts after the above ...
</head>

you can then reference this everywhere and it will always be valid even if you move the base / migrate to test/live.

Setting window.location.href to load the new View from JavaScript // Is this the best way or should I use some URL/Html helpers instead?

Depends on your requirements - you could use $.ajax (or shortcuts $.get or $.load) to load PartialViews into specific areas on your page. There's plenty of examples on SO for this and the jquery api help.

Or just use <a> anchors or @Html.ActionLink as already suggested. Without needing menu= (see next) you don't need to control all your links.

I store the state of the selected menuItem in the querystring ("menu") // Is it more common to store that kind in Session/Cookie?

If you change the page, then you could query the current url to find which menu item points to it and highlight that one (ie set the menu dynamically rather than store it).

This would also cover the case where you user enters the url directly without the menu= part ... or where your forget to add this... not that that would happen :)

Additional: You can specify which layout to use in your view by specifying the Layout at the top of the view, eg:

@{
    Layout = "~/Views/Shared/AltLayout.cshtml";
}

(which is also one of the options when you right click Views and Add View in visual studio)

Without this, MVC uses a configuration-by-convention and looks at Views/_ViewStart.cshtml which specifies the default _layout.cshtml.

If you don't want a layout at all, then just return PartialView(); instead