Use JavaScript templates to swap content

April 15th, 2012

In my previous example of using a JavaScript template, I showed you how to use it to set up some static content. While that’s a good use for JS templates, you can use it to do a lot more. One situation I find using JS templates for is when I need to swap out content based on a category or some other parameter. In fact, by expanding on the previous tutorial, we can make something that you used to use PHP for or you’d have to create long strings in your JS that you’d swap out on the page. Now we can just expand our array and use a few lines of jQuery.

We’re using the same HTML as before, so all we need to do is alter our JavaScript file (I’ve added CSS to style the example, but none of it is necessary for our example to work). What we’ll build is a page with three links at the top for each rating, then we’ll swap out the content based on which link was clicked. Here’s the starting point for our JS (where we left off last time):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
(function() {
   var container = $('#container'),
       people = [
       {
           name: 'James Bond',
           job: 'Spy',
           rating: 'Awesome'
       },
       {
           name: 'Indiana Jones',
           job: 'Archaeologist',
           rating: 'Awesome'
       },
       {
           name: 'Bruce Wayne',
           job: 'Superhero',
           rating: 'Total badass'
       },
       {
           name: 'Nicolas Cage',
           job: 'Actor',
           rating: 'Crazy'
       }
   ],
   template = Handlebars.compile($('#template').html());
   container.append(template(people));
})();

Just as a refresher, we use Handlerbars.js to grab and compile the template we have in our HTML and then we use jQuery’s append method to insert that template into the page after we pass the people array to the template. But we aren’t doing anything special, just passing an array to our template, we can use this to set up our different categories. First, we need to add the category navigation to our HTML:

1
2
3
4
5
6
7
<nav>
   <ul>
       <li><a class="current" href="#0">Awesome</a></li>
       <li><a href="#1">Badass</a></li>
       <li><a href="#2">Crazy</a></li>
   </ul>
</nav>

We have three choices, “Awesome”, “Badass” and “Crazy”. And each has a hash of 0 to 2. We’ll use this when the link is clicked to show that content on our page. Now on to the JavaScript, first we need to grab our nav. Add this right under the container variable:

1
nav = $('nav a'),

Now we have access to all the anchor tags inside our nav. If this content was being updated and added to frequently, then you’d probably want to create the category choices dynamically too, but we don’t really need that in this example. Next we need to change our array so this will work the way we want. Currently, we have objects in our people array and Handlebars.js runs through them and creates our HTML. Since we can nest arrays, which you should know unless you’re brand new to JavaScript, we can set up our people array in a way to make it easy to swap our categories. Change the people array to this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
people = [
   // Awesome
   [{
       name: 'James Bond',
       job: 'Spy',
       rating: 'Awesome'
   },
   {
       name: 'Indiana Jones',
       job: 'Archaeologist',
       rating: 'Awesome'
   },
   {
       name: 'Mario',
       job: 'Plumber',
       rating: 'Awesome'
   }],
   // Badass
   [{
       name: 'Bruce Wayne',
       job: 'Superhero',
       rating: 'Total badass'
   },
   {
       name: 'Jason Bourne',
       job: 'Assassin',
       rating: 'Total badass'
   }],
   // Crazy
   [{
       name: 'Nicolas Cage',
       job: 'Actor',
       rating: 'Crazy'
   },
   {
       name: 'The Joker',
       job: 'Criminal',
       rating: 'Crazy'
   }]
],

Other than the fact that I’ve added a few people to our array, the main change is that we’ve nested an array for each category. And each of those arrays are exactly the same as our original array, it’s an array of objects. Now you might have figured out what we’re going to do. Each category in our nav has a hash that’s a number and that number corresponds with the position of that category in our array. In our original JS, we had this line:

1
container.append(template(people));

Now we need to change it to this:

1
container.append(template(people[0]));

Now we’re passing the first item in our people array which is our Awesome category. So if we left it here, then the only change would that Mario shows up and Batman and Nic Cage don’t. And if you clicked on the links, nothing would happen. Let’s add some functionality:

1
2
3
4
5
6
7
8
nav.on('click', function(e) {
   e.preventDefault();
   var hash = this.hash.replace(/^#/, '');
   nav.removeClass();
   container.html('');
   container.append(template(people[hash]));
   $(this).addClass('current');
});

If you’ve used jQuery even once, you should be able to guess what’s basically going on here. We’re using the on method to listen for when one of anchor tags is clicked and then we use preventDefault() so that the page doesn’t reload. Next we create a variable called hash but what’s going on with what we’re assigning it? The word this is equal to which anchor tag we’ve clicked on, and we then have access to that anchor tag’s hash. There’s a problem though, if we just had var hash = this.hash, hash would equal ‘#0’ and we can’t pass that as the position in our array. So we use JavaScript’s replace method and use a tiny regular expression to remove the ‘#’ so when end up with just the number. So var hash = this.hash.replace(/^#/, ‘’) will give us ‘0’ instead of ‘#0’.

In the HTML, I added a class of current to the ‘Awesome’ link, so we remove that and then we clear the HTML inside the container div with by calling jQuery’s html() method and passing an empty string to it. Next we run the same line of code as we did before to append our template to the page but this time, instead of passing 0, we pass whatever link was clicked using our hash variable. And, finally, we add the class of current to the link that was clicked.

And here’s a demo of what we get.

The final effect is nothing that you haven’t seen before, but usually we’ve had to reload the page and use server side code, use big, hard to edit strings of HTML in our JavaScript or use a something like the jQuery tabs plug-in that still requires us to write out all the HTML. Now look at how little code we had to write to get it to work.

I’m going to do another post showing how to use Handlebars.js’ features such as conditionals and helpers.

One Response to Use JavaScript templates to swap content

  1. pol says:

    please do post more about Handlebars and if you can make it without jquery even better :)
    thanks for sharing!

Leave a Reply

Your email address will not be published. Required fields are marked *