In ASP.Net MVC, how do you create widgets that put javascript and css, where should they go?

I am trying to create a reusable widget in ASP.Net MVC. This is a widget that combines 2 dates in a row. The widget contains 3 files: Widget.cshtml, Widget.css and Widget.js and dependencies on several jquery libraries.

Widget.cshtml

<h2>Create a date range</h2> <div> <label for="startDate">Start:</label> <input id="startDate" class="date" name="startDate" type="text" /> </div> <div> <label for="endDate">End:</label> <input id="endDate" class="date" name="endDate" type="text" /> </div> <p id="output"></p> <button id="createDateRange">Create</button> 

Widget.css

 label { color: #555;} 

Widget.js

 $(function () { $(".date").datepicker(); $("#createDateRange").click(function () { var start = $("#startDate").val(); var end = $("#endDate").val(); $("#output").html(start + " to " + end); }); }); 

I want to make this widget reusable on my MVC pages. I came up with several options, including:

  • Create HTML Helper
  • Renderpartial
  • Render action
  • Remove all css and javascript dependencies from the widget file. Manually copy and paste into each view that I use it in the right place.

I was about to use an assistant when I remembered Steve Suder's rules on website performance:

Rule 5: Put Style Sheets at the Top

Rule 6: Put Scripts Below

Options 1), 2) and 3) all look like good ideas, but they all write inline code and violate performance rules. Option 4) allows you to manually place javascript and css files where they belong, but copying and pasting are error prone. A potential idea would be to write a scaffolder that puts everything where it belongs, but right now it seems too much work.

What is the best (hopefully easy) way to make widgets and still follow performance rules 5 and 6?

+8
performance asp.net-mvc widget
source share
2 answers

You can use RenderSection () , which is similar to the old ContentPlaceHolder and puts them in _Layout.cshtml

  <head> <title>@ViewBag.Title</title> <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script> @RenderSection("head"); </head> 

Then in your view put:

 @{ ViewBag.Title = "Home Page"; } @section head { <link href="widget-style.css" type="text/css" rel="stylesheet" />< } <h2>@ViewBag.Message</h2> <p> To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>. </p> @section footer{ <script type="text/javascript" src="wiget.js"></script> } 

This is a simple alternative, if you do not want to use Combress or Chirpy, you still have to add code to the pages where you use the control, but it will appear in the right places.

I also found a handy blog post about registering scripts from a partial view that might be worth a read.

+2
source share
  • Modify your widget to use unobtrusive javascript methods so that the entire DOM can be scanned for instances of your widget. Rely on classes instead of identifiers.
  • Use a tool like Chirpy to pack all your CSS and Javascript files into one library file (one .js and one .css), which you can add at the top and bottom (respectively) of your main page / layout.
  • Use the HTML helper to create your HTML widget. If you like, the HTML helper can display a partial view to save the HTML view code in the view file. Since you are using unobtrusive javascript, there is no need to create any kind of script inline. Just let the widget's javascript code scan the DOM for instances of your widget.

Step 1

The original example already uses some unobtrusive javascript methods, but here you can extend this template even further, as shown in this jsfiddle .

Widget.cshtml

 <div class="date-range-widget"> <h2>Create a date range</h2> <div> <label for="startDate">Start:</label> <input id="startDate" class="date start-date" name="startDate" type="text" /> </div> <div> <label for="endDate">End:</label> <input id="endDate" class="date end-date" name="endDate" type="text" /> </div> <p class="output"></p> <button class="create-date-range">Create</button> </div> 

Widget.js

 $(function () { // This line could probably be done generally, regardless of whether you're // in the widget. $("input.date").datepicker(); $("div.date-range-widget").each(function(){ var $t = $(this); var startBox = $t.find("input.start-date"); var endBox = $t.find("input.end-date"); var output = $t.find("p.output"); $t.find("button.create-date-range").click(function () { output.html(startBox.val() + " to " + endBox.val()); }); }); }); 

Please note that now you have several instances of this widget on your page with different id and name values, and they will work independently of each other.

When there is no data range widget, javascript will still search for the DOM, will not find and will not jump. However, the cost of this operation is usually quite light compared to doing a separate round trip for another javascript file. Storing CSS and javascript in separate static files makes it possible for the browser to cache these files, which means that it spends less data on the browser on average (since only HTML changes from one request to the next).

Step 2

I personally found it appropriate to combine my javascript and CSS into one file, so the browser only needs to pull out one javascript and one css file for a given page load (and both will be cached after the first page loads). If you have a very large javascript file that is used only on certain pages, you may want to save it separately and upload only to certain pages.

Regardless, your javascript needs to be written so that you can simultaneously upload all javascript files to your site without stepping on each other's toes.

Step 3

It should be pretty clear.

+2
source share

All Articles