Closure: Extend ui.DatePicker to highlight events

I got a change to play with the new Google Closure Library a bit, and since the DatePicker component is pretty nice, i figured i could enhance it a bit to suit a need i had some time ago: overlay data from a database, highlight the dates that correspond to events, and jump to the event’s page when clicking on a highlighted cell.

Example page
Example script

Step 1: provide the JSON events in HTML:

1
2
3
4
5
var events = [
    {date: '2009-11-05', url: 'http://www.example.com'},
    {date: '2009-11-07', url: 'http://www.example.com'},
    {date: '2009-11-10', url: 'http://www.example.com'}
];

Step 2: extend goog.ui.DatePicker:

1
2
3
4
5
6
7
8
9
10
goog.provide('goog.ui.EventsDatePicker');
 
goog.require('goog.ui.DatePicker');
 
goog.ui.EventsDatePicker = function(opt_events, opt_date, opt_dateTimeSymbols) {
    goog.ui.DatePicker.call(this, opt_date, opt_dateTimeSymbols);
 
    this.events = opt_events;
};
goog.inherits(goog.ui.EventsDatePicker, goog.ui.DatePicker);

Notice how inheritance is handled with Closure. Even though we call goog.inherits(), we must also call the superclass constructor for it to work.

Step 3: highlight events:

goog.ui.DatePicker has a setDecorator() method, that accepts a function as it’s parameter. The function should take a Date object and return a CSS class name to decorate the corresponding cell with.

It’s basically called once for every cell in the picker, and we are going to use this by checking whether an event exists for the date and return “goog-date-picker-event” if so:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
goog.ui.EventsDatePicker = function(opt_events, opt_date, opt_dateTimeSymbols) {
    goog.ui.DatePicker.call(this, opt_date, opt_dateTimeSymbols);
 
    this.events = opt_events;
 
    // new line:
    this.setDecorator(this.eventDecorator);
};
goog.inherits(goog.ui.EventsDatePicker, goog.ui.DatePicker);
 
/**
 * Searches the events array and returns the event corresponding to passed date
 */
goog.ui.EventsDatePicker.prototype.findEventByDate = function (date) {
    var dateString = date.toIsoString(true);
    var event      = goog.array.find(this.events, function (event) { return event.date == dateString; });
 
    return event;
};
 
/**
 * Returns a CSS class name to use for cells that have events
 */
goog.ui.EventsDatePicker.prototype.eventDecorator = function (date) {
    var event = this.findEventByDate(date);    
 
    if (event !== null) {
        return 'goog-date-picker-event';
    }
};

Notice the use of goog.array.find() to find the event that matches the date.

Step 4: click events:

We will use the findEventByDate function defined above and DatePicker’s SELECT event to jump to an event’s URL when clicking on it’s date:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
goog.ui.EventsDatePicker = function(opt_events, opt_date, opt_dateTimeSymbols) {
    goog.ui.DatePicker.call(this, opt_date, opt_dateTimeSymbols);
    this.events = opt_events;
    this.setDecorator(this.eventDecorator);
 
    // new line:
    goog.events.listen(this, goog.ui.DatePicker.Events.SELECT, this.dateClicked, false, this);
};
/**
 * Checks if an event cell was clicked, and jumps to the event's URL if true
 */
goog.ui.EventsDatePicker.prototype.dateClicked = function (event) {
    var date  = event.date;
    var event = this.findEventByDate(date);
    if (event !== null && event.url != '') {
        document.location.href = event.url;
    }
};

That’s it :). It’s a short example, but it covers some of the basic aspects of inheritance, event listeners, and some of the utility methods. Closure looks nice :)

Example page
Example script

Comments

3 Responses to “Closure: Extend ui.DatePicker to highlight events”

  1. Filip
    on November 9th, 2009 08:15

    Nice one!
    Closure seems very verbose and namespacy, reminds me of YUI.

    Would you use it in production instead of Prototype+Scripta?

    Myself, I’m in love with jQuery… :)

  2. Victor Stanciu
    on November 9th, 2009 10:18

    Yes, it’s a lot closer to YUI than to Prototype / jQuery / etc. And like YUI, it’s actually a big library of components, not only a framework.

    Of course, most of the components are available separately for each framework, but because these are “built-in”, it’s a guarantee that all of them are easily extendable, are coded in the same manner, etc.

    I guess using it in production depends on the project, being so verbose means there is more code to write, maintain, and so on.

    For small projects, no discussion, any framework will get you the same results faster. For larger projects with a bigger codebase, the scalable nature of Closure could make it easier in the long run.

    Also, the Closure Compiler keeps file size small, and the tests i’ve run indicate that the bigger the initial file, the greater the percentage it’s size it’s reduced by.

  3. solomongaby
    on November 9th, 2009 18:36

    very nice example!
    Saved me the time to look more into how closure sintax looks like :D

    hope to see more closer reviews and examples :)

Leave a Reply