0

I have two views nested one inside the other. The parent view has a treeview, each node of which is a link. When I click a node, the child view is changed accordingly(either the content of the child view or the child view itself is replaced with another one.) But this causes the treeview to collapse to its initial state. How could I prevent it from doing so? I'm aware of AJAX and have enough experience. But I have not used AJAX with MVC yet. A little help is greatly appreciated.

Mikayil Abdullayev
  • 12,117
  • 26
  • 122
  • 206
  • Are you using a plugin for the treeview –  Aug 15 '14 at 07:12
  • No, in fact it's a JavaScriptless treeview. It's pure CSS. – Mikayil Abdullayev Aug 15 '14 at 07:35
  • So you are actually rendering the full hierarchical structure? When you _click a node_, is that actually redirecting to another page or returning the view with additional child nodes rendered? –  Aug 15 '14 at 07:42
  • The full hierarchical structure is statically defined in the master view. When I click a node the same action method on the same controller is called with different parameters. So all the nodes in fact invoke the same action method which renders the child view. The cause for the problem is because each time the child view is rendered the master view is rendered as well, thus reloading the tree view. – Mikayil Abdullayev Aug 15 '14 at 11:09
  • 1
    I toyed with something similar some time ago. I my case I included additional view model properties to indicate the levels that should be expanded, and then when rendering the view in the loops, if the item ID matched the level ID, set a class on its child div element that made it visible. It worked in limited cases, but in the end I abandoned it and wrote my own plugin that used ajax for on demand populating of child nodes (easier, more flexible and far better performance) –  Aug 16 '14 at 00:20

1 Answers1

0

I finally found a very elegant and more than that, a built in way to do that. Yes, it indeed needs AJAX for that (how would it be done otherwise anyway?) Thanks Darin Dimitrov for his excellent answer I'm now able to do just what I need.

So as I said, I have a parent view where I have treeview with link nodes. With each click on the nodes a child view has to be reloaded. But this causes parent view to reload as well, which in turn causes the treeview to collapse. The first thing I did was to create a partial view strongly typed to that of the child view and move all the html content from child view to the newly created partial view. Then I replaced pure html with Razor for creating anchor elements. Before a tree node used to be like this:

<input type="checkbox" id="item-0" /><label for="item-0"><a href="/cabinet/inbox">Documents</a></label>

Now it's like this:

<input type="checkbox" id="item-0" /><label for="item-0">@Ajax.ActionLink("Documents(AJAX)","Inbox","Cabinet",new AjaxOptions{UpdateTargetId="partialViewContainer"})</label>

As you can see, the AJAX helper method creates the same link but this time also setting up the request to be asynchronous. What's beautiful with that is I don't have to mess with anything else to get AJAX working, everything is done behind the scenes. I just need to make sure that jquery.unobtrusive-ajax.js is included and unobstrusivejavascript is enabled in web.config, which is the default behavior. And of course, I need to have a container called partialViewContainer somewhere in the view to hold the partial view. (Notice the AjaxOptions{UpdateTargetId="partialViewContainer"}))

And finally, I needed to change the action method to return partial view instead of a normal one. Following is the only line I needed to change:

  public ActionResult Inbox(string docType){       
     ...........
     return PartialView("MyPartialView",myModel);
  }
Community
  • 1
  • 1
Mikayil Abdullayev
  • 12,117
  • 26
  • 122
  • 206