3

I'm new to using templates and I have a question about reusing them. On load, I get the template and data:

$(function() {
    var source, content;
    $.get('/templates/template.html', function(data) {
        source = data;
    })
    $.getJSON("/data/data.php", function(data) {
        content = data;
    })
    $(document).ajaxStop(function() {
        window.template = Handlebars.compile(source);
        $('#user-list tbody').html(window.template(content));
    })
})

The template is as follows:

{{#users}}
<tr>
    <td> {{name}} </td>
</tr>
{{/users}}

Here's the HTML in the same file:

<div id="content-div">
    <table id="user-list">
        <thead></thead>
        <tbody></tbody>
    </table>
</div>

How would I reuse this template when I want to append a row? For example:

function loadMore() {
    $.ajax({
        type : 'POST',
        url : '/data/more.php',
        dataType : 'json',
        success : function(data) {
            $('#user-list tbody').append(window.template(data));
        }
    });
}

It gets the data but won't append to the tbody. Why is this?

Update: Also, is it possible to put the entire table structure in the template file as such?

<table id="user-list">
    <thead></thead>
    <tbody>
        {{#users}}
        <tr>
            <td> {{name}} </td>
        </tr>
        {{/users}}
    </tbody>
</table>

Only on the initial page load would it pull in the entire structure but when I want to append additional rows, it would just append the <tr> portion.

Update: Maybe an off-topic side question but is this generally the correct way to approach this situation? I envision a folder full of templates that I can just pull in and use them when I need them. Is it correct to grab them via an ajax call?

SeanWM
  • 16,789
  • 7
  • 51
  • 83

5 Answers5

0

It's not related to the structure of your template, or to the use of append. Something else is getting fouled up. I wrote the following fiddle to demonstrate. Set var template = "#Template1"; to "#Template2" if you wish to compare templates.

See: http://jsfiddle.net/mcw0933/GnZ9M/

mcw
  • 3,500
  • 1
  • 31
  • 33
0

What if instead of using the success method of the ajax request, you try using a promise?

function loadMore() {
    $.ajax({
        type : 'POST',
        url : '/data/more.php',
        dataType : 'json'
    }).promise().always(function(data){
       $('#user-list tbody').append(window.template(data));
  });
}
MichaelKaeser
  • 162
  • 1
  • 2
  • 12
0

With regards to your update/side-question, I think this is how you approach that situation.

In general, your templates are not going to be large (byte-size-wise) in the request. However, I think it's simple enough to write in a "include the relevant templates when they are needed" based on the view you are currently in. Note, this is how Rails is set up to do JS and CSS, so you can implement something like a handlebars.html for each given relevant model/view, and set up a tag that pulls in those views in the footer before the JavaScript is executed.

However, a better direction is more likely precompilation. http://handlebarsjs.com/precompilation.html. Here's a promising Rails-y option: https://github.com/leshill/handlebars_assets

0

About your first question, I think that as somebody already pointed out, the right syntax is:

{{#each users}}
  <tr>
    <td> {{name}} </td>
  </tr>
{{/each}}

(unless you've created your custom helper "users" of course.)

Changed that, and it is still not working: are you testing it in IE 8 or 7? Internet Explorer 7 or 8 have the innerHTML property read-only for tables, so you have to use a workaround...

About the question to put the entire table in the template: yes, you can.

When requesting more data if the table is there you can just append the new rows.

Of course again if you have to be compliant also with IE in general you have to create a new table bigger than the previous one as a workaround.

It might be useful in this case the use of partials: the table would be the general template and the row will be a partial of it.

About the AJAX call instead, because templates are usually quite small, I would use an if/else statement so that when compiling the page all the templates you need will be already there ready to use - and use the AJAX call to get just the data.

Community
  • 1
  • 1
MarcoL
  • 9,829
  • 3
  • 37
  • 50
0

How would I reuse this template when I want to append a row?

I would need a demo set up to help you debug this program, try jsfiddle.net.

Also, is it possible to put the entire table structure in the template file as such?

Yes.

Maybe an off-topic side question but is this generally the correct way to approach this situation? I envision a folder full of templates that I can just pull in and use them when I need them. Is it correct to grab them via an ajax call?

What I do, is use requirejs to load the templates as module dependencies:

  1. Add the template file as a dependency using the requirejs "text" plugin.
  2. In my build script:

    a. The template files are compiled.

    b. The compiled template files (now javascript files) are optimized with the rest of the javascript files using the "r.js" optimizer included with requirejs.

  3. The result is that the templates are included in one compressed javascript file with all of the rest of the javascript for the site. I also have it set up to load different javascript bundles based on user permissions, since I know certain users aren't going to be executing the JavaScript which they can't execute because they don't have the user permissions to execute the user functions which execute the JavaScript.

There are many tutorials scattered throughout the Internet describing how to set this up. If you decide to go this route, let me know and I will post a few more resources.

Rick Suggs
  • 1,582
  • 1
  • 15
  • 30