Introducing React ReExt – Sencha Ext JS Components in React! LEARN MORE

A Peek Under the Hood at Ext Scheduler

May 19, 2011 189 Views
Show

Developing an interactive and flexible resource scheduler in Ext JS is a bit of a challenge since there is a lot of complexity hidden in this type of widget. Depending on the context in which it’s used, different requirements emerge. A decent scheduling tool should be able to show different time scales, allow for varying time resolution granularity, and visualize resource availability, just to mention a few. In a way, you could actually consider it to be more of a mini-application on its own rather than just a simple widget. Let’s take a peek under the hood of the Ext Scheduler.

Introducing Ext Scheduler

Before we start, let’s see what the Ext Scheduler looks like in action.

Ext Scheduler, built with Ext JS

As you can probably guess by looking at the screenshot, the scheduler is based on the popular GridPanel. All in all, the scheduler package consists of over 30 classes, but you mainly interact with the top level class, the SchedulerPanel. Since it inherits from GridPanel, you will find the setup and configuration very familiar, and you can use most of the GridPanel goodies such as cell editing, column resizing and so on. Although the grid only uses one data store for its rows, the scheduler uses two: a resourceStore (rows) and an eventStore (horizontal bars). These stores need to be configured in a certain way for the scheduler to work. The simple class diagram below shows some typical properties for these stores.

Ext Scheduler, built with Ext JS

In the resourceStore, you need to have a field named ID and in the eventStore, you need to have a field for “ResourceId” “StartDate” and “EndDate”. Each event in the eventStore belongs to a single resource through the ResourceId property. You can, of course, add any other metadata to your resource and event record definitions (as seen in the sample above).

Configuring the Time Scale

Getting data into the chart is essential but choosing a time granularity that makes sense is equally important. If you want to schedule meeting rooms, you will need a granularity of hours but if you run a vacation cabin rental business you probably want the schedule columns to show days or weeks. When configuring the scheduler, you control the column granularity by choosing the proper viewPreset. A view preset is a custom config object containing all the configurable properties relating to the schedule. Below, you can see an example of such a view preset:

hourAndDay : {
timeColumnWidth : 40, // Time column width, when locked columns are used
displayDateFormat : ‘G:i’, // Controls how dates will be displayed in tooltips etc
timeResolution : { // Dates will be snapped to this resolution
unit : “MINUTE”,
increment : 15
},
headerConfig : { // Definition of the header. You can define top, middle and bottom.
middle : { // “middle” object is mandatory
unit : “HOUR”,
dateFormat : ‘G:i’
},
top : {
unit : “DAY”,
dateFormat : ‘D d/m’
}
}
}

The scheduler comes with several predefined view presets that you can use:

  • “hourAndDay”
  • “dayAndWeek”
  • “weekAndDay”
  • “weekAndMonth”
  • “monthAndYear”
  • “year”

If none of these suits your needs, you can easily create your own view presets too.

A Simple Implementation

We now know how to feed data into the component, and how to define a useful viewPreset. All that’s left to do is to include some grid columns and a start and end date for the schedule:

// Set up the data stores used by the scheduler
var resourceStore = new Ext.data.JsonStore({
// config options
});
var eventStore = new Ext.data.JsonStore({
// config options
});
var scheduler = new Sch.SchedulerPanel({
loadMask : true,
columns : [
{header : ‘Staff’, width:130, dataIndex : ‘Name’}
],
renderTo : Ext.getBody(),

// A field name in the eventStore that will be rendered inside each event bar
eventBarTextField : ‘Name’,
// Schedule configuration, show one work day 8-5 PM
startDate : new Date(2011, 4, 1, 8),
endDate : new Date(2011, 4, 1, 17),
viewPreset: ‘hourAndDay’,

resourceStore : resourceStore,
eventStore : eventStore,
listeners : {
eventclick : function {
console.log(“You clicked a task, awesome!”);
}
}
});

Styling and Customizing the Event Bars

If you want to show more information than just simple text inside your rendered bars, you can easily do so by defining your own eventTemplate and eventRenderer. The eventTemplate is a standard Ext.Template that is used to render the content markup of each bar. The eventRenderer is a method which supplies the data to be applied to the event template (much like a standard grid column renderer function). Below you can see an example of how the custom template and renderer affects the look of the scheduled bars.

var scheduler = new Sch.SchedulerPanel({
eventBodyTemplate: new Ext.Template(

{headerText}

‘ +


),
eventRenderer: function (eventRecord, resourceRecord, tplData, row, col) {
// You can apply inline styles (through ‘style’ property),
// or set a CSS class on the bar element by using the ‘cls’ property
tplData.style = ‘background-color:’ + resourceRecord.get(‘Color’);
return {
headerText : eventRecord.get(‘StartDate’).format(“G:i”),
footerText: eventRecord.get(‘Title’)
};
},
});

Interacting with the Scheduler

Ext Scheduler, built with Ext JS Once you have your scheduler up and running, the fun begins. You can now drag and drop the task bars between rows, resize them and create new ones. As you are doing this, you can also validate the changes as they happen by overriding different validator functions. By using these validator functions, you can ensure that your developer Bob, for example, isn’t assigned a 22 hour non-stop task on Christmas Eve.

But What About…

This article is just a simple introduction to some of the features of the Ext Scheduler. There are lots more to explore if you visit the example section (link below). There, you can also check out Ext Gantt, which is an Ext JS Gantt chart component. If you are interested in keeping track of what is going on with these components, you can follow me on Twitter: @bryntum.

Additional Resources: