Click here to Skip to main content
Click here to Skip to main content

DayPilot - Building an Outlook-Like Calendar Component for ASP.NET

By , 26 Apr 2013
 

ASP.NET MVC Version 

June 25, 2012 - See also a follow-up article: AJAX Event Calendar (Scheduler) for ASP.NET MVC 3 in 80 Lines of Code. This article introduces a new DayPilot version for ASP.NET MVC which supports drag&drop AJAX operations (event moving, resizing, and creating). 

Building an Outlook-like calendar component for ASP.NET

The story is simple and you might have already heard it: I needed a component and because I wasn't able to find a good one I decided to write it. I was thinking like this: It would take me two hours to find it, another two hours to understand it and another two hours to customize it. Six hours. In six hours, I should be able to write a simple component by myself.

My project specification was simple.

Features

  • Reusable ASP.NET component for visually showing the events that happened during one day.
  • It must look like Outlook.
  • It must accept a DataTable with a specified structure as a data source.
  • User-defined JavaScript action for double-clicking the item.
  • User-defined JavaScript action for double-clicking the free time.
  • Support for working hours - doesn't show the time outside the working hours unless there is an event.
  • Support for events started before or finish after the current day.
  • Support for overlapping events (two or more events for a particular moment).

Features that are not supported

  • Drag and drop moving
  • Inline editing

In short, no AJAX at the moment. What I need is to show the events arranged and catch the most important events (clicking the event and clicking the free space).

Problem #1: Algorithm for arranging concurrent events

This didn't take too long. After the first hour I had the draft:

  • "Event" class will keep the basic information about the event, like starting and ending time, title, etc.
  • "Day" class will keep all the events for a certain day. It will be able to load the events from a DataTable. Each day can contain zero or more Blocks.
  • "Block" class will contain events that overlap with one another. Each Block contains one or more Columns.
  • "Column" class will contain all the events inside a Block that can be in a single Column.

Let's demonstrate it visually:

The algorithm can be described in the following steps:

  1. Shorten all the Events so that they don't overlap to another day (e.g. if something starts yesterday, let's make it start today at 00:00).
  2. Extend the Events' duration to 30 minutes blocks (we would have problems showing a duration of 5 minutes, 5 seconds - it wouldn't be possible to write any text into a rectangle of such a small height).
  3. Find Blocks:
    • Order all the events by the starting time (primary) and by the ending time in reverse (secondary) - longer events go closer to the left.
    • Iterate through the events - if it overlaps with the previous add it to the current Block; otherwise create a new Block.
  4. Arrange Events into Columns inside a Block (do this for each Block):
    • Find a moment with the most overlaps and count the overlaps. Create that many numbers of Columns.
    • Arrange Events into Columns - find the first free Column from the left and place it there.

Now, we can calculate the position of each Event because we know the Blocks and Columns:

  • Left: (the column number)/(total count of columns for the owner block) in percent.
  • Width: 1/(total count of columns) in percent
  • Top: (starting time)*(hour height)
  • Height: (duration)*(hour height)

Problem #2: Positioning the events using CSS

To show the calendar we need to draw a table with the hour numbers and yellow free cells and then draw another layer on top of the calendar that contains the events. The other "layer" can be created by setting the cascading style:

position: absolute;
top: 20px;
left: 20px;

The position is defined by the "top" and "left" coordinates. These are related to the upper left corner of the document or to the upper left corner of the containing element that has the position defined (if any).

Problem #3: Box size behavior in Firefox/Internet Explorer

The biggest problem while calculating the positions was a major difference between Firefox and Internet Explorer:

  • In Firefox, if you define the width and border (or padding, etc.) the total width of that box will be width + border. Firefox draws the border outside of the box.
  • In Internet Explorer, if you define the width and border the total width will be the width specified. Internet Explorer draws the borders inside the box.

To achieve the same behavior in IE and FF, I had to nest several DIV elements to create borders and padding. The resulting HTML of an event looks like this:

