---
title: Rendering views in Javascript
teaser: 'Add structure to your Javascript apps by using various libraries to render
  your HTML views in a systematic way.

  '
tags: javascript,new bamboo,web
author: Max Williams
published_on: 2010-02-19
---

_This post was originally published on the New Bamboo blog, before [New Bamboo
joined thoughtbot in London][new-bamboo-thoughtbot]._

---

This is possibly the hardest part of a [Javascript MVC framework] to standardise
on. More than anywhere else, it is open to interpretation and differences of
opinion. I will briefly run through a number of different options moving towards
the kind of thing I like.

One of the key things to think about first when deciding on your javascript
strategy is accessibility and SEO. This will determine whether you need the
majority of your DOM to be rendered by the server, and whether you are going to
present different parts of your application as different "pages".

If you are going to build a traditional web site where doing things goes to
different pages, you can then decide on how much you want to add "Degradable"
enhancements into the mix.

I am going to focus on non-degradable functionality, and am tallking about the
types of RIAs that would previously have been done in Flash. I'm a firm believer
in the capabilities of using HTML 5 to build almost native feeling apps.

## How to make the HTML?

With dynamic state changing in your client's browser, these objects first need
to be rendered, and then updated if they change.

The simplest thing that works is often something like this:

```javascript
document.write("<p>"+ myObject.name+"</p>")
```

Since this is obviously too simple for a real application, the next evolution of
this would be to put the new data in a specific place (using JQuery).

```javascript
$('#my_list_of_objects').append("<p>"+ myObject.name+"</p>")
```

At this point it becomes necessary to choose an overall strategy for updating
the UI and the choices can be classed as follows:

* Simple string interpolation
* Injecting fragments of HTML rendered by a server
* Employing a templating language
* Modifying and cloning existing parts of the DOM

## Libraries

There are several libraries available for rendering JS objects as HTML, which I
will cover briefly.

### The clone/modify camp

There are several options:

* [Chain.js]
* [Pure.js]
* [Kiwi]

These work by cloning a fragment of HTML you have rendered with your server, and
then replacing parts of it with the attributes of a data object. This often
means that an object such as this:

```json
{
  name: "max"
}
```

Can be fed into the following HTML and in this case populate the "text"
attribute of the span with "max":

```html
<span id="my_template" class="name"></span>
```

goes to:

```html
<span id="my_template" class="name">max</span>
```

There are often nifty options when piping in the data so that it can bind to
changes on the data object itself, or other parts of your UI such as a form.

One of the drawbacks I have found from this sort of library is that customising
the view can become difficult. In the example above, it would be difficult to
make the following object:

```json
{
  id: 3,
  color: "#eee",
  name: "foo"
}
```

into (note inline style, and id attribute):

```html
<div id="my_object_3" style="background: #eee;">foo</div>
```

Flexibility can often be achieved by passing in a bunch of configuration
options, but this seems a little unwieldy to me.

### The templating camp

* [Mustache]
* Sammy templates - based on [JavaScript Micro Templating]

These essentially mean that you end up writing something like eRB in Javascript.
They aren't really my favourite option, as I think introducing a templating
language into a frontend app violates some sort of long term maintainability
principle.

What's more, we already have enough opinionated people arguing about HAML vs Erb
Vs whatever-else in our server side code, without introducing another fight on
the client end.

If you like this sort of thing some of them are pretty advanced. I believe Sammy
templates can be requested from the server as GET requests, and also cached if
necessary.

### The "injecting fragments of HTML rendered by a server" camp (eg RJS)

This is not really something I like doing, as it fits into my concept of
"[Pseudo state]".

If a part of a UI needs to be updated by a change of state, this method means
your client app goes crying to Daddy server (via Ajax) to request a snippet of
HTML which is rendered for it. It then inserts the HTML often by using some sort
of evaluated Javascript which has been sent in the request.

I could go into more detail about this, but it just feels like an anti-pattern,
and I can't really be bothered.

## Going back to MVC

Rather than using a library for creating HTML that might mean conforming to
data-binding conventions I don't agree with, I tend go for an approach which is
flexible and __javascripty__. This means building things up from the simplest
solution that works, to a case that deals with a lot of complexity.

The technique borrows from the __clone-modify__ pattern, but adding a "builder"
type of pattern to modifying it. The end result can be extended to incorporate
behaviour and event handling.

## Item Views vs Container Views

This is quite interesting distinction, but is worth thinking about. Often you
can get away with only using item views.

The easiest way of thinking about it is in terms of Rails' partials. The
following is adding a __container view__ (my_friend_list) to the page, which
corresponds to a widget:

```html
<%= render :partial => "my_friend_list" %>
```

In this partial you might have the following erb, which renders an __item view__
("my_friend_item") based on a collection of friends:

```html
<h3> My friends </h3>
<ul>
<%= render :partial => "my_friend_item", :collection => @my_friends %>
</ul>
```

Instances of __item view classes__ render one or more similar objects and
__container view classes__ are the holder for a collection of __item views__.
These aren't hard and fast rules, but are a kind of principle.

Imagine the following scenario based on a collection of people.

```javascript
myFriendCollection = [
  {
    name: "Max"
  },
  {
    name: "Frodo"
  }
]
```

A likely widget on a page might be a list of your friends:

```html
<ul>
  <li>Max</li>
  <li>Frodo</li>
</ul>
```

In this example, a "friendListView" class might be in charge of iterating
through the "myFriendCollection" array and adding a "friendItemView" to the UL
for each person it encounters.

