Ask Kathleen

Visual Studio 2010 Tips: How to Use jQuery UI Controls in ASP.NET MVC 2

Dive a little deeper into how the jQuery script works and learn how to use the DatePicker control with ASP.NET MVC templates.



Q. I'd like to add a date-selection control to my ASP.NET MVC input form, but Model-View-Controller (MVC) doesn't have such a helper method. How do I add the control?

A. Unlike its sibling ASP.NET Web Forms, the MVC architecture doesn't provide stateful, server-side controls that you can drag and drop onto a design palette. Instead, MVC encourages use of simple HTML layout- and data-based tags for laying out the page. Rich functionality and final layout is added with client-side JavaScript and CSS style sheets.

MVC does supply a set of HtmlHelper-based extension methods to render most HTML tags. For more complex functionality, you need to write your own HTML/JavaScript, purchase a third-party MVC control package or use an open source JavaScript library. The most popular open source library today is jQuery. Visual Studio 2010 includes the jQuery core library when you create new MVC 2 projects.

The jQuery architecture adheres to the principles of "Unobtrusive JavaScript," which include the separation of HTML markup from the script that adds client-side behavior. Using this technique, developers create page layouts using simple <div>, <span> and <table> controls with class attributes. Data is displayed and collected using HTML list, anchor and form-based tags that have no attached JavaScript events. The resulting page is clean, easily displayed in any browser and lends itself to search bots like Google. A developer adds jQuery script to selected controls in the Document Object Model (DOM) and adds attributes, events and additional tags. This script creates a specific look and feel, responds to UI actions, performs animations and manages remote calls.

The jQuery library is subdivided into a core library and other plug-in libraries, including a collection of UI widgets. The core library provides selection, styling, DOM manipulation and AJAX functionality. The jQuery library can be extended by creating additional plug-ins. The jQuery UI is a set of plug-ins that includes many advanced behaviors such as dialogs, drag-and-drop and resizing, and themed widgets such as accordions, auto--complete fields, sliders, tabs and, of course, a date picker.