<div onselectstart="return false;" 
  onclick="event.cancelBubble=true;alert('Event ID: 4');"
  onmouseover="this.firstChild.style.backgroundColor='#DCDCDC';
              event.cancelBubble=true;" 
  onmouseout="this.firstChild.style.backgroundColor='white';
             event.cancelBubble=true;" 
  style="-moz-user-select:none;-khtml-user-select:none;
        user-select:none;cursor:pointer;cursor:hand;
        position:absolute;font-family:Tahoma;font-size:8pt;
        white-space:no-wrap;left:0%;top:1;width:100%;height:40;
        background-color:gray;">
    <div title="Breakfest (8:00 AM - 9:00 AM)" 
      style="margin-top:1px;display:block;height:38;
      background-color:white;border-left:1px solid gray;
      border-right:1px solid gray;overflow:hidden;">

        <div style="float:left;width:5px;height:100%;
             background-color:blue;">
        </div>
        <div style="float:left;width:2px;height:100%;"></div>
        <div style="padding:2px;">Breakfest (8:00 AM - 9:00 AM)
        </div>
    </div>
</div>

Problem #4: Firefox treated as a low-level browser

It is a known problem. The symptoms were that the HtmlWriter class that is used to render the HTML of the component automatically translates the DIV elements to TABLE elements and the STYLE attribute contents to (sometimes) the corresponding HTML attributes. This results in different appearance in Internet Explorer and in other browsers.

There are two possible solutions:

The first option was not possible because of the additional configuration required so I had to create several helper classes and write it directly as whole strings.

The final result

Finally, it took me a few days instead of a few hours but now you can share the result with me:

Updates

Please visit the DayPilot site for the updates.

History

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0

About the Author

Dan Letecky
Czech Republic Czech Republic
Member
My open-source AJAX controls:
 
DayPilot
DayPilot MVC
DayPilot Java
Outlook-Like Calendar/Scheduling Controls

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
Questionfree?memberKhinLLK24 Apr '07 - 23:47 
juz wanna know the code posted here can be used for free?
AnswerRe: free?memberDan Letecky25 Apr '07 - 2:08 
Yes.
 
--
My open-source ASP.NET 2.0 controls:
DayPilot - Outlook-like calendar/scheduling control
MenuPilot - Hover context menu

GeneralLicense questionmemberPhilBaker31 Jan '07 - 3:43 
Is this free to use in a public site?
GeneralRe: License questionmemberDan Letecky31 Jan '07 - 21:46 
Yes, provided that you link back to http://www.daypilot.org.
 
--
My sites for smart .NET developers:
DayPilot - Open-source Outlook-like calendar control for ASP.NET
DotLucene - The fastest open source fulltext search engine for .NET
MenuPilot - Open-source task menu for ASP.NET 2.0
Seekafile Server - Flexible open-source search server
DotNetFirebird

GeneralEvent FreeTimeClickmemberRoseville5 Jan '07 - 13:32 
Hi, My aspx page is getting postback but it is not calling Control_FreeTimeClick method of the event. Please advice
QuestionIs it possible to call Java Script FuntionmemberRoseville5 Jan '07 - 11:42 
Is it possible to call Custom JavaScript Funtion in the free event handler.
For E.g. Instead of "alert('{0}');" Can we call something like
setData('{0}');
 
function setData
{
....
}
GeneraloverlapswithmemberTommieKokkie18 Dec '06 - 10:44 
Hi,
In the method OverlapsWith in Block there is this statement:
return (this.BoxStart < e.BoxEnd && this.BoxEnd > e.Start);
 
I wonder if this is correct: should'nt e.start not be e.BoxStart?
 
best regards,
Tom

GeneralRe: overlapswithmemberDan Letecky18 Dec '06 - 11:56 
Yes, you're right. It's a typo. It will be fixed in DayPilot 2.1 SP3.
 
Thanks!
 
--
My sites for smart .NET developers:
DayPilot - Open-source Outlook-like calendar control for ASP.NET
DotLucene - The fastest open source fulltext search engine for .NET
MenuPilot - Open-source task menu for ASP.NET 2.0
Seekafile Server - Flexible open-source search server
DotNetFirebird

