DayPilot Knowledge Base

AJAX Calendar/Scheduling Controls
DayPilot Pro (AJAX Calendar Control)
» DayPilot AJAX Calendar
DayPilot Pro (AJAX Monthly Calendar Control)
» DayPilot AJAX Monthly Calendar
DayPilot Pro (AJAX Scheduler Control)
» DayPilot AJAX Scheduler
DayPilot » Knowledge Base » How to show one month per cell in Scheduler (CellDuration = Month)

How to show one month per cell in Scheduler (CellDuration = Month)

Last revision: Aug 17, 2010

Cell Duration

At this moment, all the cells used in DayPilot Scheduler muse have the same duration (horizontal axis). It is specified using CellDuration property (in minutes). That allows you to show wide range of scales - CellDuration can be anything from 1 minute to 10080 (one week).

However, it's difficult to show one month per cell because months don't have the same length (28-31 days). Until this is fully supported in DayPilot, you can use the following workaround.

Workaround for CellDuration = 1 Month

scheduler-year-by-months.png

One of the possible solutions is to use CellDuration=1440 (one day), Days=12 and map the Month part of the event start and end to the Day.

This is a sample for the read-only scenario. For a full drag&drop support you will need to do the conversion in the opposite direction in the event handlers such as EventMove, EventResize, and TimeRangeSelected.

ASPX

 <DayPilot:DayPilotScheduler 
        ID="DayPilotScheduler1" 
        runat="server" 
        DataStartField="start" 
        DataEndField="end" 
        DataTextField="name" 
        DataValueField="id" 
        DataResourceField="column" 
        DataTagFields="id, name"

        CellDuration="1440" 
        CellGroupBy="Year" 

        />

This is nothing special, just note CellDuration="1440" and CellGroupBy="Year" values.

C#

We need to update the start and end fields of the data source before to make sure that the Month value is copied to Day property and Day property is reset to 1.

This is an updated getData() method from Demo/Scheduler/Default.aspx.cs file:

    private DataTable getData(DateTime start, DateTime end, string filter)
    {
        String select;
        if (String.IsNullOrEmpty(filter))
        {
            select = String.Format("NOT (([end] <= '{0:s}') OR ([start] >= '{1:s}'))", start, end);
        }
        else
        {
            select = String.Format("NOT (([end] <= '{0:s}') OR ([start] >= '{1:s}')) and [name] like '%{2}%'", start, end, filter);
        }
        //throw new Exception(select); 

        DataRow[] rows = table.Select(select);
        DataTable filtered = table.Clone();
        foreach (DataRow r in rows)
        {
            filtered.ImportRow(r);
        }

        foreach (DataRow r in filtered.Rows)
        {
            r["start"] = monthToDayFloor((DateTime)r["start"]);
            r["end"] = monthToDayCeil((DateTime)r["end"]);
        }
        filtered.AcceptChanges();

        return filtered;
    }

The following lines do the trick, you need to call them for all records in your data set:

        foreach (DataRow r in filtered.Rows)
        {
            r["start"] = monthToDayFloor((DateTime)r["start"]);
            r["end"] = monthToDayCeil((DateTime)r["end"]);
        }
        filtered.AcceptChanges();

The actual conversion is done by these two helper methods:

    private DateTime monthToDayFloor(DateTime original)
    {
        return new DateTime(original.Year, 1, original.Month);
    }

    private DateTime monthToDayCeil(DateTime original)
    {
        return monthToDayFloor(original).AddDays(1);
    }

Whenever you need to map the dates back, you can use the following method:

    private DateTime dayToMonth(DateTime original)
    {
        int years = original.Day/12;
        int month = original.Day%12;
        return new DateTime(original.Year, month, 1).AddYears(years);
    }

For the read-only Scheduler, it only has to be used when limiting the SELECT to the visible range:

    private void setDataSourceAndBind()
    {
        // ensure that filter is loaded
        string filter = (string)DayPilotScheduler1.ClientState["filter"];
        DayPilotScheduler1.DataSource = getData(dayToMonth(DayPilotScheduler1.StartDate), dayToMonth(DayPilotScheduler1.EndDate), filter);
        DayPilotScheduler1.DataBind();
    }

Related

How to set the time cell colors using database data in the Scheduler
How to save the exported PNG image to a file (without a web page)
How to implement Copy & Paste in the Calendar
How to load Scheduler resource tree from a database (SQL Server)