zappee
zappee

Reputation: 22656

html template with jquery

I am trying to create a simple html template with jquery like this:

<div id="template" style="display: none">
   <div id="d1">1st line</div>
   <div id="d2">last line</div>
</div>

<div id="host"></div>

javascript:

var descriptions = [
    {'id': '1', 'author': 'Joe'},
    {'id': '2', 'author': 'Mary'},
    {'id': '3', 'author': 'Eric'}
];

// execute when page has fully loaded
window.onload = function () {
    var host = $("#host");
    var template = $("#template");

    for (var i = 0; i < descriptions.length; i++) {
        var description = descriptions[i];

        var id = "#" + description.id;
        console.log(id);
        template.find("div#d2").html(description.author);
        template.find("div#d1").attr("id", id);

        host.append(template.html());
    }
}

It works fine except the changing id part. Each inserted part has the same id: "#1" but i can see the proper content in the console log: #1, #2, #3

<div id="host">
  <div id="**#1**">1st line</div>
  <div id="d2">Joe</div>
  <div id="**#1**">1st line</div>
  <div id="d2">Mary</div>
  <div id="**#1**">1st line</div>
  <div id="d2">Eric</div>
</div>

What is wrong here?

Upvotes: 2

Views: 1588

Answers (1)

Rory McCrossan
Rory McCrossan

Reputation: 337560

The issue is because in each iteration you're looking at the original #template element. The first iteration changes the id of the #d1 element. In further iterations, the element is not found by the id selector (as you changed it) hence it's appended with the value of the first iteration.

To solve this you should clone() a new copy of #template in each iteration of the loop. Try this:

window.onload = function() {
    var $host = $("#host");
    for (var i = 0; i < descriptions.length; i++) {
        var description = descriptions[i];
        var $template = $("#template").clone();
        $template.find("div#d2").text(description.author);
        $template.find("div#d1").prop("id", description.id);
        $host.append($template.html());
    }
};

Working example

Note that I removed the # from the value you set to the id attribute, as it will lead to confusion in your JS selectors and CSS rules. Also note the use of the text() and prop() methods over html() and attr(). You also could make full use of all jQuery's features by modifying your code to this:

$(window).on('load', function() {
    var $host = $("#host");
    $.each(descriptions, function(i, description) {
        var $template = $("#template").clone();
        $template.find("div#d2").text(description.author);
        $template.find("div#d1").prop("id", description.id);
        $host.append($template.html());
    });
});

Upvotes: 3

Related Questions