In this way, an instance of "friendItemView" would receive a single object it is
to render. If items are added or removed from the collection, the
"friendListView" will need to redraw its children.

## Making simple item View classes

Here's how I tend to build-up the complexity of something like the example
above. This involves a similar "clone and modify" technique that some other
libraries use, but rather than abstracting the data mapping behind a bunch of
configuration options, I will simply build it up with basic JQuery. This may not
be to everyone's taste, but I think it strikes a nice balance between complexity
and simplicity.

### Step 1.

Identify the place in the view where you want to make changes.

```html
<ul id="my_friend_list"></div>
```

### Step 2.

Make a view class to represent an item to reside in that list:

```javascript
var friendItemView = function(holder_elem, person){
  ...
}
```

Note that `holder_elem` is the DOM element we created earlier
`($('#my_friend_list'))`, and person is the data object we are passing to it.

### Step 3.

Put some logic in the class to draw the object you have been given into the
holder element (in this case a simple string):

```javascript
var friendItemView = function(holder_elem, object){

  var draw = function(){
    holder_elem.append("<li>"+ object.name + "</li>");
  };

  // run when initialised
  draw()

}
```

### Step 4.

Instantiate the class with the holder element and an object to be rendered:

```javascript
new friendItemView($('#my_friend_list'), person);
```

### Step 5.

If you need to render a more complex template, you can grab it from a
"templates" section in your HTML (not related to the above example):

```html
<div style="display: none" id="templates">
  <ul>
  <li id="my_object_template">
    <h3></h3>
    <p class="description"></p>
  </li>
  </ul>
</div>
```

This then means altering your class to clone the template, and build the data
within it:

```javascript
var friendItemView = function(holder_elem, person, template){
  elem = template.clone().attr("id", null); // nullify id so it isn't duplicated

  var draw = function(){
    elem.find('h3').text(person.name)
    elem.find('.description').text(person.description)
  };

  // run when initialised
  draw()
}
```

And changing how the object is initialised:

```javascript
new friendItemView($('#my_friend_list'), person, $('#my_object_template'));
```

## Updating views

These item based views nicely encapsulate all the data needed to render
themselves. However, in these examples, I have used a private method ("draw") to
render them. What happens if the data changes, and the view needs to be
re-rendered? It is possible to make "draw" public, so it can be called
externally, but that often makes things a bit messy. It leads to the following
code being duplicated all over the place, not to mention the fact that something
global needs to keep track of these views in order to modify them:

```javascript
// do some stuff to change the data object
// find the view which corresponds with the object
// then call:
instance_of_specific_view.draw()
```

Events simplify this greatly. Rather than going into detail on events, I will
just give a couple of examples.

In the examples above, there is a one-to-one relationship between a view
instance and the data object it is passed. This means that the view can bind to
events triggered by the object which is passed to it. Changing the represented
state in the HTML is therefore handled internally. Note that entering this
territory means maintaining your data objects in sensible "Model" classes (the M
in MVC). We use [JS-Model] to handle this.

The following illustrates an example:

```javascript
var friendItemView = function(elem, person){
  ...
  person.bind('update', draw);
}
```

Hopefully you can see that this makes it easy maintain.

## Chucking in a bit of behaviour

You can also use the view as a place to bind behaviour to your HTML. The
following demonstrates the need to "drag" friends out of the list (kinda
pointless on its own):

```javascript
var friendItemView = function(elem, person){
  ...
  elem.draggable();
}
```

## Container View class

These are generally less used than the item views and need less code.

If you want a container which draws the collection of objects, it is generally
as easy as doing:

```javascript
var friendListView = function(elem, myFriendCollection){

  var draw = function() {
    for (i in myFriendCollection){
      new friendItemView($('#my_friend_list'), myFriendCollection[i], $('#my_object_template'));
    }
  }

}
```

Sometimes these holder classes may need to dictate dimensions to their children
(such as height), which can only be ascertained by holding knowledge of the
collection eg:

```javascript
...
for (i in myFriendCollection){
  friend_item = new friendItemView($('#my_friend_list'), myFriendCollection[i], $('#my_object_template'));
  friend_item.height = height_of_container / myFriendCollection.length
}
...
```

## Events

These collections are more likely to listen to events on the __collection__ such
as when a new item is added. On occasion, they may need to purge all the item
views and redraw.

```javascript
var friendListView = function(elem, collection){
  ...
  var add_new_view = function(evt, object){
    new friendItemView(elem, object, $('#my_object_template'));
  }

  collection.bind('create', add_new_view);
}
```

## Conclusion

While this technique is a little more involved than some of the templating
languages, it offers far more control and __crucially__ it feels really
__Javascripty__.

[Chain.js]: http://wiki.github.com/raid-ox/chain.js/
[JavaScript Micro Templating]: http://ejohn.org/blog/javascript-micro-templating/
[Javascript MVC framework]: https://thoughtbot.com/blog/why-your-javascript-apps-need-more-structure
[JS-Model]: http://github.com/benpickles/js-model
[Kiwi]: http://robertothais.com/kiwi_docs/view-listening.html
[Mustache]: http://github.com/janl/mustache.js/
[new-bamboo-thoughtbot]: https://thoughtbot.com/blog/new-bamboo-joins-thoughtbot-in-london
[Pseudo state]: https://thoughtbot.com/blog/let-them-eat-state
[Pure.js]: http://beebole.com/pure/
