Tripod.js

Two-way data-binding is sooo 2009.

What's that you say? Three-way data binding?

Data seamlessly synced between your JavaScript, the DOM, and LocalStorage.

Oh yeah, that means it syncs across browser tabs.

Whaaaaat!? I know, right?

Even works on Grandpa's browser.

Tripod.js works in IE7+. Of course, the real browsers are supported, too.

Dependencies?

Nope.

And it's tiny. About 2.1KB minified + gzipped.

Tripod.js is a library, not a framework.

So stop complaining, already. It doesn't tell you how to write your Javascript or design your systems. It's just a handy place to store your data and helps keep it organized and displayed nicely.

Tripod.js is fully unit tested.

All public methods, including binding modifiers and utility methods, are unit tested with QUnit. Have a look for yourself.

Back to Top

A Simple Demo

Here's a simple demo showing off data binding between a form element, a second DOM node (in this case a paragraph) and LocalStorage.

For extra credit, open this page up in a new tab and flip between the tabs as you change your selection in the select element. The page remembers your favorite pizza topping and syncs it across tabs.

Does your best friend know your favorite pizza topping? Tripod loves you.

The Demo

What's your favorite pizza topping?

Great! We'll put extra on your pizza!

The Code

<p>
  <select data-bound-to="pizza.pizzaTopping">
    <option>Cheese</option>
    <option>Pepperoni</option>
    <option>Anchovies</option>
    <option>Gummy Bears</option>
  </select>
</p>
<p>Great! We'll put extra 
  <strong data-bound-to="pizza.pizzaTopping"></strong>
  on your pizza!</p>
var pizza = new Tripod({}, 'pizza', true);
pizza.sync('pizzaTopping');
Back to Top

A Demo with Lots of Inputs

Tripod works with pretty much any type of DOM node you can think of, including all of your favorite input elements.

The Demo

If I told you the checkbox above was checked, that would be a statement.


Pick a number and I'll use my magic JavaScript powers to guess it.

Hmm. You're a tough read. Was it 7? Just kidding. It was .


All right, you've been a good sport. What's your name?

Nice to meet you, !

The Code

<p>
  <label>
    <input type="checkbox" data-bound-to="crazy.check">
    Check it out, yo.
  </label>
</p>

<p>If I told you the checkbox above was checked,
  that would be a <strong data-bound-to="crazy.check"></strong>
  statement.</p>

<hr>

<p>Pick a number and I'll use my magic JavaScript powers to guess it.</p>

<p>
  <label><input type="radio" name="crazyRadio" data-bound-to="crazy.radio" value="one" checked> 1</label>
  <label><input type="radio" name="crazyRadio" data-bound-to="crazy.radio" value="two"> 2</label>
  <label><input type="radio" name="crazyRadio" data-bound-to="crazy.radio" value="three"> 3</label>
  <label><input type="radio" name="crazyRadio" data-bound-to="crazy.radio" value="four"> 4</label>
  <label><input type="radio" name="crazyRadio" data-bound-to="crazy.radio" value="five"> 5</label>
</p>

<p>Hmm. You're a tough read. Was it 7? Just kidding. It was <strong data-bound-to="crazy.radio"></strong>.</p>

<hr>

<p>All right, you've been a good sport. What's your name?</p>

<p><input type="text" data-bound-to="crazy.yourName"></p>

<p data-bound-to="crazy.yourName" data-bound-as="show">
  Nice to meet you, <strong data-bound-to="crazy.yourName"></strong>!
</p>
var crazy = new Tripod({}, 'crazy');
crazy.sync(['check', 'radio', 'yourName']);
Back to Top

Introducing Binding Modifiers! (Yes, Another Demo)

Did you catch that little trick I pulled at the end of the last demo? It uses binding modifiers.

Binding modifiers take your data bindings and tweak the way they behave.

There are a bunch of binding modifiers. To see them all, your best bet is to check the source code. Have a look at the Tripod.bindingModifierFunctions object.

The Demo

The checkbox above is checked. not checked.

Show me the money. (Enter a number)

The Code

<p>
  <label>
    <input type="checkbox" data-bound-to="mods.check">
    Check it out, yo.
  </label>
</p>

<p>The checkbox above is 
  <strong data-bound-to="mods.check" data-bound-as="show">checked.</strong>
  <strong data-bound-to="mods.check" data-bound-as="hide"><em>not</em> checked.</strong>
</p>

<p>
  <label data-bound-to="mods.red" data-bound-as="toggleClass | red">
    <input type="checkbox" data-bound-to="mods.red">
    Make it red.
  </label>
</p>

<p>
  Show me the money. (Enter a number)
  <input type="text" data-bound-to="mods.currency">
</p>

<p data-bound-to="mods.currency" data-bound-as="show">
  <span data-bound-to="mods.currency" data-bound-as="currency"></span>
</p>
var mods = new Tripod({}, 'mods');
mods.sync(['check', 'red', 'currency']);
Back to Top

Templating with Binding Modifiers

The template binding modifier allows you to use a template to generate html for an object or array of objects.

Note that the template is the contents of the bound element, exclusive of the element itself. Check the demo code for clarification.

The Demo

Name Department Salary
{name} {dept} {salary}

The Code

<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Department</th>
      <th>Salary</th>
    </tr>
  </thead>
  <tbody data-bound-to="templating.salaryTable" data-bound-as="template">
    <tr>
      <td>{name}</td>
      <td>{dept}</td>
      <td>{salary}</td>
    </tr>       
  </tbody>
</table>

var data = {
  salaryTable: [
    { name: 'Bob', dept: 'Human Resources', salary: '$56,000'},
    { name: 'Jane', dept: 'Engineering', salary: '$118,000'},
    { name: 'Sue', dept: 'Management', salary: '$231,500'}
  ]
};

var templating = new Tripod(data, 'templating');
templating.push('salaryTable');