I have a reusable component implemented as an MVC3 PartialView. The component includes jquery-ui widgets which need javascript initialization code to run. The following is a simplified example:
==== MySimplifiedPartialView.cshtml ====
<div id="myTabs">
<ul>
<li><a href="#myTabs-tab1">Tab 1</a></li>
<li><a href="#myTabs-tab2">Tab 2</a></li>
<li><a href="#myTabs-tab3">Tab 3</a></li>
<li><a href="#myTabs-tab4">Tab 4</a></li>
</ul>
<div id="myTabs-tab1">
...content
</div>
<div id="myTabs-tab2">
... content
</div>
... etc ...
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#myTabs").tabs();
});
</script>
When this PartialView is loaded into a page normally, the initialization code in $(document).ready is run and the widgets are initialized properly (in this case as jquery-ui tabs).
However I also want to be able to load this PartialView into the DOM dynamically, e.g. as the result of an AJAX request. What is the usual way to ensure the initialization code is run in this case? In ASP.NET WebForms apps, I would use an UpdatePanel, and achieve this by handling the load event, e.g.:
Sys.Application.add_load(function () {
$("#myTabs").tabs();
});
What is the equivalent in an MVC3 applications?
You have a couple of options. Easiest is often to include the script in the partial view:
tsegay also shows that you can do it during your ajax success event.
As a variation on the second option, since you are worried about encapsulation, is to initialize the javascript behaviors unobtrusively. For example:
You can then encapsulate the initialization into a common object like so:
There is some initial setup in the code above, but ultimately you can do this during your ajax success event:
The view doesn’t need to know that it has to call .tabs() on anything in the partial view, just that the partial has some unobtrusive UX behaviors. You can do the same thing with unobtrusive datepickers or other things that need initialized. All you would need is another $.extend section in the $.myApp object:
Another advantage of this is that you don’t need to do any initialization on your normal (non-partial) views. The $(function(){..}); at the end of the big script above takes care of that for you by calling $myApp.obtrude(document) when the script first loads into the browser.