Tripod.js

Two-way data-binding is sooo 2009.

Data binding and the DOM

So far we've just looked at Javascript. If we just lived in the land of Javascript milk and honey, we wouldn't need all this fancy data binding goodness. Let's talk about getting your data into and out of the DOM.

First Things First: Data Attributes

Tripod needs you to tell it which DOM nodes (inputs, checkboxes, paragraphs, etc) to pay attention to. To do that, you need to add a little data attribute to elements you want to sync with your Tripod instance. The attribute is data-bound-to and it looks like this:

<input data-bound-to="vehicle.make">

The examples you see here are namespaced with vehicle. You'll get a quick rundown of namespaces in the next section.

A Quick Note About load(), push(), and sync()

You really only need to use the methods below once, if at all. They are designed to perform an initial sync of data between the DOM and your Javascript. Once you have data in both places, any edits to the page will automatically show up in your Javascript, and any edits to the instance (using set()) are automatically pushed to the DOM.

Pulling Data from the DOM Using load()

In many cases, the data you want is already hanging out in the DOM, but you don't have it available to your Javascript yet. For example, when data is loaded into the page on the server side.

Consider this HTML markup:

<input data-bound-to="vehicle.fuel" value="gasoline">

Snatching this up and adding it to our firstCar instance is trivial:

firstCar.load('fuel');

load() works like set() in that the attribute doesn't have to exist before you call it. It will be created for you.

load() and LocalStorage

If you passed true as the third argument in the constructor, your Tripod instance will be backed by LocalStorage.

When your instance is backed by LocalStorage, load() will first check LocalStorage for a value before looking in the DOM.

Putting Data into the DOM Using push()

Now consider the opposite example. You have your fancy HTML form ready to go, but your data is late to the party. Maybe your data is being brought in via an AJAX call.

Have a look at this lovely form:

<input data-bound-to="vehicle.make">
<input data-bound-to="vehicle.model">
<input data-bound-to="vehicle.year">

push() to the rescue!

firstCar.push('make');
firstCar.push('model');
firstCar.push('year');

Or, if you're into the whole brevity thing:

firstCar.push(['make', 'model', 'year']);
Protip: load() and push() also accept an array of attributes.

The one-two punch: sync()

The sync() method performs a load(), then a push().

Just like load() and push(), sync() can take an array or a string argument.

Using load() on a Specific Portion of the DOM

You can limit the scope of the DOM nodes that load() traverses (and the load() call that sync() performs under the hood.)

For example, assume you have many DOM nodes bound to the attribute you're load()ing, but from they are out of sync and you have a specific set of nodes you want to get your data from. You can pass a DOM node as a second parameter to load() and sync() to only search that node for values.

For example:

<div id="one">
	<input type="text" data-bound-to="confusion" value="1">
</div>
<div id="two">
	<input type="text" data-bound-to="confusion" value="2">
</div>
var t = new Tripod();
t.load('confusion');
t.get('confusion'); // returns '1';

t.load('confusion', document.getElementById('two'));
t.get('confusion'); // returns '2';
load() expects the second argument to be a DOM node that contains the bound elements you want, not a bound element itself.