2

I am much more of a back-end guy than a Javascript guy. Forgive me for what is probably a Javascript/Jquery newbie question.

When I find myself writing code such this:

var rowDiv = "<div class='row small'> <div class='col-sm-8 small'>" 
    + json['commentary'] + " &ndash; " + json['creation_date'] 
    + "</div><div class='col-sm-4 small'>by "
    +  json['user']
    + "</div></div>"
$('#commentary-container').append(rowDiv)

My code smells detector flashes massive red lights and sounds deafening klaxons. Creating structured data in repeated string concatenation just seems wrong to me.

Is there a programmatic way to create new elements? That might look like;

var rowDiv = $.div().setclass('row small').append(
    $.div().setclass('col-sm-8 small').html(json['commentary'])
) ... 

or something similar?

1
  • 1
    Your first code block is perfect. Creating elements in a programmatic way will quickly appear to be more messy than concatenating strings. Anyway, if you want to make a clever choice, you should compare performances : jsperf.com. Commented Mar 2, 2014 at 7:18

4 Answers 4

7

If you are creating many elements dynamically you can consider using templating libraries like Handlebars or Mustache. Using jQuery you can create the elements this way:

var $rowDiv = $('<div/>', {
   'class': 'row small',
   'html' : $('<div/>', { 'class': 'col-sm-8 small' }).html(json['commentary'])
});

How does this work?

jQuery check to see whether it has the corresponding method for the specified property or not, if it has the corresponding method, it calls that method with the specified value, otherwise it sets the value using .attr() method.

// HANDLE: $(html, props)
if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
    for ( match in context ) {
        // Properties of context are called as methods if possible
        if ( jQuery.isFunction( this[ match ] ) ) {
            this[ match ]( context[ match ] );

        // ...and otherwise set as attributes
        } else {
            this.attr( match, context[ match ] );
        }
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

{'class': 'col-sm-8 small', 'html': json['commentary']}); following the same principle
+1 for using the extra object parameter to initialize the created element. I personally find that much better than a huge list of fluent method calls.
thank you very much I'll have a look at the Handlebars and/or Mustache site!
1

You could create the new div element as a new jQuery element and use functions to set its class/contents then simply append that jQuery element wherever you want. Try something like this:

var newDiv = $('<div/>').addClass('row small').html(json['commentary']);
$('#commentary-container').append(newDiv);

Comments

1

For this type of thing I've used a templating system like handlebars in the past(http://handlebarsjs.com/). It basically allows you to define templates that you can inject data into easily. Your example might look something like this in a template:

<div class='row small'> 
  <div class='col-sm-8 small'>
    {{commentary}} &ndash; {{creation_date}}
  </div>
  <div class='col-sm-4 small'>
    by {{user}}
  </div>
</div>"

Take a look at the handlebars site. I thought they did a great job of laying out some basic examples.

Comments

0

You could do something like -

$("<input>").addClass('row small').appendTo("#add");

See this JSFiddle adding the new input and class

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.