Linking JavaScript Objects to HTML Elements
Alternative Title: The jQuery $.data() Function is Awesome
![]()
The Workflow creation tool I’ve been working on and blogging about (design & code pattern) would have been impossible without forcing myself to learn object oriented (OO) JavaScript. It was a pretty steep learning curve for a designer, and I soon came across the common pitfalls of writing OO code. The factory pattern structure I linked to above took care of most of the problems like: pushing pseudo-class objects to an array, easy find methods without the use of hash tables, and deleting objects non-destructively.
One thing that took me a while to wrap my head around: How do you form a relationship between the “back end” object instances and the HTML/DOM objects you output from these?
Say you have the classic Person object example:
var collection = [];
var Person = function(params) {
this.name = null;
this.age = null;
$.extend(this, params);
collection.push(this);
}

When I came across the problem of being able to link back to the object itself, the first (and laziest) solution that jumped to mind was searching using an instance’s unique ID. Creating the objects initially gives you the chance to ensure the HTML and back end instance shared the same ID. At a later point when you need to find the instance, you can loop through your objects with class manager shorthand findBy() function:
Manager.prototype.findBy = function(p, v) {
for(var i = 0, len = this.objs.length; i < len; i++) {
if(this.objs[i][p] === v) {
return this.objs[i];
}
}
};MyManager.findBy(“id”, 999);
This made a lot of sense initially:
- HTML attributes can only be strings.
- Make the HTML element and the back end object share an ID
- Loop through and match the object when required
![]()
An Example
In this example, we have to get the ID from the HTML element, convert it to an integer and then finally: loop through all the instances until it finds a match.
// get the ID value
var theID = parseInt($(this).attr(“objectID”), 10);
// silly loop to find the object
$(collection).each(function(i, item) {
if (item.id === theID) {
item.birthday();
}
});
But why bother looping? Maybe a hash table would be better suited to your scenario, but for me I wanted something more dynamic.
![]()
The Better Way
The jQuery $.data() method is awesome. On face value it’s like the native $.attr() method but doesn’t restrict you to a string value. What this incredibly long-winded post boils down to is the realisation that you can bind your HTML elements directly to their back end objects via the use of the data attribute. No (visible) loops.
// set the data attribute originally
$(obj).data(“personObject”, self);// call birthday on the object directly
var theObject = $(this).data(“personObject”);
theObject.birthday();
You don’t even have to declare a reference to the object, you could just as easily chain up your calls. A word of warning though: this can get a bit confusing if you’re using a chaining library like jQuery, especially if your object prototype functions share names like “remove()”. ■