2

Is there a way to set which div the partial view is loaded into depending on which view is returned from the MVC action? For example an MVC controller action could return one of two views (View A or View B) depending on some logic. If 'View A' is returned then in the done function of the Ajax call load it into 'div A', but if 'View B' is returned then I load it into 'div B'.

public ActionResult SomeActionMethod()
{
    if (someCondition == true) {
        return PartialView("ViewA", new SomeModel());
    }
    else {
        return PartialView("ViewB", new AnotherModel());
    }
}
.done(function(data) {
    if (isViewA === true) { // How do I determine which view it is?
        $('#div-a').html(data);
    } else {
        $('#div-b').html(data);
    }
})

Is there an known/accepted way to do this (how to determine if it's View A or View B)? I've thought of two ways to do this but both seem a little hacky. If there is no commonly accepted/approved way of doing this then are the following ideas okay...

Idea 1:

Search returned html for a unique element or hidden input value only found in that view. This isn't as easy as it first sounds since the returned data isn’t just simple html but some sort of nested string/object (not really sure). For top level elements the jQuery 'filter' method needs to be used:

$(data).filter('#unique-element');

Otherwise the 'find' method should be used.

Idea 2:

In the controller action, for one of the views being returned (View A), set Response.StatusCode to a custom value in the 200's range that isn’t already used (not 200-208, 226). Then in the ajax done function specify all 3 parameters and check the third parameters status property to compare to the response status you set in the controller action.

if (someCondition == true) {
    Response.StatusCode = 299;
    return PartialView("ViewA", new SomeModel());
}
else {
    return PartialView("ViewB", new AnotherModel());
}
.done(function(data, textStatus, jqXHR) {
    if (jqXHR.status === 299) {
        // It’s View A so load it into div A
    }
    else {
        // It’s View B so load it into div B
    }
})

This works like a charm but seems even more hacky than Idea 1.

Dao Seeker
  • 214
  • 2
  • 11
  • 1
    One option is to return the view as a json (refer [this answer](http://stackoverflow.com/questions/4730777/mvc-return-partial-view-as-json)) so that you can return both the view and another value indicating which view it is so that you can use something like `if (data.ViewName == ??) { ...` –  Oct 07 '16 at 00:28
  • Can 'someCondition' be evaluated in your layout or view? If so, you could call `RenderAction` from the view and have two separate controllers. – Khyron Oct 07 '16 at 01:01
  • @Khyron If I understand want you've said correctly, then RenderAction will affect the view that's return in the Ajax call but not help me determine which div to load it into. – Dao Seeker Oct 07 '16 at 01:14

2 Answers2

0

I would suggest loading the content of each div separately. Eg:

Javascript

$('div-a').html(contentforA);
$('div-b').html(contentforB);

Controller

public ActionResult ContentA()
{
    if (someCondition)
    {
        return PartialView("ViewA", new SomeModel());
    }
    return new EmptyResult();
}

public ActionResult ContentB()
{
    if (!someCondition)
    {
        return PartialView("ViewB", new AnotherModel());
    }
    return new EmptyResult();
}
Khyron
  • 468
  • 3
  • 11
  • div A and div B already have content in them, so replacing both will mean one will get the EmptyResult which is no good. Especially since I want the one that doesn't get new content to not change at all. – Dao Seeker Oct 07 '16 at 05:52
  • In that case I would only replace each div's content if the respective contenforX was not empty. Eg: `if (contentforA) $('div-a').html(contentforA);` – Khyron Oct 09 '16 at 21:29
0

You can return PartialView and a parameter to determine which view you wanna render as a Json object :

public ActionResult LoadView()
{
   if (someCondition == true)
   {
      return Json(new { Url = Url.Action("PartialA",new SomeModel()), viewName = "PartialA"});
   }
   else
   {
      return Json(new { Url = Url.Action("PartialB", new AnotherModel()),
    viewName = "PartialB"});
   }
}

https://stackoverflow.com/a/10266520/6842997

And in the view, after you get result, you can do an ajax post;

$.post(result.Url, function (partial) {
       $('#div-a').html(partial);
});

Add PartialViewResults for each Partialview in the controller;

public PartialViewResult PartialA(SomeModel model)
{
    return PartialView();
}

public PartialViewResult PartialB(AnotherModel model)
{
    return PartialView();
}

then in your js, do something like this;

<input type="submit" onclick="load()" value="submit" />

function load() {
   $.ajax(
   {
      type: "POST",
      url: "@Url.Action("LoadView", "Home")",
      data: "", 
      success: function (result) {
          if (result.viewName == "PartialA") {
              $.post(result.Url, function (partial) {
                   $('#div-a').html(partial);
              });
           } else {
              $.post(result.Url, function (partial) {
                   $('#div-b').html(partial);
              });
           }
        }
      });
    }
Community
  • 1
  • 1
M.Kenis
  • 26
  • 1
  • 2