One of the requirements that I have on an application that I’m working on is that the user can select a date easily when a textbox has focus. I wanted this to do in such a manner that programmatically this can be done with minimum effort, and that a few extra things are taken into account:
Ingredients
For this to work out, I’ve used the date picker control that’s available at http://jqueryui.com/ Besides that, I’m using ASP.Net MVC 1.0
Creating an extension method for System.Web.Mvc.ViewUserControl
For the view, I’m using an extension method that’s called “DateField”. This allows me to use the date field without having to use things like “RenderPartial” and creating custom models.
This class looks like this:
public static class ViewUserControlDateFieldExtension { public static string DateField(this IViewDataContainer control, string fieldName) { return DateField(control, fieldName, control.ViewData.Eval(fieldName) as DateTime?, false); } public static string DateField(this IViewDataContainer control, string fieldName, bool allowNulls) { return DateField(control, fieldName, control.ViewData.Eval(fieldName) as DateTime?, allowNulls); } public static string DateField(this IViewDataContainer control, string fieldName, DateTime? value) { return DateField(control, fieldName, value, false); } public static string DateField(this IViewDataContainer control, string fieldName, DateTime? value, bool allowNulls) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("<input type=\"text\" name=\"{0}\" value=\"{1}\" class=\"datepicker\" />", fieldName, GetFieldValue(control, value, allowNulls)); return sb.ToString(); } private static string GetFieldValue(IViewDataContainer control, DateTime? value, bool allowNulls) { if (allowNulls) { if (value.HasValue) return value.Value.ToString("dd-MM-yyyy"); else return String.Empty; } else { if (value.HasValue) { if (value.Value == DateTime.MinValue) return DateTime.Now.ToString("dd-MM-yyyy"); else return value.Value.ToString("dd-MM-yyyy"); } else return DateTime.Now.ToString("dd-MM-yyyy"); } } }
Next, adding some jQuery script
Adding the script to the master page is easy. Just a few <script> tags and that’s it.
<link href="/themes/redmond/ui.all.css" type="text/css" rel="Stylesheet" /> <script src="/Scripts/jquery-1.3.2.js" type="text/javascript"></script> <script src="/Scripts/ui/ui.core.js" type="text/javascript"></script> <script src="/Scripts/ui/ui.datepicker.js" type="text/javascript"></script> <script src="/Scripts/ui/i18n/ui.datepicker-nl.js" type="text/javascript"></script> <script type="text/javascript" language="javascript"> // Configure and add a date picker. $(function() { $(".datepicker").datepicker({ changeMonth: true, changeYear: true }); $(".datepicker").datepicker('option', { dateFormat: 'dd-mm-yy' }); $.datepicker.setDefaults($.extend({ showMonthAfterYear: false }, $.datepicker.regional['nl'])) }); </script>
Finally, use the class
Using the class is as easy as using this little line of code for a date field:
<% = this.DateField("EndDate", true) %>
The result looks like this:
The most nice part? It works in IE7, IE8, Opera, Chrome, FireFox and Safari.
UPDATE: Why use IViewDataContainer
I had a question from someone who wanted to know why I choose to extend IViewDataContainer in stead of WebControl/WebPage. The reason is simple. Both the System.Web.Mvc.ViewPage en System.Web.Mvc.ViewControl implement IViewDataContainer. This makes the interface the easiest target to implement.
© Copyright 2010 Jeroen Landheer Theme Design by Bryan Bell newtelligence dasBlog 2.3.9074.18820 | Page rendered at Monday, September 06, 2010 10:08:34 PM (Pacific SA Standard Time, UTC-04:00)