Monthly MVC Calendar with Dropdown Navigation (jQuery, C# and VB.NET)

mvc-2-month-jquery-dropdown.png

Download

Prerequisites

Overview

This tutorial shows how to use the Month AJAX component from DayPilot Pro package in a simple ASP.NET MVC project.

  • The current month can be switched using a drop down (select box) with a limited list of months.
  • It preserves browser history by using a hash-style URL navigation.
  • It uses jQuery to glue the generic HTML <select> element with the Month view.

For the basic Month control setup, please see:

Installation

DLL

  • Put DayPilot.Mvc.dll in the bin directory of the web application.
  • Add it to project references if you are using a compiled web project.

Scripts

Include the following scripts in the web page (the scripts can be found in Scripts/DayPilot directory):

  • common.js
  • month.js

All the scripts are included in the site template (Views/Shared/_Layout.cshtml or Views/Shared/_Layout.vbhtml):

<head>
    <!-- ... -->
    <script src="@Url.Content("~/Scripts/DayPilot/common.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/DayPilot/month.js")" type="text/javascript"></script>
</head>

CSS Themes

Include the Content/DayPilot directory from the DayPilot demo project.

Include Content/DayPilot/themes.css stylesheet in the web page:

<head>
    <!-- ... -->
    <link href="@Url.Content("~/Content/DayPilot/themes.css")" rel="stylesheet" type="text/css" />
</head>

Setting Up the View

Place the Month control in the view using the following code:

C#

<%@ Import Namespace="DayPilot.Web.Mvc" %>
<%@ Import Namespace="DayPilot.Web.Mvc.Events.Month" %>

<div>
<%= Html.DayPilotMonth("dpm", new DayPilotMonthConfig {
                BackendUrl = ResolveUrl("~/Month/Backend"),
                EventMoveHandling = EventMoveHandlingType.CallBack,
                EventResizeHandling = EventResizeHandlingType.CallBack,
                TimeRangeSelectedHandling = TimeRangeSelectedHandlingType.CallBack,
                EventStartTime = false,
                EventEndTime = false
                
            })%>
</div>

VB.NET

<%@ Import Namespace="DayPilot.Web.Mvc.Enums" %>
<%@ Import Namespace="DayPilot.Web.Mvc.Events.Month" %>

<div>

        <%=Html.DayPilotMonth("dpm", New DayPilotMonthConfig With { _
                        .BackendUrl = ResolveUrl("~/Month/Backend"), _
                        .EventMoveHandling = EventMoveHandlingType.CallBack, _
                        .EventResizeHandling = EventResizeHandlingType.CallBack, _
                        .TimeRangeSelectedHandling = TimeRangeSelectedHandlingType.CallBack, _
                        .ContextMenu = "menu", _
                        .EventStartTime = False, _
                        .EventEndTime = False _
                       })%>
           
</div>

Adding the Drop Down List

Add a simple <select> element with pre-generated list of 15 months.

C#

<select id="dropdown">
<% for (var d = new DateTime(DateTime.Today.Year, DateTime.Today.Month, 1); d < DateTime.Today.AddMonths(15); d = d.AddMonths(1)) {%>
    <option value="<%= d.ToString("s") %>"><%= d.ToString("MMMM yyyy") %></option>
<%}%>
</select>

VB.NET

<select id="dropdown">
<%  Dim first As DateTime = New DateTime(DateTime.Today.Year, DateTime.Today.Month, 1)%>
<% For i As Integer = 0 to 15 %>
    <%  Dim d = first.AddMonths(i)%>
    <option value="<%= d.ToString("s") %>"><%= d.ToString("MMMM yyyy") %></option>
<%  Next%>        
</select>

Handling the Month Selection Change

Now bind the change event of the #dropdown element using jQuery.

Our handler will fire the Command event, with "navigate" as the command id and the selected date string as the start variable.

JavaScript

<script type="text/javascript">
$("#dropdown").change(function() {
    var selected = $(this).val();
    dpm.commandCallBack("navigate", {start: selected});
});
</script>

We need to add the Command handler on the server side (in the MonthController) and change the Month calendar date as requested. A full Update is necessary in order to redraw the Month control in full (and not just the event set).

C#

            protected override void OnCommand(CommandArgs e)
            {
                switch (e.Command)
                {
                    case "navigate":
                        DateTime start = (DateTime)e.Data["start"];
                        StartDate = start;
                        Update(CallBackUpdateType.Full);
                        break;
                }
            }

VB.NET

        Protected Overrides Sub OnCommand(ByVal e As DayPilot.Web.Mvc.Events.Month.CommandArgs)
            Select Case e.Command
                Case "navigate"
                    StartDate = e.Data("start")
                    Update(CallBackUpdateType.Full)
            End Select
        End Sub

Preserving the Browser Navigation History

We can extend the jQuery code a little bit to preserve the browser navigation history. The code we have at this moment does an inline change using AJAX calls. With a little more code it will be possible to return to the previously selected month using the back button.

First, we change the URL using the hash notation when changing the month.

<script type="text/javascript">
$("#dropdown").change(function() {
    var selected = $(this).val();
    window.location = "#" + selected; 
    dpm.commandCallBack("navigate", {start: selected});
});
</script>

We also need to check the URL for the selected month and preselect the correct value in the drop down list during the initial page load.

$(document).ready(function() {
    var hash = window.location.hash;
    hash = hash.replace("#", "");
    
    if ($("#dropdown option[value='" + hash + "']").size()) {
        $("#dropdown").val(hash);    
    }
    
});

The complete JavaScript code now looks like this:

<script type="text/javascript">

var useHash = true;
$(document).ready(function() {
    if (!useHash) {
        return;
    }
    var hash = window.location.hash;
    hash = hash.replace("#", "");
    
    if ($("#dropdown option[value='" + hash + "']").size()) {
        $("#dropdown").val(hash);    
    }
    
});
$("#dropdown").change(function() {
    var selected = $(this).val();
    if (useHash) { 
        window.location = "#" + selected; 
    }
    dpm.commandCallBack("navigate", {start: selected});
});
</script>