Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ASP.NET MVC Calendar by extending the HtmlHelper

0.00/5 (No votes)
24 Jul 2008 1  
You need a Calendar to show months or archive data or others, then you'd like this.

Introduction

Would you like a calendar in your ASP.NET MVC project?

Maybe you are looking froward to a calendar control that can embedded in your ASP.NET MVC project.

Maybe much more people suggest you try a javascript calendar to meet your requirements.

Maybe you were trying the <asp:Calendar ...> control but it need a form with runat="server" that is not so clean and easy to use with our MVC web.

...

And now, you can finish them exactly easy just use <%= Html.Calendar() %> in your view page!

Background

What is it ? / Features

I've just released the run time binary on my codeplex project, you can find it here: http://www.codeplex.com/mvcapps

The Mvc Calendar is extended the HtmlHelper so you can easily embed it in your View page of an ASP.NET MVC project.

It can generate a well-formed XHTML table and with some CSS classes by default. So you can customize it by customizing the CSS.

And also you can specify the SelectedDate property so the calendar shows the month you want to let it show.

If you want to show archive data on the calendar, You can supply an array with some DateTime objects to the calendar, then it'll calculate whether a day need a hyperlink because it contains some data like articles or blog posts on that day. You should also specify the controller name and action name to the calendar to make the links.

Using the code

Okay, let's get started on the code right now!

1. SIMPLEST CALENDAR

<%= Html.Calendar() %>        

Now you'll get a calendar show the current moth:

cal-4-simplest-view-styled.jpg

2. SPECIFY DATE

<%= Html.Calendar("otherCalendar", DateTime.Now.AddMonths(-1)) %> 

Then you'll get a different calender,

And you'll customize the CSS affected the calendar.

You could get one looks like:

cal-4-simplest-view-styled.jpg

3. WITH DATA

Now let me show you the advanced options.

<%
var allPosts = MvcCalendarSample.Models.Post.GetAllPosts(); 
var datesArray = from d in allPosts 
                 select new DateTime(d.CreatedAt.Ticks);
%>

<%= Html.Calendar("archiveCalendar", datesArray, "home", "archive") %> 

You'll get a calendar with some links which look like "/home/archive?date=2008-7" or "/home/archive?date=2008-7-12".

You can customize your routes:

routes.MapRoute("Archive","home/archive/{date}",new{controller="Home",action="Archive"});

Then you can get the url like: "/home/archive/2008-7", is it beautiful?

Please download the code sample to run it live!

4.Archive Calendar

But where do the links bring me to? the "/home/archive/2008-7"?

Of course you need an action there and a View too.

Let's have a look at the code:

In the /Views/Home/Archive.aspx file:

<h2>Mvc Calendar 4: with data and links and selected date</h2>
<%
    var selectedDate = DateTime.Parse(ViewData["date"].ToString());
    var allPosts = MvcCalendarSample.Models.Post.GetAllPosts();
    var datesArray = from d in allPosts
                     select new DateTime(d.CreatedAt.Ticks);
%>

<%= Html.Calendar("archiveCalendar", selectedDate, datesArray, "home", "archive") %>

<hr />

The Archive action:

        /// <summary>
        /// The archive view will hold the query string value
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public ActionResult Archive(string date)
        {
            DateTime selectedDate;

            if(!DateTime.TryParse(date,out selectedDate)) 
               return this.Content("param date is not in a valid DateTime format");
            
            //you can add your own date validation codes here

            ViewData["Title"] = "Archived Posts in " + date;
            ViewData["date"] = date;

            var allPosts = Post.GetAllPosts();
            var dateSplits = date.Split('-');

            var filteredPosts = new List<Post>();

            if (dateSplits.Length == 3)
            {
                //year-month-day format
                filteredPosts = (from p in allPosts
                                where p.CreatedAt.Year == selectedDate.Year &&
                                      p.CreatedAt.Month == selectedDate.Month &&
                                      p.CreatedAt.Day == selectedDate.Day
                                select p).ToList();

            }
            else if (dateSplits.Length == 2)
            {
                //year-month format
                filteredPosts = (from p in allPosts
                                 where p.CreatedAt.Year == selectedDate.Year && 
                                       p.CreatedAt.Month == selectedDate.Month
                                 select p).ToList();
            }


            ViewData["posts"] = filteredPosts;


            return View();
        }

Now you'll see we have the data on the view and then I'll drop the posts in the View page:

<h2>Archived posts in <%= ViewData["date"] %></h2>
<%
    var selectedPosts = ViewData["posts"] as List<MvcCalendarSample.Models.Post>;
%>
<p>Total <%= selectedPosts.Count%> posts in <%= ViewData["date"] %></p>

<% foreach (var post in selectedPosts)
   { %>
<p>[<%= post.CreatedAt %>] <a href="#"><%= post.Title %></a></p>
<%} %> 

Now you can see the page like:

cal-11-archive-view.jpg

The archive view calendar has finished.
Hope you 'll like this.

History

This is the first release.

Any comment must be my great thanks.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here