RenderTable - Voliware/Template GitHub Wiki

May as Well Call it MagicTable

We've seen how easy it is to template and generate tables using Table. RenderTable does everything Table does, but when it re-builds <table>s with fresh data, it doesn't empty the <tbody>. This means that users staring at a table that updates itself every 5 seconds won't have their page jumping around. It also means that interactive elements, like a bootstrap switch, or a basic <button>, won't show elasticity or seem to be broken during DOM redraws.

Here is our template, sitting in an HTML file

<table class="table template" id="nukesTableTemplate">
    <thead>
        <tr>
            <th>Name</th>
            <th>Yield</th>
            <th>Launch</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><span data-name="name"></span></td>
            <td><span data-name="yield"></span></td>
            <td><button type="button" name="launched">LAUNCH</button></td>
        </tr>
    </tbody>
</table>

Here is our data, an object of objects (can also be an array of objects).

var data = {
    0 : {
      name : 'Little Boy',
      yield : '15 kt',
      launched : 1
    },    
    1 : {
      name : 'Tsar Bomba',
      yield : '100 kt',
      launched : 0
    }
};

Our construction code is the same as Table, with one additional option: identifier. In order for RenderTable to manage data and its table - that is, update, add, and remove old rows - it needs to track each object by some reference. In this case, we are telling RenderTable to track each incoming and saved data objects by their name attribute.

var table = new RenderTable({
   template : $('#nukesTableTemplate'),
   identifier : 'name'
})
.appendTo('body')
.build(data);

The result is the same as a regular Table...

Name Yield Launch
Little Boy 15 kt LAUNCHED
Tsar Bomba 100 kt LAUNCH

Now we make it interesting. Our application just received some new data, and the <table> needs to be updated, RenderTable will intelligently update the <tbody> without wiping it. It will automatically remove, add, or update rows using the incoming data as a master record:

Here is some new data, hot from the president's desk:

var data = {
    0 : {
      name : 'B-61',
      yield : '340 kt',
      launched : 0
    },    
    1 : {
      name : 'Tsar Bomba',
      yield : '100 kt',
      launched : 1
    }
};

The first object Little Boy is gone, B-61 is new, and someone launched the Tsar Bomba! Quick, update the table!

Name Yield Launch
Tsar Bomba 100 kt LAUNCHED
B-61 340 kt LAUNCH

Didn't I Just Click That?

Okay, cool. RenderTable can update everything by itself, including removing old rows. There's one more piece to this puzzle: interactive table elements. Take the LAUNCH button (it is a link here, due to wiki constraints) for example. While we want to provide the user with the most up-to-date data about the state of controls, we also have to remember that the user is the master, and that the application is a little more subordinate. That means that even in our explosive example, if our nuke has been launched, we don't want to update this button.

Why is that? As an analogy, when we turn on a light switch in our home, and there is no power, nothing turns the light switch back off - if something doesn't work, we should provide feedback in a different way, such as an alert. In most cases, we want the user to be the master. To do this, we just need to add one more attribute to elements that we only want updated the first time they are added: data-update="false".

Here is our new template, where the LAUNCH button will only be updated the first time.

<table class="table template" id="nukesTableTemplate">
    <thead>
        <tr>
            <th>Name</th>
            <th>Yield</th>
            <th>Launch</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><span data-name="name"></span></td>
            <td><span data-name="yield"></span></td>
            <td><button type="button" name="launched" data-update="false">LAUNCH</button></td>
        </tr>
    </tbody>
</table>

Now, when we update (all builds other than first), RenderTable will update the <span> elements as normal, but it won't touch the <button>. You can set a similar attribute for columns you may not want to be populated at all, using data-populate="false". These elements will simply remain as they were in the template.

RenderTable is the perfect solution for interactive tables that are updating at some interval. They are great for dynamic management tables, where each row may have an action item, or a toggleable state that shouldn't bounce around as the user interacts with it.

⚠️ **GitHub.com Fallback** ⚠️