QuestionloadEventsToDaymemberTommieKokkie8 Dec '06 - 1:34 
Hi,
I experimenting a bit with the sourcecode of the project. I encountered a double call to the procedure loadEventsToDay, from Render and from PerformDataBinding. I don't think they are both nescessary. Is that correct?

 
best regards,
Tom

AnswerRe: loadEventsToDaymemberDan Letecky10 Dec '06 - 21:58 
Yes, you're right!
The call in Render is not necessary. I've removed it so it won't appear in the next release (2.1 SP3).
 

 
--
My sites for smart .NET developers:
DayPilot - Open-source Outlook-like calendar control for ASP.NET
DotLucene - The fastest open source fulltext search engine for .NET
MenuPilot - Open-source task menu for ASP.NET 2.0
Seekafile Server - Flexible open-source search server
DotNetFirebird

QuestionRefreshing DayPilot ControlmemberEnriqueSu17 Oct '06 - 5:21 
What is the best way to "refresh" a 5 day DayPilot Control v2.1(with SQLDatasource) when the user changes de workingweek to view? Can you help me? Regards...
 
Enrique Suarez
enrique.suarez@stiva.com

QuestionData binding &amp; integration with webcontrols.calendar [modified]memberEnriqueSu15 Sep '06 - 13:46 
Hi there!...your tools realy looks good and i am trying to use it in my web. I am a newbie...so the tutorial is not enough info for me in order to use a SQLDatabase/Table.
 
Do you have a code sample with SQLDabase as Datasource?
any chance with webcontrols.calendar integration too?
 
I hope you can help me.
 
Best Regards!!
 

-- modified at 10:24 Tuesday 19th September, 2006
 
Enrique Suarez / enriquesu@yahoo.com

AnswerRe: Data binding &amp; integration with webcontrols.calendarmemberDan Letecky2 Oct '06 - 20:58 
See WebControls.Calendar integration on daypilot.org.
 
If you mean SqlDataSource it will be supported in DayPilot 2.1.
 
--
My sites for smart .NET developers:
DayPilot - Open-source Outlook-like calendar control for ASP.NET
DotLucene - The fastest open source fulltext search engine for .NET
Seekafile Server - Flexible open-source search server
DotNetFirebird - Using Firebird SQL in .NET

QuestionHow about and "Enabled" style/property?memberSpotnick13 Sep '06 - 3:47 
I'm trying to see if DayPilot is able to do what I want it to do, and right now, the only feature I don't have is to be able to "hatch" an event that was flagged as "done" by my users.
 
This would be a nice feature, to be able to access the ItemDataBound and set the properties of the item, its style, etc, or to define a CssStyle for "Enabled = False", and one for "Enabled = True" for each event.
 
Cheers.
GeneralDayPilot 2.0.1 releasedmemberDan Letecky23 Jun '06 - 3:00 
This is a bugfix release. Read more in the release notes.
 
You can go directly to the download.
 
--
My sites for smart .NET developers:
DayPilot - Open-source Outlook-like calendar control for ASP.NET
DotLucene - The fastest open source fulltext search engine for .NET
Seekafile Server - Flexible open-source search server
DotNetFirebird - Using Firebird SQL in .NET

Questioneditingmembereighteenpinkpandas12 Jun '06 - 3:18 
hi!
 
this tool is very helpful! i'd just like to ask if you know of a method in which the selected area, may it be an event or a free time, can turn into an editable text box..
 
thanks! Big Grin | :-D
 

 
elisa
 
[no one can make you feel inferior without your consent -- e.roosevelt]
Generalappearancememberr.waymen11 Jun '06 - 21:56 
hey,
 
great job on this one! i'd just like to ask if there's any way that i could change the color scheme... i.e. i want to change it from the yellow theme to a blue one..
 
thanks in advance! Smile | :)
 
andrea
GeneralRe: appearancememberDan Letecky11 Jun '06 - 22:07 
Hi, This is planned for the release 2.1 that should come on 1 July 2006.
 
