+1-888-365-2779
Try Now
More in this section
Categories
Bloggers
Blogs RSS feed

Group appointments by event categories in a custom Events Schedule View

by Radoslav Georgiev
This week's Tip of the Week post samples a custom Events Schedule View that allows us to group event items in the RadScheduler by the categories events belong to. For the purposes of this we will need to create a custom control that inherits from the built in Events Schedule View control and override some of its methods.

 

By default the RadScheduler control in the Events Schedule View is bound to an object data source. This object data source takes relevant event items from the Events Module and then feeds them to the Scheduler. However by design this does not allow us to group appointments in the scheduler by categories for example. So first thing that we have to do is to bind the RadScheduler to our custom data source object that will allow is to perform the desired. We have to start by creating the container that will hold the necessary information for the RadScheduler's appointments. Bellow is a sample class that does the required:

using System; 
using Telerik.Cms.Engine; 
using Telerik.Events; 
 
namespace Telerik.Samples.Events.DataSources 
    /// <summary> 
    /// This class is a container that will hold all necessary information  
    /// for appointment items - the event item from Events Module and its category ID 
    /// to allo grouping by categories 
    /// </summary> 
    public class AppointmentInfo 
    { 
        private string id; 
        private string subject; 
        private DateTime start; 
        private DateTime end; 
        private Guid categoryID; 
        private IEvent eventItem; 
 
        public string ID 
        { 
            get { return id; } 
            set { id = value; } 
        } 
        public string Subject 
        { 
            get { return subject; } 
            set { subject = value; } 
        } 
        public DateTime Start 
        { 
            get { return start; } 
            set { start = value; } 
        } 
        public DateTime End 
        { 
            get { return end; } 
            set { end = value; } 
        } 
        public Guid CategoryID 
        { 
            get { return categoryID; } 
            set { categoryID = value; } 
        } 
        public AppointmentInfo(IEvent eventItem) 
        { 
            this.eventItem = eventItem; 
            this.id = eventItem.ID.ToString(); 
            this.subject = eventItem.EventTitle; 
            this.start = eventItem.Start; 
            this.end = eventItem.End; 
            string categoryName = eventItem.ContentItem.GetMetaData("Category").ToString(); 
            if (categoryName != null
            { 
                Telerik.Cms.Engine.ContentManager manager = new ContentManager("Events"); 
                ICategory category = manager.GetCategory(categoryName); 
                if(category!=null
                    this.categoryID = category.ID; 
            } 
        } 
    } 
 

Once we are done with the container class it is time to start our custom control. As mentioned above the control will be derived from the built in Events Schedule View. We will have to override the InitializeControls method and point the Scheduler to our custom data source. In this same method we have to also create an object data source for our the categories form Events module. We can also make the Scheduler paint each appointment based on the category it belongs to. Sample code bellow:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using Telerik.Cms.Engine; 
using Telerik.Events; 
using Telerik.Events.WebControls; 
using Telerik.Samples.Events.DataSources; 
using Telerik.Web.UI; 
 
namespace Telerik.Samples.Events.WebControls 
 
    /// <summary> 
    /// Summary description for CustomScheduleView 
    /// </summary> 
    public class CustomScheduleView : EventsScheduleView 
    { 
        //our custom datasource for event items 
        private System.Collections.Generic.List<AppointmentInfo> appointments; 
        private EventsManager eventsManager; 
 
        [Browsable(true)] 
        [Category("Appearance")] 
        [Description("Gets or sets the path to a custom layout template for the control.")] 
        public override string  LayoutTemplatePath 
        { 
              get  
            {  
                 return "~/Sitefinity/ControlTemplates/Events/EventsScheduleView.ascx"
            } 
              set  
            {  
                base.LayoutTemplatePath = value; 
            } 
        } 
        
        protected override void InitializeControls(Control controlContainer) 
        { 
            if (Page == null || DesignMode) 
            { 
                Label noDesignModeLabel = new Label(); 
                noDesignModeLabel.Text = "The Events Schedule View control cannot be rendered in Design Mode"
                this.EventsSchedule.Visible = false
                this.Controls.Add(noDesignModeLabel); 
            } 
            else 
            { 
                if (base.CssFileLink1 != null
                { 
                    base.CssFileLink1.AssemblyInfo = base.AssemblyInfo; 
                } 
                //we have to bind the RadScheduler control to a custom data source that holds all necessary information 
                appointments = new List<AppointmentInfo>(); 
                this.eventsManager = new EventsManager("Events"); 
                foreach (IEvent _event in eventsManager.GetEvents()) 
                { 
                    if (_event.ContentItem.Status == Telerik.Cms.Engine.ContentStatus.Published) 
                        appointments.Add(new AppointmentInfo(_event)); 
                } 
                this.EventsSchedule.DataSource = appointments; 
                this.EventsSchedule.DataKeyField = "ID"
                this.EventsSchedule.DataSubjectField = "Subject"
                this.EventsSchedule.DataStartField = "Start"
                this.EventsSchedule.DataEndField = "End"
                this.EventsSchedule.AllowDelete = false
                this.EventsSchedule.AllowInsert = false
                this.EventsSchedule.AllowEdit = false
                this.EventsSchedule.AppointmentCreated += new Telerik.Web.UI.AppointmentCreatedEventHandler(EventsSchedule_AppointmentCreated); 
                 
                //create an object data source that will extract categories from the Events module 
                ObjectDataSource categoriesDataSource = new ObjectDataSource(); 
                categoriesDataSource.ID = "categoriesDataSource"
                categoriesDataSource.TypeName = "Telerik.Cms.Engine.ContentManager"
                categoriesDataSource.SelectMethod = "GetCategories"
                categoriesDataSource.ObjectCreating += new ObjectDataSourceObjectEventHandler(categoriesDataSource_ObjectCreating); 
                Controls.Add(categoriesDataSource); 
                ResourceType rt = new ResourceType("Category"); 
                rt.DataSource = categoriesDataSource; 
                rt.KeyField = "ID"
                rt.TextField = "CategoryName"
                rt.ForeignKeyField = "CategoryID"
                this.EventsSchedule.ResourceTypes.Add(rt); 
            } 
        } 
 
        void categoriesDataSource_ObjectCreating(object sender, ObjectDataSourceEventArgs e) 
        { 
            e.ObjectInstance = new ContentManager("Events"); 
        } 
        void EventsSchedule_AppointmentCreated(object sender, Telerik.Web.UI.AppointmentCreatedEventArgs e) 
        { 
            IEvent event2 = this.eventsManager.GetEvent(new Guid(e.Appointment.ID.ToString())); 
            HyperLink link = (HyperLink)e.Container.FindControl("eventDetailsLink"); 
            if (link != null
            { 
                link.Text = e.Appointment.Subject; 
                link.NavigateUrl = this.GetItemUrl(event2.ContentItem, this.SingleEventUrl); 
            } 
            string category = event2.ContentItem.GetMetaData("Category").ToString(); 
            //here you can style the appearance of each appoinment 
            //for simplicity we use builtin RadScheduler CSS classes 
            if(category!=null
                e.Appointment.CssClass= "rsCategory"+category; 
        } 
    } 

Now all we have to do is to modify the markup of the RadScheduler to set it to group appointments by category. For this we have to change the control template of our custom control. Above you can see that we are using this file - ~/Sitefinity/ControlTemplates/Events/EventsScheduleView.ascx for control template. Add the highlighted to the Scheduler markup:

<telerik:RadScheduler ID="eventsSchedule" runat="server" 
 SelectedView="TimelineView" GroupingDirection="Vertical" GroupBy="Category"
    <AppointmentTemplate>  
        <asp:HyperLink id="eventDetailsLink" runat="server" />  
   </AppointmentTemplate> 
</telerik:RadScheduler> 

Finally add the control to our Sitefinity toolbox. Add the bellow markup to the web.config:

<toolboxControls> 
    <clear/> 
        ... 
  <add name="Custom Schedule View" section="Custom Controls" type="Telerik.Samples.Events.WebControls.CustomScheduleView, App_Code"/> 
</toolboxControls> 

 

The above modifications will make the scheduler group events as in this image:

Custom Events Schedule View

You can take a look at the following articles in order to gain a better idea on how to style the Scheduler to make it look the way you want.

RadScheduler - Controlling Appearance

RadScheduler - Setting styles for appointments

You can download all the code that was sampled in this post from here:   Custom Schedule View

Leave a comment