If you haven’t yet seen the Calendar Component for ExtJs, you might well want to check it here first, and then see it in action (an example is below in this blog post, ExtJs example for Calendar component is here).

Although the Calendar component’s Pro edition is planned in February 2011, we have already started using the Pro features for one of our enterprise apps in a major way. And my first assignment for the Calendar component was making the available Calendars dynamic. A bit of a background to explain what I mean…

Multi Calendar SupportThe Calendar component supports multi-calendar feature. You actually pass-in 2 stores to the Calendar component, one specifying the available Calendars and the other with the events. Each event is associated to one Calendar and each Calendar can be assigned a Color. This color is used for rendering all events belonging to that Calendar (see the screenshot on the right for an example).

Now the Calendar component does not support dynamic Calendars (i.e. the ability of adding/removing/modifying Calendars, or changing a Calendar’s color-code) out-of-the-box. For our application, we needed to provide users with the ability to manage Calendars individually for each user.

Below is a simplified version of what I produced for my team (Click here to open the example in a new tab):

 

 

Click on the “Manage Calendars” button on the left bar to add/remove Calendars dynamically or change their color codes. Then try clicking on the Calendar surface to add/edit events for the newly added Calendars.

The following code is what is needed for the dynamic Calendar feature. I have modified the code to integrate easily with the official Calendar app example so that you can see the dynamic Calendar feature at work with the full power of the Calendar component. You can easily change the namespaces below to use for your application.

 

{syntaxhighlighter brush: jscript;fontsize: 100; first-line: 1; } App.calendarWindowMenu = new Ext.menu.Menu({
cls: ‘x-calendar-list-menu’,
items: [new Ext.ensible.cal.ColorPalette({
handler: function(palette, colorId) {
var record = App.calendarPanel.calendarStore.getAt(App.calendarWindowMenu.recordIndex);
record.set(‘ColorId’, colorId);
App.calendarWindowMenu.hide();
App.calendarWindowDataView.refreshNode(App.calendarWindowMenu.recordIndex);
}
}),
new Ext.menu.Item({
text: ‘Delete’,
iconCls: ‘no-icon’,
handler: function() {
Ext.Msg.confirm(‘Action confirmation’, ‘Please ensure no Event is associated to this Calendar. Continue with deletion?’,
function(btn) {
if (btn == ‘yes’) {
App.calendarPanel.calendarStore.removeAt(App.calendarWindowMenu.recordIndex);
}
});
}
})]
});

App.calendarWindow = new Ext.Window({
title: ‘Manage Calendars’,
width: 325,
height: 400,
modal: true,
layout: ‘fit’,
closeAction: ‘hide’,
bodyStyle: ‘background-color: white’,
items: [new Ext.DataView({
store: App.calendarPanel.calendarStore,
cls: ‘x-combo-list’,
style: ‘background-color: white; padding: 5px’,
itemSelector: ‘.x-combo-list-item’,
selectedClass: ‘x-combo-selected’,
overClass: ‘x-combo-selected’,
autoScroll: true,
tpl: new Ext.XTemplate(
‘<div>Click on a Calendar to change its color or remove it.</div>’,
‘<tpl for=”.”>’,
‘<div class=”x-combo-list-item” style=”vertical-align: middle”>’,
‘<div class=”x-cal-{ColorId}”>’,
‘<div class=”mail-calendar-cat-color ext-cal-picker-icon” onmouseover=”Ext.get(this).addClass(\’mail-calendar-cat-color-over\’);” onmouseout=”Ext.get(this).removeClass(\’mail-calendar-cat-color-over\’);”>&nbsp;</div>’,
‘</div>’,
‘<div>{Title}</div>’,
‘</div>’,
‘</tpl>’,
‘<div class=”x-clear”></div>’
),
multiSelect: false,
listeners: {
click: function(view, index, node, e) {
App.calendarWindowMenu.recordIndex = index;

App.calendarWindowMenu.show(Ext.get(node));
}
}
})],
buttons: [{ text: ‘Add Calendar’,
handler: function() {
Ext.Msg.prompt(‘Enter name’, ‘Enter calendar name:’,
function(btn, text) {
if (btn != ‘ok’)
return;

if (App.calendarPanel.calendarStore.findExact(‘Title’, text) != -1) {
Ext.Msg.alert(‘Invalid input’, ‘A Calendar with the same name already exists.’);
} else {
App.calendarPanel.calendarStore.loadData({ calendars: [{ title: text, color: 1}] }, true);
}
});
}
}, { text: ‘Save Changes’,
handler: function() {
Ext.Msg.alert(‘Save’, ‘Save changes to the Calendars on the server here.’);
App.calendarPanel.calendarStore.commitChanges();
App.calendarWindow.hide();
}
}, { text: ‘Cancel’,
handler: function() {
App.calendarPanel.calendarStore.rejectAllChanges();
App.calendarWindowDataView.refresh();
App.calendarWindow.hide();
}
}
]
});

App.calendarWindowDataView = App.calendarWindow.items.items[0];
});{/syntaxhighlighter}

 

 

The above code uses an Ext.DataView to display a list of available Calendars together with their current color. Most of the code above is boiler-plate ExtJs code, except choosing the color for the Calendar in a menu. I had to dig deep into the Calendar component framework to understand how it handles colors for the Calendars.

Calendar color paletteTo provide you some idea, the Calendar framework comes with a built-in support of 32 configurable colors for the Calendars. You can choose the colors via the ColorPalette available in Calender Pro. However, the built-in framework shows you ColorPalette inside a CalendarList component (the one in the left bar in the above example), and shows other options while choosing the color. Moreover, it only allows you to change color of an existing Calendar but does not allow you to add new Calendars.

The code above allows you to manipulate available Calendars dynamically providing options for adding/removing or changing colors for Calendars. As mentioned, the code renders the available Calendars in a DataView. Clicking any row of the DataView pops-up a Menu allowing you to change the color for the Calendar, or remove it altogether. You can easily add any desired MenuItem to the Menu to provide more custom options for any Calendar.

You can override the default available 32 colors for a Calendar (and the color palette) through css. Have a look at the “resources/css/calendar-colors.css” file in the Calendar package to know the css classes you need to override for changing the available colors.

 

Let me tell you another aspect of our application regarding the multi-calendar support. The Calendar component uses colors for events to distinguish between various types of events, and calls each type a Calendar (thus calling the whole concept multi-calendar support).

For our application, we instead call each type a Category. So, colors are used for distinguishing between the types of events on a single Calendar. We allow our users to open multiple Calendar instances in Tabs to provide a more real multi-calendar support, where users can manage Categories for each Calendar independently.

 

The code for the above example (html, css and javascript) is attached below. I would again like to acknowledge that I modified the Calendar test application that ships with the Calendar Pro version to create the example above.