user1985189
user1985189

Reputation: 669

Alternatives to Javascript string concatenation?

Our sign-in page for web apps currently uses javascript string concatenation to generate markup:

var signinHtml='<div>'+
    '    <form class="form-signin" method="post">'+
    '        <div class="form-signin-app-icon"></div>'+
    '        <h2 class="form-signin-heading">'+appName+'</h2> '+
    '        <h4 class="form-signin-heading-sub">'+appMotto+'</h4>'+
    '        <div class="form-signin-input">'+
    '            <input id="username" type="text" name="username" class="input-block-level" placeholder="Username"></input>'+
    '        </div>'+
    '        <div class="form-signin-input">'+
    '            <input type="password" name="password" id="password" class="input-block-level" placeholder="Password"></input>'+
    '        </div>'+
    '        <button class="btn btn-small btn-inverse form-signin-button" type="submit" id="signin">Sign in</button>'+
    '    </form>'+
    '</div>';       

    $(self).html(signinHtml);

This approach works but is messy, error-prone, and probably not the best way of doing it. From what I've read, arrays are more efficient performance-wise but even worse in terms of readability. Can anyone recommend a cleaner/better alternative?

Upvotes: 1

Views: 3548

Answers (4)

JustRaman
JustRaman

Reputation: 1161

USE TEMPLATE LITERALS

your code looks like this which use '+' several times and it looks ugly.

var a = 5;
var b = 10;
console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');
// "Fifteen is 15 and
// not 20."

How if i write code like this

var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."

All the latest browser except Safari , IE supporting template literals

Upvotes: 1

Tommy Brunn
Tommy Brunn

Reputation: 2562

I would suggest looking up template engines, such as Mustache or Handlebars.

Those would allow you to define your markup in a simple language that is then parsed by the template compiler so that they're available in your Javascript, so that all you have to do is pass in your data and get HTML back.

EDIT: An example of how this could work with Handlebars (I'm using that because it's what I used last, but the concepts are the same regardless of what you use).

First you create a template. The template is just your HTML, but you represent your data with tokens. It could look like this:

<div>
    <h1>My name is {{ name }}</h1>
    <p>Here's some information about me: {{ about }}</p>
</div>

That template has to be accessed somehow in your Javascript. The simplest way to do that is to simply put it in a script tag with a certain type:

<script id="my-template" type="text/x-handlebars-template">OUR TEMPLATE GOES HERE</script>

Then we have to compile the template. What that means is that the template engine takes the HTML-like text that we created, parses that and turns it into a javascript function. In handlebars, that is done like this:

var template = Handlebars.compile($('#my-template').html());

(Note that in this example I'm using jQuery to get the contents of the script tag)

template is now a Javascript function that will return HTML if I supply it with the data we need (name and about). So let's do that:

var data = {name: 'Tommy Brunn', about: 'I like cats and Belgian beer'};
var output = template(data);

output will now contain the HTML from our template, but with the tokens replaced with my data:

 <div>
    <h1>My name is Tommy Brunn</h1>
    <p>Here's some information about me: I like cats and Belgian beer</p>
</div>

This is just the simplest example of a template. Some templating languages allow you to do things like loop over lists, modify variables (for example, uppercasing) or perform selections ("if name is more than 5 letters long, reverse it").

In this example, the compilation of the template is done on the client side. That's fine in most cases, but if you need the extra performance, you probably want to do the compilation on the server side. Most (maybe all?) template engines provide you with a way to do that as part of your build process. What you'd end up with then is a Javascript file that contains the function that your template compiled to. Another benefit of that is that you won't need to include the full compiler on your site. You only need a smaller runtime instead.

Upvotes: 7

Shoreline
Shoreline

Reputation: 812

Angularjs also supplies some good template mechanisms, if you're looking for alternatives to those mentioned.

Upvotes: 0

Jason
Jason

Reputation: 4159

The best answer to the question has already been provided by Tommy Brunn above, however, there is a solution for if you are dealing with small snippets.

var element = $("<a />", {"href": "http://www.example.com", "target": "_blank", "class": "example-class"}).html("example.com");

parent.append(element);

It is particularly useful if you need to create elements that have a lot of dynamic attributes and require attached events and other interactions. I find it much cleaner than strings of text and then searching (.find()) through them after the fact to find elements.

Upvotes: 2

Related Questions