Category Archives: UX Development

Setting up Compass with or without Grunt

Setting up Compass wasn’t massively complex, but did involve a bit of thought. Mostly this thought was to get around the limitations imposed by my specific situation but I’ll recount them for anyone in a similar one.

To install SASS, and therefore Compass, you first need Ruby to be installed. Because the main language we use at work is Java I opted to use JRuby in case it became useful at some point in the future. Other people on the team just used Ruby and had no problems though.

Get Ruby

JRuby, however, did provide a problem. There is apparently a bug in it that means that when it is running in Ruby 1.9 mode, SASS doesn’t work. This is a problem with JRuby becuase Ruby 1.9 proper is fine. The solution was simple though, I just had to change JRuby to run in 1.8 mode. This was done by adding a new Environment Variable called JRUBY_OPTS with a value --1.8.

Bypass your proxy

With Ruby working, the next thing to do is to install SASS or Compass. Compass and SASS are both gems, which are packages of Ruby code which can be easily transported and installed.

Unfortunately, it requires some wrangling to install gems when you are behind a proxy like I am at work. Fortunately, it’s not that hard. I set an environment variable called http_proxy with the value proxy.myworkproxy.co.uk:myworkproxyport.

Install Compass

To install SASS go to the command line and type gem install sass. But also, don’t do that, because if you install Compass it brings SASS with it and Compass is better.

To install Compass, go to the command line and type gem update --system and then gem install compass. And with that, Compass is installed on your local machine.

You can then use the Compass watch command to start polling for changes to your SASS/SCSS files. There is a SASS watch command too, but if you really want to avoid compass I’m sure you’re capable of finding it yourself. You contrary kraken.

Set up Compass in a project without Grunt

With Compass installed on the machine, you still need to add it to any given project. The Compass website provides a tool for creating config options. You may find that useful, I found it more confusing than it needed to be. If you already have a project set up then use the command line to navigate to it and type compass install compass. If you are starting a new project using compass then go to the folder you want it with the command line and type compass create myProject. Probably not myProject though, call it whatever you want. Do that somewhere and take a look at what you get is my advice, after that the tool provided by Compass should become useful for guiding you through the set up. I’m not going to because I have barely used this method, preferring instead to use Grunt.

Set up Compass in a Grunt project

Let’s assume you have a Grunt project already set up. Installing Compass to your project is easy.

First, get Ruby, bypass any proxy you may need to and install Compass to your machine as described above. Then, in the command line navigate to the folder holding your Gruntfile and type npm install grunt-compass.

This installs grunt-compass, the grunt plugin for compass to your project. Npm stands for Node Package Module and is a similar concept to a Ruby Gem.

Then you need to add this line to your gruntfile
grunt.loadNpmTasks('grunt-compass');
This registers the newly installed node module to Grunt in your project. Compass is now installed to your Grunt project, but not doing anything. Let’s configure it.
Add something like this to your Grunt initConfig. I won’t go into massive detail about the configuration because the grunt-compass documentation is already good.

 compass: {
    src: 'sass',
    dest: 'css',
    forcecompile: true
    },

The three options we’ve set are src, which tells it where to find your SASS files and dest, which tells it where to put your css files. forcecompile is also pretty important for our purposes because we’re about to add Compass to the Grunt watch, which means we need to force it to compile and replace older versions of the css. There are many more options available but I’m not going to mess with them now.

To add compass to your watch in grunt go to the watch section in your Grunt initConfig, it should already be there and add path/to/scss/**/*.scss to the files and compass to the tasks. Like so

    watch: {
      files: 'scss/**/*.js ',
      tasks: 'compass lint'
    },

There we have it though, setting up Compass.

Advertisements
Tagged , , , ,

Grunt in the flesh

So last week I spoke about why Grunt is one of my favourite things. Today I’m going to cover how to bring Grunt into your life.

Setting up a grunt project

