1

I have a scenario of buttons invoking Url.Action to different views. Upon loading the view, I want to set appropriate button (acting as tabs) to be selected. Setting the value in ViewBag and trying to retrieve it yields empty string.

The Layout page sets the value of selected button through AJAX call subsequent to which it is reloaded as

$(function () {
        var tab = "My Lists";
        $('#btnMyLists').click(function () {
            $.ajax({
                type: "POST",
                url: '@Url.Action("SetSelectedTab", "Home")',
                datatype: "json",
                data: { "tab": tab },
                success: function (response) {
                    window.location.href = '@Url.Action("MyLists", "AssocLists")';
                },
                error: function (errordata) {
                }
            });
        });
    });

I added a method to store the state of the selected tab in the ViewBag in Home Controller as

    [HttpPost]
    [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
    public ActionResult SetSelectedTab(string tab)
    {
        ViewBag.SelectedTab = tab;
        return new JsonResult { Data = new { Ok = true, message = string.Empty } };

    }

but seems like the retrieval of ViewBag variable seems to be happening prior to rendering of the view, which utilizes the Layout or I am unsure how to obtain the ViewBag variable to successfully set the selected class of the button.

$(function () {
        //DOES NOT WORK - EMPTY STRING
        var seltab = "@(ViewBag.SelectedTab)";
        if (seltab.length > 0 && seltab == "My Lists")
           $(btnMyLists).addClass('homepageHeaderButtonActive').siblings().removeClass('homepageHeaderButtonActive');
})
  • Is this code in a view (cshtml)? Where do you set `ViewBag.SelectedTab`? – Boris B. Aug 15 '13 at 16:21
  • Change `"@(ViewBag.SelectedTab)"` to use single quotes – NinjaNye Aug 15 '13 at 16:23
  • Yes, this is in Layout.cshtml. I tried setting the SelectedTab value in ViewBag by doing an AJAX post to the home controller. – biztalkdude Aug 15 '13 at 16:24
  • That should work. Note that the value of ViewBag must be set when the page is generated the first time. It appears that you are attempting to read the value after an ajax call. Unless you reload the entire page this wont work. If you need the tab to change on an ajax call, then the ajax response must provide details on which tab to show. – Kami Aug 15 '13 at 16:30

2 Answers2

0

It should be like this:

var seltab = "@ViewBag.SelectedTab";
ataravati
  • 8,891
  • 9
  • 57
  • 89
0

A ViewBag's lifetime is just for one request. When your SetSelectedTab action gets called you set ViewBag.SelectedTab, but as soon as the action finishes and JSON result is sent to the client the ViewBag is destroyed. On a next request the ViewBag is empty.

What you should do is make a hidden field (<input name="selectedTab" type="hidden"...)in the view, and when the selected tab changes you should set the value in the hidden field (on the client side, in JS). When that form is submitted to the server you then read the value from there and not from the ViewBag. Another option is to use a Session instead of a ViewBag, but I don't recommend it for such a simple scenario.

For more information on this you can check out the following SO question: What is the right time for ViewData, ViewBag, Session, TempData.

Community
  • 1
  • 1
Boris B.
  • 4,933
  • 1
  • 28
  • 59