views:

64

answers:

2

I have seen many questions raised around PartialViews and Javascript: the problem is a PartialView that requires Javascript, e.g. a view that renders a jqGrid:

The partial View needs a <div id="myGrid"></div> and then some script:

<script>
$(document).ready(function(){
   $('#myGrid').jqGrid( { // config params go here 
   });
}
</script>

The issue is how to include the PartialView without littering the page with inline tags and multiple $(document).ready tags.

We would also like to club the results from multiple RenderPartial calls into a single document.Ready() call.

And lastly we have the issue of the Javascript library files such as JQuery and JQGrid.js which should ideally be included at the bottom of the page (right before the $.ready block) and ideally only included when the appropriate PartialViews are used on the page.

In scouring the WWW it does not appear that anyone has solved this issue. A potential way might be to implement a custom View Engine. I was wondering if anyone had any alternative suggestions I may have missed?

+2  A: 

This is a good question and it is something my team struggled with when JQuery was first released. One colleague wrote a page base class that combined all of the document ready calls into one, but it was a complete waste of time and our client's money.

There is no need to combine the $(document).ready() calls into one as they will all be called, one after the other in the order that they appear on the page. this is due to the multi-cast delegate nature of the method and it won't have a significant affect on performance. You might find your page slightly more maintainable, but maintainability is seldom an issue with jQuery as it has such concise syntax.

Could you expand on the reasons for wanting to combine them? I find a lot of developers are perfectionists and want their markup to be absolutely perfect. Rather, I find that when it is good enough for the client, when it performs adequately and displays properly, then my time is better spent delivering the next requirement. I have wasted a lot of time in the past formatting HTML that no-one will ever look at.

Any script that you want to appear at the bottom of the page should go inside the ClientScriptManager.RegisterStartupScript Method as it renders at the bottom of the page.

http://msdn.microsoft.com/en-us/library/z9h4dk8y.aspx

Edit Just noticed that your question was specific to ASP.NET MVC. My answer is more of an ASP.NET answer but in terms of the rendered html, most of my comments are still relevant. Multiple document.ready functions are not a problem.

The standard jQuery approach is to write a single script that will add behaviour to multiple elements. So, add a class to the divs that you want to contain a grid and call a function on each one:

<script language="text/javascript">
     $(document).ready(function(){
         $('.myGridClass').each(function(){
               $(this).jqGrid( { 
                    // config params can be determined from 
                    //attributes added to the div element
                    var url = $(this).attr("data-url");

                });
          });
     }
</script>

You only need to add this script once on your page and in your partial views you just have:

   <div class="myGridClass" data-url="http://whatever-url-to-be-used"&gt;&lt;/div&gt;

Notice the data-url attribute. This is HTML5 syntax, which will fail HTML 4 validation. It will still work in HTML 4 browsers. It only matters if you have to run your pages through html validators. And I can see you already know about HTML5

Daniel Dyson
Thanks for the response. I like your idea of the custom attributes on the div. Main issue with your answer though is that a PartialView is not self-contained. It'll have some markup but that markup depends on another script elsewhere outside the view.
Francis Shanahan
True, but any approach that combines document ready functions into a single one would also require external dependencies to keep track of and combine the scripts. My guess is that you will not have very many grids on your page and that one script for each one will be sufficient, but not ideal. If you had a page with many controls then there would be a good argument for a single script. As with many things, there is no simple, easy answer. There will be a compromise between self-containment and readability of the markup. With regard to performance, you will have to perform your own tests.
Daniel Dyson
A: 

Not pretty but as regards your last point can you not send the appropriate tags as a ViewData dictionary in the action that returns the partial?

Doozer1979