Grunt offers a variety of pre-made project set ups to save time when you create a new project. From what I understand about these things, they create a folder structure with some placeholder files for you to suit a selection of different project types. I’m sure these are all lovely and useful but I haven’t touched them. I’ve either wanted to construct my projects from scratch to get my head around the process or was adding grunt to pre-existing code.

Doing this means creating just a gruntfile. To do this, from the command line navigate to the folder you want it to be in and type grunt init:gruntfile. To use one of the others just change the gruntfile bit to something else. Just type grunt init to get a list of them.

grunt init:gruntfile

After issuing the command to create a gruntfile, it’ll ask you a load of questions. Answer them honestly or if you’re playing around, just go with the one in lower case when presenter with the Y/n choice. You’re not committing to anything forever here, just defining the start point for your gruntfile.

After this, it creates a single file called grunt.js (If you’re reading this from the future, then it might be called gruntfile.js). Let’s take a look at it.

module.exports = function(grunt) { is at the top of the file. Don’t touch it. It needs to be there, but you don’t need to do anything to it.

grunt.registerTask('default', 'lint test'); is at the bottom. This defines what happens if you just type grunt into your command line. Well actually, if you are using windows you’ll need to type grunt.cmd whenever I mention typing grunt after the initial creation of the file, I really mean type grunt.cmd in Windows. This is because of a naming conflict where typing grunt while you’re in a folder with a file called grunt, like the gruntfile, it’ll try to open that file instead. This is why future people will find their gruntfile called gruntfile.js.

But I digress, the second parameter of register task, lint test says it will run the lint and test tasks. More on those in a moment. You can define further tasks by adding lines like this:
grunt.registerTask('myTask', 'some tasks')
This can be called by typing grunt myTask into the command line. Tasks can be called directly without doing this by just typing grunt task into the command line, but this is a way to combine multiple tasks into a single command.

grunt.initConfig

This is the big one, near the top of the file an attribute of the grunt object called initConfig is defined. This is an object which contains all the config information for your tasks. Some tasks are built into grunt – lint and test are examples. Others can be added with plugins but I won’t be doing that here.

Any tasks can (and probably will if you’re using it) be listed as a property of grunt.initConfig like this

 grunt.initConfig({
    lint: {
      files: ['grunt.js', 'lib/**/*.js', 'test/**/*.js']
    },
    test: {
      files: ['test/**/*.js']
    },
    watch: {
      files: '',
      tasks: 'lint test'
    },
    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true
      }
 	}
 });
 

Lint and jshint are actually related to each other. Lint defines which files are looked at when the lint task is called, jshint configures jshint which is grunt’s linter of choice.

Test runs qunit tests if you’re into that sort of thing. I am not.

Watch is pretty magical. It defines files to watch and then tasks to run if any of them change. Watch is invoked by typing grunt watch into your command line.

An unfortunate fact of Grunt right now is it watches all the files listed and then runs all the tasks if any of them change, so here if I am watching CSS and JavaScript and I change a CSS file it’ll lint my JavaScript. Just in case. Apparently in the next major release of grunt different files can be watched for different tasks. I am excited about this and I imagine you future people are already enjoying it.

That’s the anatomy of grunt then, I’ll probably talk about it quite a lot in the coming weeks. Becuase it is amazing.

Tagged , , , ,

Automating with Grunt

Of all the new things from our new dev stack, Grunt is the one I find most exciting. Quoting from the website, Grunt is a task-based command line build tool for JavaScript projects. But what is that?

What is Grunt for

I can’t really think of a more succinct way to put it than that. Although when I first read it, it was pretty meaningless to me so let’s take it apart a bit.

Grunt is run from the command line, but doing so is not complicated so anyone unfamiliar with the command line need not panic.

It is used to run Tasks. What do I mean by tasks? Well, anything. Tasks can be defined and then run with Grunt, providing vast scope for automating repetitive actions in your work flow.

