Please turn on JavaScript. To find out how to do this visit the WebWise JavaScript guide.

This is a worked example of using a glow.widgets.Timetable and loading the Track and Item data into it from a remote source. The process is divided in to 6 steps.

  1. Identify the data source.
  2. Define a transform function to turn the source into Timetable specific data.
  3. Use glow.net to get the source data
  4. Use your transformer to turn it into the right format for a glow.widgets.Timetable constructor
  5. Create a glow.widgets.Timetable with your transformed data.
  6. draw() the Timetable

Identify the data source.

In this case we have grabbed some TV schedule data from the ION schedule. This comes in a very verbose JSON format (you can look at it at all.json), but, leaving only the bits we are interested in here, it look like this;

{
   /* ... */
   "blocklist" : [
      {
        /* ... */
         "emp_title" : "Leum is Danns: Episode 21",
         "service" : "bbc_alba",
         "end" : "2009-03-09T17:10:00",
         "service_title" : "BBC ALBA",
         "start" : "2009-03-09T17:00:00",
      },
      {
        /* more of the same */
      }
   ],
   /* ... */
}

It's worth noting that all the channels with programmes in this data are mixed up, so that each programme has all the channel info we need attached to it.

Define a transform function to turn the source into Timetable specific data.

This function will have several steps. First lets define the shell.

function process(netResponse) {
    var list = netResponse.json().blocklist;

    return {};
}

This gets the glow.net.Response data as a JSON object, and then accesses the blocklist property, which is an Array. It returns an object because we want to extract several peices of data from this response.

Next, we write a loop that goes through this array. The body of the loop looks like this;

thisService = list[i].service;
services[thisService] = services[thisService] || {title: list[i].service_title, programmes: []};

thisStart = makeDate(list[i].start);
thisEnd = makeDate(list[i].end);

programmes = services[list[i].service].programmes;
programmes[programmes.length] = [
    list[i].emp_title,
    thisStart,
    thisEnd
];

Because the programmes are in one big list, we need to separate them into channels ourselves. The first line of the loop creates (if not already created) an entry in the services collection, keyed on the channel ("service" in this data) code.

The remaining lines populate the programmes Array property of this entry with Arrays of properties suitable for passing to glow.widgets.Timetable.Track#addItem.

Note the makeDate function. This is necessary because the date format in the data is not suitable for creating a Javascript Date, so we need a function to do this transformation.

function makeDate(sDate) {
    var adjusted = sDate.replace(/^([0-9]{4})-([0-9]{2})-([0-9]{2}).([0-9]{2}):([0-9]{2}):([0-9]{2})$/,
                                 "$1/$2/$3 $4:$5:$6");

    return new Date(adjusted);
}

Next we transform the services collection in to an Array of Track data Arrays, each of which represents suitable arguments for passing to glow.widgets.Timetable#addTrack.

for(var id in services) {
    tracks[tracks.length] = [services[id].title, trackSize, {items: services[id].programmes}];
}

Finally we add the results to the return object.

return {
    tracks: tracks,
};

Putting it all together and fleshing it out a little (especially to extract the Timetable's start and end points and the view window), we get this;

function makeDate(sDate) {
    var adjusted = sDate.replace(/^([0-9]{4})-([0-9]{2})-([0-9]{2}).([0-9]{2}):([0-9]{2}):([0-9]{2})$/,
                                 "$1/$2/$3 $4:$5:$6");

    return new Date(adjusted);
}

function process(netResponse) {
    var list = netResponse.json().blocklist,
        i = list.length,
        services = {},
        programmes = null,
        latest = new Date(0),
        earliest = new Date("2099/12/31 23:59:59"),
        thisStart = null,
        thisEnd = null
        thisService = null;

    // grab required tracks and transform items
    while (i--) {
        thisService = list[i].service;
        services[thisService] = services[thisService] || {title: list[i].service_title, programmes: []};
        programmes = services[list[i].service].programmes;

        thisStart = makeDate(list[i].start);
        thisEnd = makeDate(list[i].end);

        // deduce required Timetable end points
        if(thisStart.valueOf()  latest.valueOf()) {
            latest = thisEnd;
        }

        programmes[programmes.length] = [
            list[i].emp_title,
            thisStart,
            thisEnd
        ];
    }

    // deduce required Timetable view points
    var viewStart = new Date(earliest.valueOf() + 3 * 60 * 60 * 1000),
        viewEnd = new Date(earliest.valueOf() + 6 * 60 * 60 * 1000),
        tracks = []
        trackSize = 155;

    // transform grabbed tracks
    for(var id in services) {
        tracks[tracks.length] = [services[id].title, trackSize, {items: services[id].programmes}];
    }

    // disable all tracks but the first 4. tracks[j][2] is the options object
    // this is so we have something that fits the page
    for(var j = 4, len = tracks.length; j 

Use glow.net to get the source data and Use your transformer to turn it into the right format for a glow.widgets.Timetable constructor

This bit is fairly straighforward glow.net.get call. The onLoad of the call is a function that calls our process function on the data before using it to create the Timetable.

glow.net.get("all.json", {onLoad: function (response) {
    var processed = process(response);
    /* create the Timetable */
}});

Create a glow.widgets.Timetable with your transformed data and draw() the Timetable

All that remains is to flesh out the onLoad with the code to create and draw the Timetable. Because we have processed all our data in to one set for passing as an option to the constructor, we can draw it straight away. So the extra code looks like this.

var myTimetable = new glow.widgets.Timetable("#remoteExample",
    processed.earliest, processed.latest,
    processed.viewStart, processed.viewEnd,
    {
        size: 600,
        tracks: processed.tracks,
    }
).setBanding("hour")
 .addScale("hour", "left", 83, {template: scaleMe})
 .addScrollbar("hour", "right", 50, {template: scaleMe})
 .setTrackHeaderTemplate("<h2>{title}</h2>")
 .draw();

Note that the scale and scrollbar templates are both defined as scaleMe. This is the following function, which simply gives a 12-hour clock hour only (eg "8am") from a given time.

function scaleMe(data) {
    var start = data.start,
        hours = Math.floor(start.valueOf() / 3600000) % 24,
        ampm = ["am", "pm"][Math.floor(hours / 12)],
        hh = ((hours - 24) % 12) + 12;

    return hh + ampm;
}

And finally...

Putting all the above together produces a result that looks like this (there is data in BBC Three, it's just further down...).

If you look at the source code of this page you will see that the code that produces this example, is exactly the code as given above.

What next?

This example has concentrated on the process of getting the Track and Item data from an external source. It could easily be enhanced with more programme data placed in the Item's data object and a nicer Item template to display it. Perhaps it could also use a glow.widgets.InfoPanel to give the user more information about an Item they have clicked on.

BBC © 2014 The BBC is not responsible for the content of external sites. Read more.

This page is best viewed in an up-to-date web browser with style sheets (CSS) enabled. While you will be able to view the content of this page in your current browser, you will not be able to get the full visual experience. Please consider upgrading your browser software or enabling style sheets (CSS) if you are able to do so.