views:

788

answers:

6

I'm calling a web service that returns an array of objects in JSON.

I want to take those objects and populate a div with html. Let's say each object contains a url and a name.

If i wanted to generate the following html for each object:

    <div><img src="the url" />the name</div>

Is there a best practice for this? I can see three ways of doing it:

  1. Concatentate strings
  2. Create elements
  3. Use some sort of templating plugin like http://beebole.com/pure/ which seems like a cool yet immature technology

  4. UPDATE, a friend suggested the following: generate the html on the server, then serve up via json, this is faster and allows you to reuse the template on any server side stuff you are doing

+5  A: 

Either of the first two options is both common and acceptable.

I'll give examples of each one in Prototype.

// assuming JSON looks like this:
// { 'src': 'foo/bar.jpg', 'name': 'Lorem ipsum' }

Approach #1:

var html = "<div><img src='#{src}' /> #{name}</div>".interpolate(json);
$('container').insert(html); // inserts at bottom

Approach #2:

var div = new Element('div');
div.insert( new Element('img', { src: json.src }) );
div.insert(" " + json.name);
$('container').insert(div); // inserts at bottom
savetheclocktower
Building generating the HTML explicitly with strings rather than DOM elements is more performant (assuming string concatenation isn't a real issue) and readable.
Rodrick Chapman
In IE string concatenation always is an issue. Use an array instead.
some
+10  A: 

Options #1 and #2 are going to be your most immediate straight forward options, however, for both options, you're going to feel the performance and maintenance impact by either building strings or creating DOM objects.

Templating isn't all that immature, and you're seeing it popup in most of the major Javascript frameworks.

Here's an example in JQuery Template Plugin that will save you the performance hit, and is really, really straightforward:

var t = $.template('<div><img src="${url}" />${name}</div>');

$(selector).append( t , {
     url: jsonObj.url,
     name: jsonObj.name
});

I say go the cool route (and better performing, more maintainable), and use templating.

Jim Fiorato
Ach, man, I was looking for that just the other day.
Tchalvak
+2  A: 

Here's an example, using my Simple Templates plug-in for jQuery:

var tmpl = '<div class="#{classname}">#{content}</div>';
var vals = {
    classname : 'my-class',
    content   : 'This is my content.'
};
var html = $.tmpl(tmpl, vals);
Andrew Hedges
Neat. I could have used something that like on a big project a few months ago.
Rodrick Chapman
A: 

You could add the template HTML to your page in a hidden div and then use cloneNode and your favorite library's querying facilities to populate it

/* CSS */
.template {display:none;}

<!--HTML-->
<div class="template">
  <div class="container">
    <h1></h1>
    <img src="" alt="" />
  </div>
</div>

/*Javascript (using Prototype)*/
var copy = $$(".template .container")[0].cloneNode(true);
myElement.appendChild(copy);
$(copy).select("h1").each(function(e) {/*do stuff to h1*/})
$(copy).select("img").each(function(e) {/*do stuff to img*/})
Leo
A: 

Errh, yes. Don't...!! ;)

Or if you absolutely have to you could check out Builder.node in prototype.js...

Thomas Hansen
Errrrr, ever hear of AJAX? One of the most common things to do with an AJAX response is to modify the DOM in some way. -1
Greg Dean
+3  A: 

If you absolutely have to concatenate strings, instead of the normal :

var s="";
for (var i=0; i < 200; ++i) {s += "testing"; }

use a temporary array:

var s=[];
for (var i=0; i < 200; ++i) { s.push("testing"); }
s = s.join("");

Using arrays is much faster, especially in IE. I did some testing with strings a while ago with IE7, Opera and FF. Opera took only 0.4s to perform the test, but IE7 hadn't finished after 20 MINUTES !!!! ( No, I am not kidding. ) With array IE was very fast.

some
Don't you love IE JavaScript performance? :P
alex
I switched browser a long time ago, so I don't suffer that much. IE was a horrible browser but it is getting better. But I doubt I will ever switch back.
some