Finally, for JavaScript projects? Well, because it’s written in JavaScript it is best suited to tasks that affect JavaScript. But it already has many plugins for CSS and HTML based actions.

Why use Grunt?

With the addition of SASS and Require to our process we’ve added some complexity to our front end build process. Also, our old system was written in Java meaning it was oblique to members of the front end team or arduous to adjust.

Grunt solves all these problems beautifully. We can use it to automatically compile our SCSS into CSS as we’re working. We can use it to automatically run our suite of JavaScript tests and JS Hint as we are working and we can use it to run the require optimizer to bundle our JavaScript up (say it with me now) as we are working. These things alone were enough to make me fall in love. Boiling all the complexity we introduced by adding new tools to our Dev Stack down to one solution.

However, the goodness continues! Grunt is a Node module, so is written in JavaScript. Our team makes a distinction between front end developers and back end developers. We front end types are reliably confident with JavaScript, HTML and CSS but not necessarily any other language. This means that our Front End Build solution can now be placed into the hands of the front end development team.

We’re not done yet though! Grunt has an active community of plugin developers creating more and more tools we can easily include just by adding it to Grunt. In addition to the ones listed above, we’ve already got one which can base-64 encode images into our CSS to reduce requests on the mobile site and we’ve barely started looking.

A caveat

For all my love and excitement about Grunt it does present a problem to us. The machines we’re using for our CI, running our tests and build process on the repository whenever anyone checks in are currently unable to run it. In the future we’re planning to add it, but right now we’re only using it on our local machines. More on using Grunt in a CI in the future. Presumably.

Tagged , , , , ,

Removing Backbone from Mobile

This week we established a few depressing things.

  1. The mobile site is going to have to support IE because Windows Phones use it.
  2. Zepto doesn’t just not support old IE, it doesn’t work on IE9 and 10 either. This means we can’t rely on it on Mobile.
  3. Backbone depends on jQuery/Zepto more than we thought.

For the mobile site, we are acutely aware of code efficiency and file size. For this reason we are unwilling to include jQuery on it. This has created a spiral of difficulties for us though this week.

Backbone needs jQuery or Zepto’s document ready function to use Routers. We tried a few home-written alternatives and none of them worked. This wasn’t a huge disaster though because we were already having some difficulty with the Router. Because we weren’t using it entirely as intended – just using it to detect which page we were on and run the relevant script we were finding issues. We are not using it to produce a One Page App. Our architecture still involves speaking to the server through Query Parameters, which the Router was not great at handling. So we came to accept that we were going to have to get rid of the Router.

In doing this, we removed Zepto from the page we were working on and found that this broke our Backbone View. With a little digging we established that the View was indeed using Zepto. It makes sense really, we were perhaps a little naive to think otherwise. Backbone uses a very similar syntax to jQuery for binding events, why wouldn’t it use it?

As an interesting aside, Zepto was not being listed as a dependency to require by the View, but it was being loaded into the page. This meant that our require module had acquired a silent dependency on it. This isn’t wholly surprising but I suspect we’ll do well to remember this is possible in the future.

Losing Views was a more serious issue. Without Views, Backbone wasn’t really adding all that much to our app. Between it and Lo dash, we were adding about 8kb to our javascript bundle, but for what gain?

We saw three reasonable responses to this

  1. Provide a fallback, so users on IE would download jQuery to replace Zepto. This would make our lives easy but really destroy the experience for Windows Phone users
  2. Create a custom jQuery build with just the bits Backbone needed and hope it was reasonably sized
  3. Remove Backbone from the mobile site

Falling back to jQuery

This was lazy-me’s favourite solution, but clearly we weren’t going to do this. Even Windows Phone users deserve to use the site in a reasonable way.

Creating a Custom jQuery

We didn’t look deeply into this. I created a custom jQuery bundle without any extraneous modules and still found it far too big for us. I also tried substituting in Sizzle for jQuery in Backbone. All this did was tell us Backbone Views use more than the selectors from jQuery

