Mark Dalgleish

Mark Dalgleish

UI Engineer - Melbourne, Australia

Random Hacks of Kindness #3: One Week Later

RHoK #3 finished last Sunday and this week has been a busy week, I figured I’m overdue a rundown of how the weekend went and what I personally got out of it.

If you haven’t heard of the event before, according to the official RHoK website, “Random Hacks of Kindness is a community of innovation focused on developing practical open source solutions to disaster risk management and climate change adaptation challenges. Random Hacks of Kindness was founded in 2009 in partnership between Google, Microsoft, Yahoo!, NASA and the World Bank.”

One of my team members, Tony Milne, has already contributed a fantastic technical recap of the VicAlert/VicSafe projects on his blog so I won’t attempt to write a similar article. In fact, you should probably read his blog post before reading this one. Rather, this post will cover my personal experiences being part of Melbourne’s first RHoK event, which also happened to be my first hackathon.

Arriving at Swinburne Hawthorn’s wonderful Advanced Technologies Centre, a $140 million beacon of sustainable architecture housed in glass and metal, I felt dwarfed by the scale of the building around me, but equally welcomed by the friendly people working the front desk. After joining the other RHoKers in the auditorium, I wasted no time in opening up my laptop and connecting to the free wifi. Once the room started to fill up, we were given a briefing on how the day would commence and what to expect from the rest of the weekend.

Tables were arranged for the “four horsemen of the apocalypse”, as they were dubbed: fire, earthquake, flood and ‘general’. I, along with a couple of my fellow MelbJS attendees, @benjaminpearson and tonymilne, walked over to the ‘flood’ table and began the initial discussion on the problem definition we had seen on the RHoK website.

After speaking with Stefan Willoughby from the Bureau of Meteorology and, particularly after hearing from some people from the ABC who have dealt first-hand with disaster response through community radio, we quickly realised that the problem of getting relevant information to those in need during an emergency was much bigger than we initially expected. Needless to say, the scope of our work extended quite a bit and we found our project split in two: VicAlert, a central alerting API based on the Common Alerting Protocol, and VicSafe, a sample JavaScript application for consuming those alerts. VicSafe was targeted at solving the problem definition, which was giving people a visual indicator of the danger they were facing as flood waters were rising around them.

The work environment at a hackathon was something completely new and intimidating to me. Tasked with creating a solution over two caffeine-fueled days with a team of people you haven’t met before, especially when everybody’s skills might not entirely mesh, is quite a tall order. In fact, early into the first day we lost two of our team members due to differing technical backgrounds, leaving them feeling like they wouldn’t be able to make a worthwhile contribution.

Our project was mostly written in JavaScript, with the back end being written in Node.js. The front end was vanilla JavaScript interacting with the Google Maps API, with a healthy dose of jQuery/jQuery UI for interactivity and Socket.io for real time communication with the server. I became the de facto front end coordinator for VicSafe, ensuring that the disparate parts of code being created by myself and others on the team would coalesce into a usable whole. It must be said that such a working environment doesn’t result in the highest quality of code, but I suppose code quality is of a lower importance when your projects have to be done in what basically amounts to a single day of coding.

We coded through the day, winding down later in the night. To my surprise, at least in my case, the real breakthroughs seem to happen just as you’re getting ready to leave. On the bright side, upon returning the next morning, the development speed completely picked up and I found that a good night’s sleep did wonders for my mental clarity. With only hours until our code had to be presented to the other hackers, the final front end code and a decent amount of spit and polish created the presentation-ready version of VicSafe, which at this stage was interacting with the presentation-ready version of VicAlert using Socket.io.

Presenting to a crowd of 60+ developers was a daunting task. Public speaking isn’t something I normally have too much difficulty with, but talking to an auditorium of developers was a little more nerve wracking than I was expecting. Luckily @benjaminpearson did most of the presenting and he did a great job. The VicAlert/VicSafe presentation was very well-received and the slides are available now on SlideShare.

The projects created by all teams over the weekend were really impressive:

  • QuakeFelt: Android app/jQuery Mobile website that allows users to report earthquake intensity and building damage.
  • MyPlan: Website for creating a customised disaster response plan, with particular attention paid to preparing a medicine kit for those who require medication - “Prepare, Print, Survive”.
  • Bushfire Connect: Upgrades to usability of website and maps, particularly full screen maps and automatic geolocation.

The response for VicAlert/VicSafe was especially positive and, even though the focus of the event wasn’t on teams trying to win, the judges awarded our team with the top prize, saying that a centralised alerting system for Victoria has the potential to be a “game changer”.

One week on from the event and some positive things have come from this for me, personally. I’ve made some new friends, been able to work alongside existing friends for the first time, and I’ve been able to contribute to a project that has the potential to be a vital tool for all Victorians. We’re all still waiting with bated breath for the opportunity to present our proof of concept to those who will be able to give it the proper attention and funding to move the project forward. While what we created over the course of a single weekend was certainly a powerful reminder of what can be done when you put a group of experts in a room with a short time limit, the VicAlert and VicSafe projects merely scratch the surface of what needs to be done to turn this important idea into a reality.

In fact, shortly after the RHoK event, ABC published a story covering the VicAlert/VicSafe projects and recognising the potential for a future where the alerting systems were unified around a central platform.

I’d like to say a special thank you to @benjaminpearson, @tonymilne, @wolfeidau and @sivaone for making the weekend so enjoyable. You’re truly a smart bunch of people and I look forward to seeing what you guys have to contribute at RHoK #4.

The code for VicSafe is available on GitHub: github.com/wolfeidau/VicSafe.

Creating Highly Configurable jQuery Plugins

