views:

427

answers:

4

Hello, In an example I am having this structure (small example):

<table id=example>
<tr class="blah test example"><td>Test1</td><td><a href="url">LINK</a>Test11</td></tr>
<tr class="blah test example"><td>Test2</td><td><a href="url">LINK</a>Test22</td></tr>
<tr class="blah test example"><td>Test3</td><td><a href="url">LINK</a>Test33</td></tr>
</table>

In jQuery I would create it dynamically like:

var test = "<table id=" + someIDVar + ">"
           + "<tr class=" + classOneVar 
+ classTwoVar + classThreeVar + ">"....

and etc etc... (lots of other stuff to write). After I would just append it:

$(".somePlaceInHtml").append(test);

So is there any other way to write such a structure dynamically with jQuery? This is a problem for me because I am having a big structure, not as small as I showed in the example. The main reason is I want to get better readability for myself and other developers who will maintain this code. Thanks for any advice!

+2  A: 

Can you make a "template" out of your string? If yes, then store it in a "constant" variable (e.g. defined in global scope), containing placeholders for actual variables, like {0}, {1} etc, as you would use it in C#'s string.format() method.

So, you would have code like this:

var rowTemplate = "<tr><td>{0}</td><td>SomePredefinedText {1}</td></tr>";
var alternateRowTemplate = "<tr><td class='a'>{0}</td><td>SomewhatDifferent {1}</td></tr>";
 ...... somewhere deep in your code
 $("#someElement").append(
        rowTemplate.format("myvalue1", "myvalue2")
       ).append(
        alternateRowTemplate.format("myvalue3", "myvalue4")
       );

You would then use the string.format implementation as per this answer: http://stackoverflow.com/questions/1038746/equivalent-of-string-format-in-jquery/1038930#1038930

naivists
+1  A: 

Here's a simplified example:

  $(function() {
    var tbl = $('<table></table>').attr({ id: "bob" });
    var row = $('<tr></tr>').attr({ class: ["class1", "class2", "class3"].join(' ') }).appendTo(tbl);
    $('<td></td>').text("text1").appendTo(row);
    $('<td></td>').text("Test22").prepend($('<a></a>').attr({ href: "#" }).text("LINK")).appendTo(row);        
    tbl.appendTo($(".somePlaceInHtml"));        
  });

Wrap the row portion in a loop, replace with variables and it's at least easier to maintain/read in my opinion, but I'm used to jQuery, so your mileage may vary, just an option.

A side note, since this is using .text() everywhere, it helps prevents cross-site scripting attacks within your output as well.

Nick Craver
+1  A: 

You could create a StringBuilder, much like the one in C#. Here's a snippet took from Telerik Extensions for ASP.NET MVC:

$.stringBuilder = function() {
    this.buffer = [];
};

$.stringBuilder.prototype = {

    cat: function(what) {
        this.buffer.push(what);
        return this;
    },

    string: function() {
        return this.buffer.join('');
    }
};

This way, you can have the following code:

var html = new $.stringBuilder();
for (var i in data)
    html.cat("<tr><td>").cat(i).cat("</td><td></tr>");

$('#element').append(html.string());

The benefit of this approach is that you'll have fast concatenation (array joins perform better under IE6), and you could extend the object with other useful function (say, catIf that takes a boolean expression, or rep that repeats a given string several times).

Alexander Gyoshev
Array joins *were* faster in IE6. In present browsers, the speed is approximately the same - sometimes string concatenation is faster, sometimes array joining. See my benchmarks here: http://tips.naivist.net/2010/01/19/string-concatenation-versus-array-join-in-javascript/
naivists
note taken! thanks - and here's one more article that I found on the subject: http://james.padolsey.com/javascript/fastest-way-to-build-an-html-string/ - seems that the join is best ;-)
Alexander Gyoshev
+1  A: 

Or you could instead of concatenating strings together so make use of the array.join function.

    for(var i=0;i<arr.length;i++)
    {
      arr[i] = "<tr>" + sth + "</tr>";       
    }

node.innerHTML = arr.join(''); 
poo