Remove Backbone from the mobile site

With the other two out, this is what we’re doing. Now that we’ve made the decision I’m ok with it really. Our brief flirtation with Backbone was good but it was not adding enough value to our site to merit the extra file size. This is not a criticism of Backbone, if our application architecture was different then it would be awesome. But most of its work is already being done by the back end, and the rest we will be able to recreate in a smaller bespoke package and by obeying conventions in our coding.

We may well still use it on the Desktop site though, once we get there.

Tagged , , , , ,

Improving SASS with Compass

On Sunday I talked about why CSS is dumb and SASS is awesome, today I’m going to talk about how SASS is dumb and Compass is awesome. That’s not entirely fair, Compass relies on SASS, but it is the thing that really unlocks the potential of SASS with limited effort on your own part.

What is Compass for?

SASS is a language for writing Stylesheets, Compass is a framework built in SASS. This means that while SASS enables all sorts of cleverness, Compass applies that cleverness in ways that should be useful to almost anyone.

Why use Compass?

The two features of compass which are most exciting me right now are CSS3 helpers and Spriting. It does other things too – helpers to automatically adjust values, text styling, a reset file and layout support. These all sound marvellous but I’ve not touched the things yet. Let’s talk about the bits I have played with.

CSS3 helpers are a collection of mixins to help with CSS3. I’m sure this is a surprise to no one. What it means is, rather than writing out multiple lines of browser specific code for any given CSS3 feature, instead you just use one of Compass’ mixins to produce the same result. This resolves the annoyance of writing the same command more than once and also means that when if the browsers settle down and we stop needing the browser specific versions, we can change it in one place and update our commands everywhere.

There’s no reason you couldn’t write this out yourself in SASS, but Compass has had more time put into each mixin than you’re likely to want to and is a hell of a lot easier.

Spiriting, on the other hand, can’t be done without something extra. There are other libraries that do this for you, but the fact that its integrated with your Stylesheets is nice. But what the hell do I mean when I say spriting?

Well, with Compass you can use a diverse set of individual images which can be automatically turned into a single sprite image, with the positioning worked out automatically. Gone are the days of remembering the offset necessary to get a specific icon, instead you just use the icon image and let Compass turn it into a Sprite. I believe the phrase is having your cake and eating it too.

So that’s Compass, a way to really leverage using SASS without re-inventing the wheel or straining yourself in any significant capacity.

Next week, how to set up SASS and Compass.

Tagged , , , , ,

Improving CSS with SASS

Syntactically Awesome Style Sheets is a CSS Pre-processing language. It is not the only one, but it is the one we’ve chosen to use. The other major players in the CSS-Pre-Processor-Fight are LESS and Stylus. Our decision making process between these three and countless others that exist but have less press was not massively sophisticated. We looked at some articles which generally seemed to prefer SASS. That said, they all had good things to say about the others just claimed SASS had a slight edge.

Because writing CSS-Pre-Processor is going to get old fast, I’m going to stop talking about them in general and instead talk just about SASS. Everything about why to use SASS is generally applicable to them all.

What is SASS for?

CSS is stupid. As your selectors start having to get more specific, so you start writing the same thing over and over. If you need to use similar bits of styling with minor differences multiple times (I’m looking at you border-radius), then you’re writing it out again. If you want to keep a consistent colour palette you’ve got to remember what colours you’re using and if you’re changing them, you’ve got to change them all manually. These are hallmarks of a stupid language.

But it doesn’t have to be. What if we stopped writing CSS and instead let it become an output, like what happend to Machine Code back in the mists of time? This sounds radical, but it isn’t really. We’re already pre-processing our CSS before serving it to a client by minifying it, why not expand that process to allow us to write CSS intelligently?

So why use SASS?

