Saturday, March 26, 2016

Limit Telerik's date and time pickers to working days and hours

Recently I was asked if we can limit date and time selection to working days and hours only. So I was hoping Telerik Rad Calendar simply allows to disable weekend days, and was looking for something like that:

dpDeliveryDate.Calendar.DisableWeekendDays = true;

However, there is no such feature in Rad Calendar. Instead, there is a much more generic feature called Special Days, which allows to control weekends, holidays, birthdays or any other special day.
Here is the code required to disable all Saturdays from now on:

            var day = new Telerik.Web.UI.RadCalendarDay();
            day.Repeatable = Telerik.Web.UI.Calendar.RecurringEvents.Week;
            day.IsDisabled = true;
            day.IsSelectable = false;
            var date = DateTime.Today.AddDays(DayOfWeek.Saturday - DateTime.Today.DayOfWeek);
            day.Date = date;
            dpDeliveryDate.Calendar.SpecialDays.Add(day);

As a Special Day is based on a specific date, this code does a little trick in order to get the date of the next Saturday. The code can be reused in order to disable the selection of Sundays as well. So this can be the final code:

        private void DisableDayOfWeekInCalendar(DayOfWeek dayOfWeek)
        {
            var day = new Telerik.Web.UI.RadCalendarDay();
            day.Repeatable = Telerik.Web.UI.Calendar.RecurringEvents.Week;
            day.IsDisabled = true;
            day.IsSelectable = false;
            var date = DateTime.Today.AddDays(dayOfWeek - DateTime.Today.DayOfWeek);
            day.Date = date;
            dpDeliveryDate.Calendar.SpecialDays.Add(day);
        }

         DisableDayOfWeekInCalendar(DayOfWeek.Saturday);
         DisableDayOfWeekInCalendar(DayOfWeek.Sunday);

This code is not enough if you want to deal with different cultures, which may have their weekend on other days of the week. This issue can be solved by getting user input. You could think that using the value

Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek

would solve this issue, but this value refers to the first day of the week in a calendar, not the first business day. For most cultures it would actually work, but not for en-US. So if this issue is relevant, user input is probably the best way to go.

Finally, limiting the time picker to working hours is very simple:

            radTimeDefaultValue.TimeView.StartTime = new TimeSpan(9, 0, 0);
            radTimeDefaultValue.TimeView.EndTime = new TimeSpan(17, 0, 0);

Working hours can also vary, and again, user input is probably the right way to handle it.