Using a DateTime Picker for ASP.NET MVC 5 with Bootstrap

.NET Musings

Wandering thoughts of a developer, architect, speaker, and trainer

NAVIGATION - SEARCH

Using a DateTime Picker for ASP.NET MVC 5 with Bootstrap

Background

I just released a new website for my home owner’s association (http://www.rdhoa.net) using ASP.NET MVC5 and Entity Framework 6.1. As you probably know, the new MVC websites starter template uses Bootstrap.  My site needed date pickers and time pickers, and I wanted to use one that worked well with Bootstrap.  Ironically, there are several that call themselves bootstrap.datepicker.  After much searching and testing, the one that I selected is Boostrap 3 Date Picker, located at http://eonasdan.github.io/bootstrap-datetimepicker/.

Getting the Files

This is the easiest part, since there are a host of ways to get the files.  There are detailed instructions for installing a number of ways for a variety of platforms.  As a .NET developer, I prefer NuGet, and installing couldn’t be easier. From package manager console, enter:

Install-Package Boostrap.v3.Datetimepicker (for the LESS version) or

Install-Package Bootstrap.v3.Datetimepicker.css (for the CSS version)

If you want to use the NuGet GUI, search for Bootstrap.v3.Datetimepicker.  (Make sure to select one of the ones created by Eonasdan.)  Here as well you can select either the LESS version or the CSS version.

SNAGHTML1649535a

Adding the files to your project

We first create a bundle for the files.  The DateTime Picker relies on Momentjs as well as Bootstrap.  Bootstrap is already in the default layout, so we only need to add moment* and bootstrap-,datetimepicker*, and make sure that the bundle is added before the bundle that adds boostrap to the layout.

Create the Bundle

Open BundleConfig.cs (located in the App_Start directory).  Add the following code:

bundles.Add(new ScriptBundle("~/bundles/datetime").Include(
    "~/Scripts/moment*",
    "~/Scripts/bootstrap-datetimepicker*"));

Update the Layout Page

Open _Layout.cshtml.  Update the code near the bottom of the page to look like this:

  @Scripts.Render("~/bundles/jquery")
  @Scripts.Render("~/bundles/bootstrap")
  @Scripts.Render("~/bundles/datetime")
  @RenderSection("scripts", required: false)
</body>
</html>

It’s important that the datetime bundle is placed after the bootstrap bundle. Notice the @RenderSection line.  This will be used in the next section.

Using the DateTime Picker in a Razor View

Since the DateTime Picker relies on Bootstrap (as well as Moment and the DateTime Picker JavaScript file itself), any calls must be placed after the bundles have been loaded.  To add the code to an MVC view, we must use the @section Razor directive to encapsulate the code. At the bottom of your view, add code similar to what is shown in the next listing.  The @section ensures that the encapsulated code is loaded in the area of the page that is defined by the @RenderSection directive in the layout page.

@section scripts {
    <script type="text/javascript">
  $(function () {
    $('#AnnualMeetingDate').datetimepicker({
      defaultDate: '@Model.AnnualMeetingDate',
      format: 'L',
      showClose: true,
      showClear: true,
      toolbarPlacement: 'top'
    });
    $('#AnnualMeetingStartTime').datetimepicker({
      defaultDate: '@Model.AnnualMeetingStartTime',
      format: 'LT',
      showClose: true,
      showClear: true,
      toolbarPlacement: 'top',
      stepping: 15
    });
  });
    </script>
}

The documentation for the DateTime picker and Momentjs formats is very good, so I won’t go through all of the options available. 

Updating the Html.EditorFor calls

We need to set the initial value of the textboxes, and to make sure there isn’t a jarring change when the JavaScript is executed, we want to make sure the value is shown in the same format as the format specified in the DateTime Picker code.  Adding the initial value is easy.  Add a @Value = Model.DateTimeProperty.CorrectFormat to the htmlAttributes code in the EditorFor line.

<div class="form-group">
    @Html.LabelFor(model => model.AnnualMeetingDate, 
        htmlAttributes: new { @class = "control-label col-md-3" })
    <div class="col-md-8">
        @Html.EditorFor(model => model.AnnualMeetingDate,
           new { htmlAttributes = new { 
             @Value = Model.AnnualMeetingDate.ToString("MM/dd/yyyy"), 
             @class = "form-control" }, })
           @Html.ValidationMessageFor(model => model.AnnualMeetingDate, "", new { @class = "text-danger" })
  </div>
</div>
<div class="form-group">
    @Html.LabelFor(model => model.AnnualMeetingStartTime, htmlAttributes: new { @class = "control-label col-md-3" })
    <div class="col-md-8">
        @Html.EditorFor(model => model.AnnualMeetingStartTime,
      new { htmlAttributes = new { 
               @Value = Model.AnnualMeetingStartTime.ToShortTimeString(), 
               @class = "form-control" } })
               @Html.ValidationMessageFor(model => model.AnnualMeetingStartTime, "", new { @class = "text-danger" })
  </div>
</div>

That’s it! The following two images shows the DateTime pickers in action with the options I have selected:

image

image

About the author

Philip Japikse

Philip JapikseA Principal Consultant/Architect with Strategic Data Systems (http://www.sds-consulting.com), international speaker, Microsoft MVP, ASPInsider, MCSD, CSM, and CSP, and a passionate member of the developer community, Phil Japikse has been working with .NET since the first betas, developing software for over 30 years, and heavily involved in the agile community since 2005. Phil is the Lead Director for the Cincinnati .NET User’s Group (www.cinnug.org) and the Cincinnati Software Architect Group, co-hosts the Hallway Conversations podcast (www.hallwayconversations.com), founded the Cincinnati Day of Agile (www.dayofagile.org), and volunteers for the National Ski Patrol. Phil enjoys to continuously learn new tech and is always striving to improving his craft. You can follow Phil on twitter via www.twitter.com/skimedic and read his blog at www.skimedic.com/blog, and see all of his connections at http://www.about.me/skimedic

Comments (1) -

All works for me great. Apart from if I add a locale then the calendar no longer pops up when I select the control.

Any ideas why this might be ?

Thanks

Comments are closed
Managed Windows Shared Hosting by OrcsWeb