Enter SASS. It is a cleverer langauge than CSS which compiles down into valid CSS. This means that using SASS doesn’t create any sort of compatability issue or overhead for your user, just adds some weight to your compile step. But what do you get for this added weight beyond vague claims of cleverness?

As ever, the SASS homepage provides a better summary than I will here, and indeed a better in depth discussion too. But here’s my own summary.

How to use SASS

Nesting

Ever written anything like this?

.aClass { 
	width: 100px
}
.aClass .anotherClass { 
	height: 200px
}

With SASS you can write it like this

.aClass { 
	width: 100px
	.anotherClass {
		height: 200px;
	}
}

This gives you a syntax which better represents the relationship between selectors and involves writing .aClass one less time. Result!

Selector Inheritance

How abou this? Ever needed this?

.aClass, .extendedClass {
	width: 100px;
	border: solid 1px red;
}
.aClass.bigText, .extendedClass.bigText {
	font-size: 2em;
}
.extendedClass {
	border-width: 3px;
}

SASS let’s you extend classes like this

.aClass {
	width: 100px
	border: solid 1px red;
}
.aClass.bigText {
	font-size: 2em;
}
.extendedClass {
	@extend .aClass;
	border-width: 3px;
}

Again, less writing and a better representation of the relationship between classes. But what about the .aClass.bigText selector? That meant writing .aClass twice and writing things twice is everything I stand against. We can’t nest it as before because that would produce .aClass .bigText rahter than .aClass.bigText, but have no fear!

.aClass {
	width: 100px;
	border: solid 1px red;
	&.bigText {
		font-size: 2em;
	}
}

The & represents the original selector and lets us nest the .bigText inside .aClass.

Variables

Let’s say you wanted to have a standard version of blue used across your whole site. Rather than remembering its hex code, you can store it in a variable

$blue: #3bbfce;
.aClass {
	background: $blue;
}

Mixins

Mixins provide parameterizable reusable sections of code. For example, whenever we want a broder radius we need something like this

.aClass {
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	border-radius: 5px;
}

.anotherClass {
	-webkit-border-radius: 2px;
	-moz-border-radius: 2px;
	border-radius: 2px;
}

With SASS, we can boil it down to this


@mixin border-radius($radius) {
	-webkit-border-radius: $radius;
	-moz-border-radius: $radius;
	border-radius: $radius;
}

.aClass {
	@include border-radius(5px);
}
.anotherClass {
	@include border-raidus(2px);
}

I should also include a note clarifying the difference between SASS, SCSS, and SASS.

SASS is a CSS Pre-processing language. Originally its syntax was modelled on haml and was very terse, keeping keystrokes to a minimum. This was popular with many people but also put others off. I am in the second camp, I want write my CSS using CSS syntax with logical extensions.

To cater to the likes of me a new syntax was developed, Sassy CSS or SCSS. SCSS is a syntax for SASS which looks a lot like CSS and is how I choose to write my SASS. However they didn’t deprecate the old syntax which still exists and is called SASS. So, SASS is a pre-processing language, SCSS is a syntax for SASS, and SASS is also a syntax for SASS. Clear as mud? Good.

I will almost never mean SASS the syntax when I talk about it, because I don’t use it. I also have a habit of using SASS and SCSS interchangeably. Sorry.

And that’s your whistlestop tour of SASS. It makes writing and maintaining your CSS easier without creating problems for the client.

Tagged , , , , ,

Using Backbone with Require

So we’ve done Backbone, we’ve done Require. Let’s put them together. Previously we wrote a pointless little Backbone app. Now, we’re going to Require-ify it.

Require.js is, as you know, all about modularisation. Fortunately, Backbone makes it pretty obvious what makes up a Module. Is it a distinct Backbone entity? A Model, a Collection or a View? Boom. It’s a module.

So with the difficult decision making done, let’s look at how we’d do this.

Starting from the beginning, our require config. You might recognise this from my original require post. That is because I am lazy.

File: js/requireConfig.js

require.config({
	paths: {
		//libraries
		jquery: 'libs/jquery',
		underscore: 'libs/underscore',
		backbone: 'libs/backbone',

		//scripts
		developerModel: 'models/DeveloperModel',
		developerCollection: 'collections/DeveloperCollection',
		developerListView: 'views/DevelopersListView'
	},
	shim: {
		jquery: {
			exports: "$"
		},
		underscore: {
			exports: "_"
		},
		backbone: {
			deps: ['underscore', 'jquery'],
			exports: "Backbone"
		}
	}
});

File: js/index.main.js

require(['requireConfig'], function(){
	require(['developerListView'], function(DeveloperListView){
		var myView = new DeveloperListView();
	});
});

File: index.html

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<title>One Page Web App</title>

	</head>
	<body>
		<section id="content">
			<h1>Really Useful Dev List App</h1>
			<input type="text" id="name"></input>
			<input type="radio" name="role" id="isUx">UX</input>
			<input type="radio" name="role" id="isDev">Dev</input>
			<button id='add'>Add List item</button>
			<ul></ul>
		</section>

		<script src="js/libs/require.js" data-main="js/index.main">
	</body>
</html>

This is the same html as my Backbone post but with a require script tag instead of an ordinary one.

Right, that’s all the essentially unchanged stuff out the way. Now let’s look at the MOSTLY unchanged stuff. After that we will have run out of stuff.

filename: js/models/DeveloperModel.js

define([
	'underscore',
	'backbone'
], function(_, Backbone){
	var Developer = Backbone.Model.extend({
		defaults: {
			name: 'A Dev'
		}
	});

	return Developer;
});

This is the Model from our earlier Backbone app. It is now a file in its own right wrapped in a define block. It has its dependencies, Backbone and Underscore defined and then establishes a function that creates the concept of a Developer Model and returns it. Note, it is not returning “A developer” it is returning the Developer Model, which can be instantiated as needed.

filename: js/collections/DeveloperCollection

define([
	'underscore',
	'backbone',
	'developerModel'
], function(_, Backbone, Developer){
	var DeveloperCollection = Backbone.Collection.extend({
		model: Developer
	});

	return DeveloperCollection;
});

This is our collection. Again, it returns the idea of a collection of developers, not an actual collection of developers. It may well be possible to remove the dependency on the Developer model by passing it into any calls to the DeveloperModel. I’ll be exploring this and if it turns out to be a good idea and possible, I’ll talk about it.

Finally, our View. For the sake of avoiding this post becoming any more massive than it already is, I’ve snipped out all the logic inside the View, if you want to see it check out my Backbone post. Doing my bit to save your monitor’s ink reservoir.

define([
	'jquery',
	'underscore',
	'backbone',
	'developerCollection',
], function($, _, Backbone, DeveloperCollection){
	var DevelopersListView = Backbone.View.extend({
		...
	});

	return DevelopersListView;
});

On a sidenote, when I wrote this I gave the path names in RequireConfig camel-cased names, starting on lowercase letters but decided to follow the convention of having anything imported into a file start with a capital letter. This was annoying. Don’t do that. Although I am fond of the capital letters for imported objects though. I recommend that.

That’s it, we now have a pointless little Backbone and Require app.

Tagged , , , , ,

Using Backbone.js

Like Require, Backbone has many pre-existing and excellent tutorials. In particular Artur Adib’s tutorial is what made it all become clear to me and Aaron Hardy’s article on JavaScript Architecture continues to make me happy.

Still here? Are there not plenty of links to fit your information needs above? You curious fellow/fellette. Let’s have a crack at an overview of Backbone then.

Backbone’s structure

Backbone introduces four types of Object to your JavaScript. Models, which represent a single entity of data. Collections, which contains multiple Models. Views, which handle the presentation of your data. And Routers which are special and cool and not going to come up again in this post.

Starting with a Model

Creating a Model is really easy in Backbone.
var Developer = Backbone.Model.extend();
Boom. A Developer Model. We can get fancy though

var Developer = Backbone.Model.extend({
	defaults: {
		name: 'A Dev'
	}
});

Here we are defining a pair of default attributes. This means that any Developer created will have these attributes set to these values unless specified otherwise. We are not defining a complete list of possible attributes, merely the ones we want all examples of the Model to have and their default values.

There’s more we can do with a Model, but we’re not going to get into that now.

Creating a Collection

If you’re still reeling from creating a Model, then creating your collection can be a bit of a breather for you.

var DeveloperCollection = Backbone.Collection.extend({
	model: Developer
});

Done. We’ve created a collection and told it what it’s a collection of. Again, there’s more fancitude available but we’re not going to touch it today.

Displaying data with a View

Backbone is very close to a Model-View-Controller pattern. The thing it’s missing is a Controller. That’s becuase responsibilty for Control is placed partly in the Collection, but mostly in the View.

The View is responsible for rendering html to display your models and taking in user input. This means that even even at its most basic, there’s a little more to a View than a Model or Collection. Let’s take a look:

var DevelopersListView = Backbone.View.extend({
	el: $('#content'),
	initialize: function(){
		_.bindAll(this,'render', 'appendItem');
		this.collection = new DeveloperCollection();
		this.render();
	},
	render: function(){
		var self = this;
		_(this.collection.models).each(function(item){
			self.appendItem(item);
		});
	},
	appendItem: function(item){
		var template = _.template('<li><%= name %></li>');
		var templateVariables = {
			name: this.model.get('name')
		};
		$('ul', this.el).append(template(templateVariables));
	}
});

The el attribute tells the View where in the page to insert itself. I’m not sure about using a jQuery selector here, I suspect it’s not necessary but it’s what Artur did and I’m not going to argue right now.

The initialize function is run when the View is instantiated. It is doing three things. First, it’s calling bindAll on its functions. bindAll is an Underscore function which fixes the context of functions. What that means is, whenever we call a bound (binded?) function, the value of this is fixed to the object passed as its first parameter. In this case, it’s the View.

Second, initialize instantiates a Collection to use. Third and finally, it calls its own render function.

The render function iterates through the collection using Underscore’s each function and calls its own appendItem function on it.

The appendItem function uses an Underscore template and the contents of the object passed to it, a Model, to add a DOM element to the page. This could and should be a separate file, but for now it can just be a String.

So that’s all very good and lovely, except right now we’re using an empty collection and have no way to add anything to it. Let’s fix that by adding a bit more to the View

var DevelopersListView = Backbone.View.extend({

	el: $('#content'),
	events: {
		'click button#add': 'addItem'
	},
	initialize: function(){
		_.bindAll(this,'render', 'addItem', 'appendItem');
		this.collection = new DeveloperCollection();
		this.collection.bind('add', this.appendItem);
		this.render();
	},
	render: function(){
		var self = this;
		_(this.collection.models).each(function(item){
			self.appendItem(item);
		});
	},
	addItem: function(){
		var nameIn = $('#name').val();
		if (nameIn) {
			this.collection.add({name:nameIn});
		} else {
			this.collection.add();
		}
	},
	appendItem: function(item){
		var template = _.template('<li><%= name %></li>');
		var templateVariables = {
			name: this.model.get('name')
		};
		$('ul', this.el).append(template(templateVariables));
	}
});

So, what’s new here? We’ve added an events object, an addItem function and a couple of extra bindings. Let’s start on the addItem function. We’re looking at the DOM object with id name, taking its value and adding it to the collection. We’ve wrapped this add in an if statement so that if the name input is empty, we’re using a default.

So, how about our new bindings? Well, addItem has been added to the bindAll. Pretty much every function attached to your View should be in the bindAll. We’ve also called bind on an add event for the new collection. Confusingly, this is not an Underscore bind. This is a function of the Backbone collection Object. We’re saying that when an add event is fired by the DeveloperCollection object, then we should run the appendItem function.