See the roadmap.
 
--
My sites for smart .NET developers:
DayPilot - Open-source Outlook-like calendar control for ASP.NET
DotLucene - The fastest open source fulltext search engine for .NET
Seekafile Server - Flexible open-source search server
DotNetFirebird - Using Firebird SQL in .NET

QuestionRe: appearancememberr.waymen11 Jun '06 - 23:25 
thanks for the fast reply! i hope you don't mind me asking another question..
 
is there a way to change the header date to .toLongDateString() format?
 
thanks again!Smile | :)
 
andrea
AnswerRe: appearancememberDan Letecky12 Jun '06 - 0:48 
Set the property HeaderDateFormat to "D".

 
--
My sites for smart .NET developers:
DayPilot - Open-source Outlook-like calendar control for ASP.NET
DotLucene - The fastest open source fulltext search engine for .NET
Seekafile Server - Flexible open-source search server
DotNetFirebird - Using Firebird SQL in .NET

AnswerRe: appearancememberDan Letecky12 Jun '06 - 6:08 
I've prepared a list of example header formats. See Choosing HeaderDateFormat - DateTime.ToString() parameters.
 
--
My sites for smart .NET developers:
DayPilot - Open-source Outlook-like calendar control for ASP.NET
DotLucene - The fastest open source fulltext search engine for .NET
Seekafile Server - Flexible open-source search server
DotNetFirebird - Using Firebird SQL in .NET

GeneralDayPilot 2.0 releasedmemberDan Letecky9 Jun '06 - 12:55 
What's new since 1.1:
 
- Multiple days can appear in one control
- Supports day headers (see new properties ShowHeader, HeaderHeight and HeaderDateFormat)
- API Change: Property "Date" is now replaced by "StartDate" and "EndDate"
- Hour height is now reducible down to 30 pixels without additional tweaking
 
Read more in the release notes.

 
--
My sites for smart .NET developers:
DayPilot - Open-source Outlook-like calendar control for ASP.NET
DotLucene - The fastest open source fulltext search engine for .NET
Seekafile Server - Flexible open-source search server
DotNetFirebird - Using Firebird SQL in .NET

GeneralEvents Renderer function in a wrong waymemberKeynan_d24 May '06 - 18:39 
Hi
I have an ASP page that was configure with the attribute dir="rtl" (right to left).
At the beginning when I got no event in the specific day everything was OK and the control was renderer in the right place.
When I add new event to the same specific day I got the following result:
The control was renderer in the right place BUT the event was renderer out of the control. Why?
 
Can you help me with this.
For debuging you can take the demo page : http://www.daypilot.org/demo
and put in the body tag the attribute dir="rtl"
 
Thanks
Danny
 
P.S. Great job
GeneralRe: Events Renderer function in a wrong waymemberDan Letecky9 Jun '06 - 12:53 
Thanks for reporting this. I need to investigate this issue.
 
--
My sites for smart .NET developers:
DayPilot - Open-source Outlook-like calendar control for ASP.NET
DotLucene - The fastest open source fulltext search engine for .NET
Seekafile Server - Flexible open-source search server
DotNetFirebird - Using Firebird SQL in .NET

GeneralDayPilot 2.0 Beta 1 releasedmemberDan Letecky14 May '06 - 4:11 
What's new:
 
- Multiple days can appear in one control
- API Change: Property "Date" is now replaced by "StartDate" and "EndDate"
- Hour height is now reducible down to 30 pixels without additional tweaking
- Events overlapping is fixed (http://blog.daypilot.org/2006/04/bugfix-for-events-overlapping.html)
 
Read more in the release notes.
 

 
--
My sites for smart .NET developers:
DayPilot - Open-source Outlook-like calendar control for ASP.NET
DotLucene - The fastest open source fulltext search engine for .NET
Seekafile Server - Flexible open-source search server
DotNetFirebird - Using Firebird SQL in .NET

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130523.1 | Last Updated 26 Apr 2013
Article Copyright 2005 by Dan Letecky
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid