One of the fundamental premises of ASP.NET is the “separation of concerns”. In ASP.NET WebForms Code and Markup go in separate files by default (.aspx / .aspx.cs). In ASP.NET MVC concern isolation is innate to the MVC convention. It therefore only makes sense to apply the same organizational construct to our use of JavaScript, especially as we federate more and more logic to the client side of our applications (meaning the browser.)

I’ve adopted  the practice of “Unobtrusive JavaScript” that appears below. FOr the sake of simplicity I’ve created this without using the standard WebForms template.

Lets suppose I have a page and I want to implement some jQuery / jQuery UI  features. Given this page …

I want to be able to drag & drop ….

And resize it ….

And I wanted to use jQuery UI features like a Pop-Up Calendar Picker.

To begin, lets look at the syte’s MasterPage :


<%@ Master Language='C#' AutoEventWireup='true'Inherits='Site' 
                         CodeFile='Site.master.cs' %>
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml'>
<head runat='server'>
    <title>jQuery UI wire-up sample</title>
    <link href='Content/themes/base/jquery.ui.all.css' rel='stylesheet' 
                                                       type='text/css' />
    <link href='Content/site.css' rel='stylesheet' type='text/css' />
    <asp:ContentPlaceHolder id='head' runat='server'>
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id='form1' runat='server'>
    <div>
        <asp:ContentPlaceHolder id='ContentPlaceHolderMain' runat='server'>        
        </asp:ContentPlaceHolder>
    </div>
    </form>
    <script src='Scripts/jquery-1.5.1.min.js' type='text/javascript'>
	</script>
    <script src='Scripts/jquery-ui-1.8.11.min.js' type='text/javascript'>
	</script>
    <asp:ContentPlaceHolder id='PageScriptPlaceHolder' runat='server'>
    </asp:ContentPlaceHolder>
</body>
</html>   

At the top of our MasterPage markup we include the jQuery UI CSS file and towards the bottom of the markup we include the jQuery and jQueryUI script files.

The positioning of these files is to increase page load performance. The CSS file is at the top since DOM objects will be using the CSS classes. The JavaScript code won’t be needed untill the page DOM is loaded.

Of particuar note in the MasterPage markup is the third ContentPlaceholder whos name id is “PageScriptHolder”.

The purpose of this place holder is so that we can create a page that derives from our master page and include script files that don’t need to be included on all the pages in our site that derive from that master page. (Meaning they will only be used on the specific page.)

Our Default.aspx page markuup is very clean.


<%@ Page Language='C#' MasterPageFile='~/Site.master' AutoEventWireup='true' 
                       CodeFile='Default.aspx.cs' Inherits='Sample' %>
<asp:Content runat='server' ContentPlaceHolderID='head'>
</asp:Content>
<asp:Content runat='server' ContentPlaceHolderID='ContentPlaceHolderMain'>
<br /><br />
<center>
    <div>
        <div>
            <asp:Label runat='server' AssociatedControlID='startDate'>
                 Start Date:
            </asp:Label>
            <asp:TextBox runat='server' ID='startDate' 
			                            data-ui-fn='datepicker' />
        </div>
        <br />
        <div>
            <asp:Label runat='server' AssociatedControlID='endDate'>
                 End Date:
            </asp:Label>
            <asp:TextBox runat='server' ID='endDate' 
			                            data-ui-fn='datepicker' />
        </div>
        <br />
        <div class='status-box' data-ui-fn='draggable resizable'>
            I'm a Drag and Droppable, resizable content area. 
			Move me, change me. 
        </div>
    </div>
</center>
</asp:Content>
<asp:Content ID='ScriptIncludes' runat='server' 
             ContentPlaceHolderID='PageScriptPlaceHolder'>

    <script src='Scripts/Default.js' type='text/javascript'></script>

</asp:Content>   

Note at the bottom where we pull in the Default.js JavaScript file. The naming convention is optional but makes things organized.

  • Default.aspx
  • Default.aspx,cs
  • Default.js

That file contains a clever bit of JavaScript that I orrigionaly got from Damian Edwards of the ASP.NET Team.


/// <reference path='jquery-1.5.1.js' />
/// <reference path='jquery-ui-1.8.11.js' />
$(function () {

    // Wire-up jQuery UI unobtrusively
    $('*[data-ui-fn]').each(function () {
        var $el = $(this);
        $.each($el.attr('data-ui-fn').split(' '), function () {
            ($el[this] || $.noop).call($el);
        });
    });
});     

This code itterates the page elements, finds elements with the custom attribute data-ui-fn and then apply the desired JavaScript / jQuery attribute:

ie:

<asp:TextBox runat='server' ID='startDate' data-ui-fn='datepicker' />

Clean and Simple.

You can download a working sample [ HERE ]