Finally, the events object. This defines all the event bindings associated with the View. We’ve said that when a click event is fired on the button with id add, we run the addItem function.

All this needs now is some html including a name input, an add button and a content div

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8" />
		<title>One Page Web App</title>

	</head>
	<body>
		<section id="content">
			<h1>Really Useful Dev List App</h1>
			<input type="text" id="name"></input>
			<button id='add'>Add List item</button>
			<ul></ul>
		</section>
		<script src="backboneapp.js"></script>

	</body>
</html>

Ta-Da! That’s it for now, a fully functional if pointless little Backbone app.

Tagged , , , ,

Utilitying With Underscore.js

Underscore.js is a utility library which Backbone depends on. I’m afraid I don’t have a huge amount to say about it though because the only reason we’re using it is so that we can use Backbone. Lovely cuddly Backbone.

What is Underscore for?

It provides functional programming support for your JavaScript. This includes tools for manipulating Objects, Collections and Arrays as well as some generic utility functions.

It also supports some baisc HTML templating. This is the only feature I’ve actively used as it is valuable for producing Backbone Views. As a templater it’s pretty simple, which is probably a good thing. It’s been fit for all my extremely limited needs so far. This is tepid praise but based on inexperience rather than any negative feelings.

So why use Underscore?

So that we can use Backbone and because it makes life easier. A bit like functional jQuery.

Well that was short. Let’s talk about Lodash while we’re here. Lodash is a drop in replacement for Underscore. In theory this means that if you write your code base using Underscore, you can then change your mind and use Lo-Dash.

So Why Use Lo-Dash?

It’s a bit bigger but offers performance enhancements and some extra features. It’s also possible to generate specific subsections of Lo-Dash, so you can just get the bits relevant to Backbone and use that instead of the whole thing.
This link from the comments provides a much better answer to this question than I can. Lo-Dash has been designed to provide a more efficient, more consistent and better tested alternative to Underscore. It has been design with compatibility in mind though, so that if you don’t use the extra Lo-Dash features, the two should indeed be interchangeable.

We haven’t decided between the two yet. Lodash sounds pretty good but the whole thing is 19kb compared to Underscore’s 4kb. Taking just a Backbone version will reduce that but right now I don’t know how much. These enhancements sound great but are they 15kb of download better?
John in the comments has pointed out that the size difference is not as great I originally thought. It’s actually more like half a kilobyte.

The good news is since it drops in to replace, we should be able to build around underscore then swap in lodash to see if things are better.

Tagged , , , , ,

Stucturing with Backbone

Backbone.js is a library for giving structure to your JavaScript. It provides a framework that looks very similar to Model-View-Controller to base your app on.

What is Backbone for?

Combined with Require.js, this means our apps can have a well defined and sensible structure that’s starting to look like Object Orientation. I can barely contian my excitement either. No really, I can’t, this is awesome.

So why use Backbone?

Using Backbone means your code can fit into a consistent and comprehensible format. You keep your data in a Model. You keep your Modles in a Collection and you access your Collection through a View.

We’re developing with a view to produce control widgets that can be reused in different places – specifically desktop, mobile, and a summary screen. Using Backbone we can write the Model and Collection code once, only changing the necessary bits in the View to reuse it.

Backbone also provides a Router feature that decides which scripts to run based on the URL. To facilitate this, it can either use or polyfill for the HTML5 History API. This means you can manipulate the url and browser back/forward behaviour without actually changing the page.

We’re planning on sharing urls between desktop and mobile pages. However this is complicated because some things that share a page on desktop are separate pages on mobile. With Backbone Routers this should be possible.

In summary, backbone provides a structure to your JavaScript that makes it easier to write, maintain and reuse.

Tagged , , , , ,
Advertisements