jQuery UI Plug-Ins
In order to use the UI library, you must first download it from the jQuery UI site. From the homepage, you can review the available themes using the Theme Gallery and then download a customized version of the library. When preparing your download, be sure to select the components you wish to use (the default is all of the components), which library version you want (generally you'll pick the most recent) and one of the preconfigured themes. Download the ZIP file to your computer and unzip it. Beneath this unzipped folder, you should see several folders, including CSS and JS.

Add the custom theme you downloaded to your project by copying the named style folder from the CSS directory to your MVC project's Content folder. Copy the custom jQuery UI script library from the js folder to your project's Scripts folder. I downloaded the latest version -- version 1.8.4 -- at the time of this writing. If you plan to deploy your project using Web Deployment Packages, be sure to add the style folder and JavaScript file to your Visual Studio project, or you'll find the application runs in your local environment but mysteriously fails in production.

The ASP.NET MVC architecture consists of -- unsurprisingly -- Models, Views and Controllers. Models are simply data classes that may be optionally decorated with DataAnnotation attributes. All URLS are translated into calls to a public method on a Controller. The Controller manipulates data passed to it and creates the data required by the View, and (indirectly) invokes the View. A View's primary job is to render the data created by the Controller. Views are similar to ASP.NET pages, but have no code behind. Views can be strongly typed, meaning they expect a control to set up a data object that's passed to them for rendering. This object is accessible throughout the view via a strongly typed Model variable. To make it easier to render form-based controls such as textboxes and radio buttons, Views use a set of HtmlHelper methods, accessed using a variable called Html. These extension methods have access to the Model data and the Metadata about the Model, usually based on DataAnnotation attributes placed on the Model class and fields.

Add the following script to the View page's Master Page (by default Site.master), substituting the name of the style you downloaded with your jQuery UI library for <your style here>. For my sample, I used the "redmond" style:

<link href="<%=Url.Content("~/Content/<your style here>
/jquery-ui-1.8.4.custom.css")%>" rel="stylesheet" type="text/
css" />
<script type="text/javascript" src="<%=Url.Content("~/Scripts/
jquery-1.4.1.min.js")%>" ></script>
<script type="text/javascript" src="<%=Url.Content("~/Scripts/
jquery-ui-1.8.4.custom.min.js")%>" >

Be sure the script tag for the jQuery core library -- in this case jquery-1.4.1.min.js -- appears before the tag to jQuery UI library, or you'll receive a scripting error similar to "'jQuery' is undefined" when you run your application.

To add the date picker calendar control to a View page, first use the HtmlHelper TextBox extension method to add a Textbox to the View, annotated with your choice of class name:

<%= Html.TextBox("TestDatePicker"
, Model.TestDatePicker.ToString("d"),
new { @class = "myDatePickerClass" })%>

All strongly typed View pages have access to a Model variable that represents an instance of a C# class and is passed to the View by a Controller. In this case, the Model references a class that contains a DateTime field called TestDatePicker. Note that this TextBox helper sets an initial formatted value for the TestDate-Picker field using the ToString() method. This is necessary because the jQuery DatePicker control applies its dateFormat option only after you select a date in the calendar control.

Next, add the following jQuery script to your Master Page. The class being searched for -- in this case myDatePickerClass -- must match the one added to the TextBox:

    <script type="text/javascript">
$(document).ready(
function () {
$(".myDatePickerClass ").datepicker({
buttonImage: '<%=Url.Content("~/Content/
images/calendar.gif")%>',
dateFormat: 'm/d/yy',
showOn: 'button',
buttonImageOnly: true
})
}
);
</script>

Open the page. When you click on the calendar icon to the right of the text box, you should see the calendar control in Figure 1. Selecting a date will populate the text field. You can also change the date in the text box, and that will be reflected in the calendar popup. Note that jQuery won't let you enter an invalid date in the text field.


[Click on image for larger view.]
Figure 1. You can heavily customize the date picker. Here the popup is configured to include a month and year drop-down at the top, resized to a smaller font and positioned to roughly the center of the text box.

It's worth diving a little deeper into how the jQuery script works. To add a script that runs when the browser loads a page, a function declaration is placed inside the jQuery ready() function. The ready() function guarantees that your function will run only after the entire DOM is loaded. Consistent with jQuery, the added function first looks for all tags with a class attribute of "myDatePickerClass." For each tag found in the search, jQuery calls the datepicker() method to add the calendar functionality.

The date picker recognizes almost 50 options to modify its behavior. These options include specifying the image to use for selecting the popup, the format of the date, whether the calendar pops up when you enter the text field or when you click an image anchor -- even whether or not you can change the date in the text field. For a complete list refer to the documentation on the jQuery site.

To modify the look and feel of all jQuery UI controls, you can use the ThemeRoller tool on the jQuery UI site. To override just the date picker style attributes, override the jQuery date picker styles using your own style sheet. Be sure to add the link to your custom sheet after the jQuery UI style sheet, or none of your overrides will show up in the control. As an example of the changes that are possible, you can make the calendar control smaller by adding the following to your CSS style sheet:

.ui-datepicker { font-size: 80%; }
Templated Helpers

Developers using the MVC architecture must create their own HTML for edit and display forms, often a tedious and error-prone task. A typical edit form contains multiple fields, each of which follows a pattern similar to:

<div class="editor-label">
<%= Html.LabelFor(m => m.TestDatePicker) %>
</div>
<div class="editor-field">
<%= Html.TextBoxFor(m => m.TestDate)%>
<%= Html.ValidationMessageFor(m => m.TestDatePicker) %>
</div>

In order to increase developer productivity, Visual Studio 2010 ASP.NET MVC 2 introduced strongly typed and templated helpers. Strongly typed helpers, whose names usually end in "For," use lambda expressions to provide compile time checking and IntelliSense. These helpers make heavy use of Data Annotation attributes placed on the Model class and fields to render proper labels and field names, and perform validation checks.

Templated helpers make it possible to render all the fields for an edit or display form for an entire object using a single extension method:

<%= Html.EditorForModel() %>

ASP.NET MVC 2 supplies a set of default templates used to render each field in a Model object based on its data type and Data-Annotation decorations. For the most part, these templates render reasonable HTML, but sometimes you want to customize what's rendered for a specific data type, all data classes or even a specific data class. ASP.NET MVC 2 provides an extension point that allows developers to override its default templates. You can take advantage of this feature to add a jQuery DatePicker to all DateTime fields.

To create a custom editor template for the DateTime type, first create the folder Views/Shared/EditorTemplates in your ASP.NET MVC project and add a partial View called DateTime.ascx. Add the following content to the partial view:

<%@ Control Language="C#" Inherits="System.Web.Mvc.
ViewUserControl<System.DateTime?>" %>
<% string formatString = ViewData.ModelMetadata.DisplayFormat-
String ?? "{0:d}"; %>
<% string displayString = String.Format(formatString, this.
Model); %>
<%=Html.TextBox("", displayString, new { @class = "myDatePick-
erClass" })%>

Whenever a templated helper method such as Html.EditorForModel() is called, ASP.NET MVC 2 will use this template to render all DateTime fields in the Model. The custom template in my example sets an initial formatted value for the TextBox either using a format specified on the Model's field using a DisplayFormat DataAnnotation attribute, or using a default display format.

Although ASP.NET MVC 2 doesn't make use of rich server-side controls like the Web Forms model, open source libraries such as jQuery UI can provide plug-ins that allow the same rich functionality in the browser with only a few lines of code.


About the Author

Doug Gregory, a consulting Enterprise Architect with Spitfire Group LLC, is a guest columnist for Kathleen Dollard this month. He explains how Visual Studio 2010 ASP.NET MVC 2 works with client-side behavior using jQuery, and shows you how to add a DatePicker control.

comments powered by Disqus

Featured

Subscribe on YouTube