JavaScript Tutorial

In this tutorial we'll cover the basics of the JavaScript implementation in Hummingbird Lite.

One of the coolest features is the built-in object-oriented micro-framework that comes with your Hummingbird Lite instance. With it, you can build modern, modular JavaScript web applications, and, while it doesn't include some advanced functionality like routing, you may add it easily given the great flexibility of the framework.

So let's get started.

Meet the Class

Starting from version 3, Hummingbird Lite includes a modified version of the John Resig JavaScript inheritance implementation.

It defines a base Class object, which you can extend and infuse with new methods and properties, effectively providing an object-oriented foundation for your projects.

The Class object has four methods:

  • copy(object) - Allows deep copying (cloning) of objects.
  • inject(prop) - Allows method injection to the base class of a given object.
  • merge(original, extended) - Allows merging of two objects, deep copying its properties if required.
  • extend(prop) - Allows the inheritance of one object into another. This is the most important method of them all.

A very simple implementation uses only the extend method to define a base controller class for your site or application, and if you check out the site.js file on the assets/scripts folder of your Hummingbird Lite instance you can see it in action:

Site = Class.extend({
    init: function(options) {
        var obj = this,
            opts = _.defaults(options, {
                // Add options here
            });
        jQuery(document).ready(function($) {
            obj.onDomReady($);
        });
    },
    onDomReady: function($) {
        var obj = this;
        // Bind jQuery stuff here
    }
});

var site = new Site();

That is the base implementation, and as you can see, it's the simplest possible one.

It defines a new Site object, with the following methods:

  • init(options) - The constructor. Every Class-extended object has this method, it receives an options hash.
  • onDomReady(options) - This is the jQuery wrapping callback, when the jQuery(document).ready() event fires it triggers this callback. It's the place where should you place all your jQuery bindings and stuff.

So for example, if you want to listen to the click event of a button with class js-login, you would do it this way:

Site = Class.extend({
    init: function(options) {
        var obj = this,
            opts = _.defaults(options, {
                // Add options here
            });
        jQuery(document).ready(function($) {
            obj.onDomReady($);
        });
    },
    onDomReady: function($) {
        var obj = this;
        $('.js-login').on('click', function(e) {
            alert('Click on login button');
        });
    }
});

var site = new Site();

Basically, you put all your jQuery code inside the onDomReady callback.

The OOP approach allows you to define new methods on the Site object, for example, let's say that you want to encapsulate your login logic on a function instead of putting it on the click handler of the button you may do it this way:

Site = Class.extend({
    init: function(options) {
        var obj = this,
            opts = _.defaults(options, {
                // Add options here
            });
        jQuery(document).ready(function($) {
            obj.onDomReady($);
        });
    },
    onDomReady: function($) {
        var obj = this;
        $('.js-login').on('click', function(e) {
            var user = $('[name=user]').val(),
                password = $('[name=password]').val();
            obj.login(user, password);
        });
    },
    login: function(user, password) {
        if (user && password) {
            // Your login logic goes here
        } else {
            alert('Please enter your user name and password');
        }
    }
});

var site = new Site();

And that's only the beginning. You may create your own classes to implement a modular app for example:

// Define a base Module class
Module = Class.extend({
    name: '',
    init: function(options) {
        // This is the base constructor/initialization function
    }
});

// And extend (inherit) your modules from the base Module class
ModuleContact = Module.extend({
    email: null,
    init: function(options) {
        // Call the base constructor/initialization function
        this.parent();
        // Set own properties and values
        this.name = 'Contact us';
        this.email = 'contact@url-sample.com';
    },
    onDomReady: function() {
        var obj = this; // Save the value of the this pointer
        // Bind form.submit event
        // - Once the form is validated, you may call obj.send() to run your sending logic
    },
    send: function() {
        // Send logic
    }
});

From there, it's only matter of creating an instance of ModuleContact and calling its OnDomReady whenever you enter to the Contact page, you may even use a routing library for hash navigation to easily implement a SPA.

So, that's all for now. Now you have the basics for building advanced apps and websites with a clean and extensible JavaScript foundation.

Go back to previous page