When writing jQuery plugins, you have many options for how you might structure your code.

Depending on the complexity of your plugin, you’ll probably want to allow users of your plugin to exert some level of control over how it operates. There are a few ways to do this, but I like to ensure that there are many ways even within a single plugin to allow the greatest level of flexibility.

Let’s start off with a basic and decidedly pointless plugin:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(function(window, $){
  var Plugin = function(elem){
      this.elem = elem;
      this.$elem = $(elem);
    };

  Plugin.prototype = {
    init: function() {
      this.displayMessage();
      return this;
    },
    displayMessage: function() {
      alert('Hello World!');
    }
  };

  $.fn.plugin = function() {
    return this.each(function() {
      new Plugin(this).init();
    });
  };

  window.Plugin = Plugin;
})(window, jQuery);

If the first and last lines look unfamiliar to you, the plugin is wrapped in a self-executing anonymous function.

One thing to note is that even in this basic example, we’ve already allowed for a couple of use cases. The plugin logic is not nested inside a jQuery plugin. The jQuery plugin merely allows for easy instantiation of the Plugin object. If the user of your plugin prefers, she might prefer to instantiate it manually by calling the following:

1
2
var elem = document.getElementById('elem'),
    p = new Plugin(elem).init();

Calling the plugin this way allows continued access to the innards of the plugin. This might allow the creation of a custom interface to your plugin, for example. The user of your plugin might like to trigger another alert, like so:

1
p.displayMessage();

Currently, the plugin is extra useless. Let’s make it a little less so by allowing the message to be customised.

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
31
32
33
(function(window, $){
  var Plugin = function(elem, options){
      this.elem = elem;
      this.$elem = $(elem);
      this.options = options;
    };

  Plugin.prototype = {
    defaults: {
      message: 'Hello world!'
    },
    init: function() {
      this.config = $.extend({}, this.defaults, this.options);

      this.displayMessage();

      return this;
    },
    displayMessage: function() {
      alert(this.config.message);
    }
  };

  Plugin.defaults = Plugin.prototype.defaults;

  $.fn.plugin = function(options) {
    return this.each(function() {
      new Plugin(this, options).init();
    });
  };

  window.Plugin = Plugin;
})(window, jQuery);

As you can see, we’ve introduced a set of defaults within the plugin and allowed it to be extended globally or using an object literal either of the following ways:

1
2
3
4
5
6
7
8
9
10
11
//Set the message per instance:
$('#elem').plugin({
  message: 'Goodbye World!'
});

var p = new Plugin(document.getElementById('elem'), {
  message: 'Goodbye World!'
}).init();

//Or, set the global default message:
Plugin.defaults.message = 'Goodbye World!';

This was due to the wonderful jQuery utility method called ‘extend’. Extending a set of object literals merges the contents of each into the object specified as the first argument. As is the case with our plugin, the first item should be an empty object literal if you don’t want to override anything.

But what if we want to customise the message displayed on a per-element basis? I admit, with this example it makes little sense, but bear with me. At present, the message can be set globally, or it can be set per collection of elements. But if the user of your plugin wanted to override it easily for a small subset of elements, they’re out of luck. Let’s change that:

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
31
32
33
34
(function(window, $){
  var Plugin = function(elem, options){
      this.elem = elem;
      this.$elem = $(elem);
      this.options = options;
      this.metadata = this.$elem.data('plugin-options');
    };

  Plugin.prototype = {
    defaults: {
      message: 'Hello world!'
    },
    init: function() {
      this.config = $.extend({}, this.defaults, this.options, this.metadata);

      this.displayMessage();

      return this;
    },
    displayMessage: function() {
      alert(this.config.message);
    }
  }

  Plugin.defaults = Plugin.prototype.defaults;

  $.fn.plugin = function(options) {
    return this.each(function() {
      new Plugin(this, options).init();
    });
  };

  window.Plugin = Plugin;
})(window, jQuery);

We’ve set the ‘metadata’ property by getting the HTML5 data attribute ‘data-plugin-options’. Now, you can customise the plugin on an element basis like so:

1
<div id="elem" data-plugin-options='{"message":"Goodbye World!"}'></div>

Notice the subtle change in the usage of single and double quotation marks.

Now our useless plugin can be setup and instantiated in a myriad of ways to suit the end users needs.

When designing a plugin, it’s important to allow users to interact with it in a way that negates the need to change the original source code. Opening up the number of was in which the default configuration can be changed is the first step in that process.

jQuery Selector for HTML5 Input Types

With HTML5 comes a new set of input types, including search and date types. The problem is that currently most of these are currently treated as textboxes and the following selectors won’t pick them up:

1
2
$('input[type=text]');
$('input:text');

Obviously, you could select just the type of input you like by substituting ‘input[type=text]’ with ‘input[type=search]’, but if you need to attach the same logic to all textbox-style HTML5 inputs, your selector will quickly get a little messy.

As a solution to this, I’ve created the following HTML5 input selector for jQuery called ‘:textall’.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// ':textall' jQuery pseudo-selector for all text input types
(function($) {
  var types = 'text search number email datetime datetime-local date '
        + 'month week time tel url color range'.split(' '),
      len = types.length;
  $.expr[':']['textall'] = function(elem) {
    var type = elem.getAttribute('type');
    for (var i = 0; i < len; i++) {
      if (type === types[i]) {
        return true;
      }
    }
    return false;
  };
})(jQuery);

With this you can easily select all input types listed in the ‘types’ array with one pseudo-selector.

1
$('input:textall');

Feel free to add or remove input types as necessary. Obviously you will get better performance by having less attributes to test. This also serves s a great blueprint for creating similar selectors for your projects.