Today I wanted to share a snippet of Javascript with you. This function works with the excellent Behaviour javascript library. Normally, I’m very wary of using javascript libraries. Often they are quite bloated, the documentation is a nightmare and they require almost as long to learn as it would take to write it yourself. Behaviour is a little different though: you could barely even call it a library, since there’s really only one function you need to know.

Behaviour, written by Ben Nolan - a Kiwi, hence the correct spelling :) - is to javascript events as CSS is to html formatting. Basically, you define the behaviours of elements based on a CSS selector. More information is available at the site if you’re interested.

Now to the snippet.

One common task in developing a web application involves creating a data table with checkboxes down one side so you can perform bulk operations. When you’ve got a layout like that, it’s often very handy for the user to have a “select all/none” option. This function will apply a behaviour to all checkboxes which are inside a TH element to tick/untick all the checkboxes in that column.


Behaviour.register({
	"th input[type=checkbox]" : function (el) {
		el.onclick = function() {
			// find the table element
			var tempEl = this;
			var breakNow = false;
			var col = 0;
			var table;
			while ((tempEl = tempEl.parentNode) && !breakNow) {
				switch (tempEl.nodeName.toLowerCase()) {
					case 'table' :
						table = tempEl;
						breakNow = true;
						break;
					case 'th' :
						// find which column this is in
						var cell = tempEl;
						while (cell = node_before(cell)) col++;
					break;
				}
			}
			if (tempEl.parentNode == undefined) return;
			var rows = table.rows;
			for (var i = 0; i < rows.length; i++) {
				var inp = rows[i].cells[col].getElementsByTagName('input');
				for (var j = 0; j < inp.length; j++) {
					if (inp[j].type == 'checkbox') {
						inp[j].checked = this.checked;
					}
				}
			}
		}
	}
});

you might notice that this uses another external function called “node_before()”. This behaviour could easily be rewritten without the dependency on that function - it merely gets the, wait for it, node before the given element, except that it ignores comments and whitespace. It was stolen sourced from the Mozilla Developer Center and can be found here in my small library of DOM Functions.