A Dutch software developer living in Chile
# Friday, June 05, 2009
Adding some UI elements with jQuery to an MVC app

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:

  • Nullable dates (i.e. end dates) should be allowed with an empty text box
  • Not-nullable dates should default to the date of today
  • Multiple date pickers should be possible within the same form

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:

image

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.


Friday, June 05, 2009 5:03:17 PM (Pacific SA Standard Time, UTC-04:00)  #    Comments [0]  MVC | Programming