Introduction
These are 2 free controls, ScheduleCalendar and ScheduleGeneral, designed
to show scheduled events in the form of a table. They are simple versions of the
so-called Gantt chart. They don't have advanced features such as dependencies
and milestones, but on the other hand, they allow you to provide either a lambda expression or a partial view for the content of the items,
so it's up to you, the developer, what you want to show.
The controls can be used for a broad variety of applications: time tables, resource
usage planners, calendars, event schedulers, activities, reservations, sequences,
project management, etc... See the demos for some examples.
The ScheduleCalendar control for instance will turn this data:
StartTime
| EndTime
| EventDate
| Task
|
9:00
| 11:00
| 3/8/2013
| History
|
9:00
| 10:00
| 3/9/2013
| Math
|
10:00
| 11:00
| 3/9/2013
| Biology
|
11:00
| 12:00
| 3/9/2013
| History
|
9:00
| 10:00
| 3/10/2013
| Geology
|
10:00
| 12:00
| 3/10/2013
| Math
|
9:00
| 10:00
| 3/11/2013
| Economy
|
10:00
| 12:00
| 3/11/2013
| Literature
|
9:00
| 12:00
| 3/12/2013
| Sports
|
9:00
| 11:00
| 3/15/2013
| History
|
9:00
| 10:00
| 3/16/2013
| Math
|
10:00
| 11:00
| 3/16/2013
| Biology
|
11:00
| 12:00
| 3/16/2013
| History
|
9:00
| 10:00
| 3/17/2013
| Geology
|
10:00
| 12:00
| 3/17/2013
| Math
|
9:00
| 10:00
| 3/18/2013
| Economy
|
10:00
| 12:00
| 3/18/2013
| Literature
|
9:00
| 12:00
| 3/19/2013
| Sports
|
into this presentation:
The other control is the ScheduleGeneral. Here you can provide
your own titles (you may think of people, resources or location names). Here's
an example with TV stations:
Automatically, overlapping events will cause extra rows or columns to be added to
the table, enabling them to be shown correctly.
Overlapping items:
The controls require at least ASP.NET
4.0 and MVC3. They come with a documentation file "documentation.chm".
Installation
Installing the controls
You can install the controls in the standard way:
- create a "bin" folder inside the application root of your website (if
it's not already there)
- copy the assembly file MvcSchedule.dll into the bin folder
A NuGet package is also available at https://www.nuget.org/packages/MvcSchedule.
Installing the demos
I added a Visual Studio project with a set of simple demo files.
Using the controls
Adding the controls to your page
Add these lines to the top of your page (Razor syntax):
@using MvcSchedule;
@using MvcSchedule.Objects;
Then, call the following Html helper where you want the schedule to be displayed:
C#
@Html.ScheduleCalendarFor(Model,
m => m.StartTime,
m => m.EndTime,
m => m.EventDate,
m => m.Task,
new MvcScheduleCalendarOptions {
Layout = LayoutEnum.Vertical,
ItemCss = "item"
},
t => ((DateTime)t).ToString("hh:mm"),
d => ((DateTime)d).ToString("dd/MM"))
VB.NET
@Html.ScheduleCalendarFor(Model,
Function(m) m.StartTime,
Function(m) m.EndTime,
Function(m) m.EventDate,
Function(m) m.Task,
new MvcScheduleCalendarOptions With {
.Layout = LayoutEnum.Vertical,
.ItemCss = "item"
},
Function(d) DirectCast(d,DateTime).ToString("hh:mm"),
Function(t) DirectCast(t,DateTime).ToString("dd/MM"))
Of course, for the general version, you use ScheduleGeneralFor
instead of ScheduleCalendarFor
.
The Model should be an IEnumerable type.
Data expressions
For each item on the schedule, the model should provide expressions providing
a start value, an end value, and custom data (typically a description of the task
or event). For the ScheduleCalendar control when TimeExpressionsContainDate==false
,
you also need a date expression. For the ScheduleGeneral control you also need a title
expression (for display on column/row headers).
You need to provide at least 3 lambda expressions with the Html helper call:
ScheduleCalendar:
StartTimeExpression
: the expression that yields the start of
the event for an item of the model
EndTimeExpression
: the expression that yields the end of the event
DateExpression
: the expression that yields the date of the event. This
expression should
produce a result of type "DateTime" (exception: when TimeExpressionsContainDate==true
this expression is ignored, see below). In a vertical layout, this expression will be used
for column titles. In a horizontal layout, it will be used for row titles.
ScheduleGeneral:
DataRangeStartExpression
: the expression that yields the start
of the event
DataRangeEndExpression
: the expression that yields the end of the event
TitleExpression
: the expression that provides the titles. You can think
of some useful fields for titles: people names, locations, classrooms, resources,
etc...) In a vertical layout, this expression will be used for column titles. In a horizontal
layout, it will be used for row titles.
1) and 2) can be thought of as time expressions, but in general, any type of sortable
expression (such as an integer) will do. Only when TimeExpressionsContainDate==true
for the ScheduleCalendar control, they should contain date and time information,
and when FullTimeScale=True
, they should contain at least time information.
Finally, you need to provide a way to display the content of the items themselves.
This can be done in two ways (depending on which overload of the Html helper that you use):
- By providing a
ItemDisplayExpression
: an expression that provides the content
displayed in the actual item.
- By providing the
ItemPartialViewName
: the name of a partial view that displays the item on the schedule.
This allows you to provide all kinds of rich content for the items.
Options
You can provide an optional parameter with all kinds of options. For the calendar control,
this is an MvcScheduleCalendarOptions object, for the general control, it's an
MvcScheduleGeneralOptions object.
Through the options you can set the css styles for the different parts of the schedules.
These are the styles:
GeneralCss
: the style class applied to the entire schedule table. ItemCss
: the style class applied to schedule items. AlternatingItemCss
: the style class applied to alternating schedule items. When null, the ItemCss is applied. RangeHeaderCss
: the style class applied to range header items. For calendars, use TimeCss
instead. TitleCss
: the style class applied to title items. For calendars, use DateCss
instead. BackgroundCss
: the style class applied to the background cells (cells with no content).
One important option is the FullTimeScale
property. When false (the
default value), only range values occurring in the model are shown. When true,
a continuous time scale is displayed (like the Outlook calendar). For the ScheduleGeneral
control, this requires the DataRangeStartExpression
and DataRangeEndExpression
expressions in the model to be of type DateTime.
The image below shows the the same item (Lunch from 12:30 to 13:30) in both cases:
FullTimeScale = false
12:30
|
Lunch from 12:30 to 13:30
| 13:30
| |
|
FullTimeScale = true and TimeScaleInterval = 15
12:30
|
Lunch from 12:30 to 13:30
| 12:45
| 13:00
| 13:15
| 13:30
| |
|
When FullTimeScale
is true, there are 3 additional options that
you can set:
TimeScaleInterval
: an integer value giving the number of minutes for
the interval (default=60) StartOfTimeScale
: a timespan value setting the start time of the time
scale (default=8:00) EndOfTimeScale
: a timespan value setting the end time of the time scale
(default=17:00). The highest value allowed here is 24:00 (midnight), which should
be entered as "1.00:00" (one day, zero hours and minutes).
Two other important options are IncludeEndValue
and ShowValueMarks
.
When IncludeEndValue
is true
, the row with the end value
will be included in the event. Sometimes, this will result in a more logical presentation.
However, when the items are adjacent (for instance: one event ends at 10:00 AM,
and another starts at the same time), it's better to set IncludeEndValue
to false
. Otherwise, the items will be shown as overlapping. In this
case, you can also set ShowValueMarks
to true
, which will
add marks indicating the values, and the values will be shown in the middle of the
item. The default value is false
for both.
The image below shows the the same item (Lunch from 12:30 to 13:30) in all cases:
IncludeEndvalue = False and ShowValueMarks = False
12:30
|
Lunch from 12:30 to 13:30
|
13:00
|
13:30
| |
14:00
| |
IncludeEndValue = True (ShowValueMarks is ignored)
12:30
|
Lunch from 12:30 to 13:30
|
13:00
|
13:30
|
14:00
| |
IncludeEndValue = False and ShowValueMarks = True
12:30
|
| |
|
Lunch from 12:30 to 13:30
|
13:00
|
|
|
13:30
|
|
| |
14:00
|
|
| |
For the ScheduleCalendar control, you can set these additional properties
on the MvcScheduleCalendarOptions parameter:
The ScheduleGeneral control has two additional properties on the
MvcScheduleGeneralOptions parameter:
AutoSortTitles
: When true, the titles are sorted automatically, even
when they are not sorted in the model. When false, you may provide your own
sorting order for the titles, but make sure that the items with the same titles
are grouped together, and that for each title, the items are sorted on DataRangeStartExpression
first and on DataRangeEndExpression next. The default value for AutoSortTitles
is true. SeparateDateHeader
: When true, an extra range of cells will be added
to group all events of the same date. This requires DataRangeStartExpression
and DataRangeEndExpression
to be of type DateTime
. The default
is false.
SeparateDateHeader=False
12/9/2013 14:00
| Task 1
| 12/9/2013 15:00
| 12/10/2013 14:00
| Task 2
| 12/10/2013 15:00
|
|
SeparateDateHeader=True
12/9/2013
| 14:00
| Task 1
| 15:00
| 12/10/2013
| 14:00
| Task 2
| 15:00
|
|
For both the ScheduleCalendar and ScheduleGeneral controls, you can easily switch
between a vertical or a horizontal layout with the Layout
property.
Providing formats
Apart from the expressions used to build the schedule, you can provide optional expressions
to indicate how to display the data.
For instance, you may use some DateTime property for the DataRangeStartExpression
, but you
could provide a DataRangeDisplayExpression
that formats this property in the short date format.
For the ScheduleGeneral control, these are:
DataRangeDisplayExpression
for displaying range start and range end values. TitleDisplayExpression
for displaying title values. DateHeaderDisplayExpression
for displaying date header values.
For the ScheduleCalendar control, these are:
TimeDisplayExpression
for displaying the time values. DateDisplayExpression
for displaying date values.
Demo pages
Download the demo pages for samples showing you how the Schedule controls could be
used. In each sample, you can set the properties with the help of a form and you
can add items. These samples use a SQL Server database as the data source.
- demo1.aspx shows a sample of a calendar. It also shows you how to delete
items with a linkbutton.
- demo2.aspx shows a sample of a task list. It also shows you how to edit and
delete items with a linkbutton.
- demo3.aspx shows a sample of a TV program schedule.
- demo4.aspx shows a sample of a calendar with items that span midnight.
How it works
I decided to use a table for displaying all the items, instead of graphics. Graphics
can put a heavy load on the server, and most importantly: a table can contain
partial views. By using partial views, a developer has full control over the content of the items.
I created a BaseSchedule object, which contains the code that is common for ScheduleGeneral
and ScheduleCalendar.
First, all the information is extracted from the model in order to create
lists for the row and column headers. Any double values are removed, and the remainder
is sorted in ascending order.
Next, an empty table object is built, with the correct number of rows and columns.
For simplicity, the table is always built in vertical layout, and only converted
to a horizontal web table later when necessary.
Then, the header items are added (row headers and column headers).
Next, the scheduled items are added to the body of the table. The most difficult
part is to calculate the position and span of each item, to merge the corresponding
cells, and to check whether items don't overlap.
Finally, the table object is converted into an html table.
Future
Here are some ideas for future improvement:
- Provide support for right-to-left languages
- Add dragging support for selecting a range (Outlook style)
- Support for recurring events
If anyone decides to extend these controls, or has any comments, bug reports or questions,
then it would be great to hear from you.
Points of interest
Update history
Release 1.0.0
First version
Downloads