0

Hi Guys I'm working on a web app that outputs a heap of html and objects onto a html page via javascript.

Its looking quite messy and that made me wonder - What is the optimum way to write this and why.

this is my code

var html_content = '';
     html_content += "<div class='body-content'>";
        html_content += "<h1>" + wowArr.name +"</h1><br />" + "<h2> Arena Titles (Account Wide)</h2>" + achievementZ.join('<br />') + "<br /><br />" 

                + "<h2>Highest Arena Ratings</h2>" 

                + "<span style='color: #FFFFFF;'>"+rating2v2.name+"</span>" + ": " + rating2v2.quantity + "<br/>" + "Last Reached On: " + getHighestDate(rating2v2) + "<br/><br/>"

                + "<span style='color: #FFFFFF;'>"+rating3v3.name+"</span>" + ": " + rating3v3.quantity + "<br/>" + "Last Reached On: " + getHighestDate(rating3v3) + "<br/><br/>"

                + "<span style='color: #FFFFFF;'>"+rating5v5.name+"</span>" + ": " + rating5v5.quantity + "<br/>" + "Last Reached On: " + getHighestDate(rating5v5) + "<br/><br/>"

                + "<h2>Current Arena Rating</h2>2v2 Rating: " + wow2s + '<br />' + "3v3 Rating: " + wow3s + '<br />' + "5v5 Rating: " + wow5s + '<br /><br />'  

                + "<h2>Current RBG Rating</h2>RBG Rating: " + wowRBGs + '<br /><br />' 

                + '<input type="button" class="homebtn" name="startGame" value="new" onclick="reloadW();">';
     html_content += "</div>";

    $('.main-content').html(html_content);

To me it looks like theres a better way to do this but I don't have the slightest where to start.

Any direction or help would be appreciated!

Codegenesis G
  • 79
  • 1
  • 1
  • 9
  • Possible duplicate of [How to insert a large block of HTML in JavaScript?](http://stackoverflow.com/questions/16270761/how-to-insert-a-large-block-of-html-in-javascript) – Andrew Jan 16 '16 at 01:44

4 Answers4

1

You can use a "multi-line" string in javascript by bypassing the line-breaks using \:

var html_content = "
    <div class='body-content'>\
        <h1>" + wowArr.name + "</h1><br />\
        <h2> Arena Titles (Account Wide)</h2>" + achievementZ.join('<br />') + "\
        <br /><br />\
        <h2>Highest Arena Ratings</h2>\
        <span style='color: #FFFFFF;'>" + rating2v2.name + "</span>" + ": " + rating2v2.quantity + "<br/>" + "Last Reached On: " + getHighestDate(rating2v2) + "<br/><br/>\
        <span style='color: #FFFFFF;'>" + rating3v3.name + "</span>" + ": " + rating3v3.quantity + "<br/>" + "Last Reached On: " + getHighestDate(rating3v3) + "<br/><br/>\
        <span style='color: #FFFFFF;'>" + rating5v5.name + "</span>" + ": " + rating5v5.quantity + "<br/>" + "Last Reached On: " + getHighestDate(rating5v5) + "<br/><br/>\
        <h2>Current Arena Rating</h2>2v2 Rating: " + wow2s + '<br />' + "3v3 Rating: " + wow3s + '<br />' + "5v5 Rating: " + wow5s + "<br /><br />\
        <h2>Current RBG Rating</h2>RBG Rating: " + wowRBGs + '<br /><br />\
        <input type="button" class="homebtn" name="startGame" value="new" onclick="reloadW();">\
    </div>";
Filipe
  • 1,788
  • 2
  • 13
  • 18
1

You can use the es6 template string.

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

so you dont have to use all the +..

for more: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/template_strings

Alon
  • 2,919
  • 6
  • 27
  • 47
1

Here are the most common ways people prefer to write very long strings in JavaScript. I attempted to put them in decreasing order by my own subjective preferences.

ES6 Template strings

If you have access to ES6 features, this is the best way to go. These template strings are multiline by definition.

var foo = 7;
console.log(`
  <div>${foo-1}</div>
  <div>${foo+1}</div>
`);

Prints:

<div>6</div>
<div>8</div>

Compiled to ES5 (babel/repl):

"use strict";
var foo = 7;
console.log("\n  <div>" + (foo - 1) + "</div>\n  <div>" + (foo + 1) + "</div>\n");

Escape newline in string literal:

var foo = 7;
console.log("\
  <div>" + (foo-1) + "</div> \
  <div>" + (foo+1) + "</div> \
");

Concatenated expression

var foo = 7;
console.log(""
  +"<div>" + (foo-1) + "</div>\n"
  +"<div>" + (foo+1) + "</div>\n"
);

Build string line-by-line

var foo = 7;
var tmp = '';
tmp += '<div>' + (foo-1) + '</div>\n';
tmp += '<div>' + (foo+1) + '</div>\n';
console.log(tmp);

Array join

var foo = 7;
console.log([
  '<div>' + (foo-1) + '</div>',
  '<div>' + (foo+1) + '</div>'
].join('\n'));

Consider using JSX

This is a different approach, but provides a safer way to interact with the DOM:

var foo = 7;
var shadowDom = <div>
  <div>{foo-1}</div>
  <div>{foo+1}</div>
</div>;

See Babel repl

Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97
  • for my current situation what in your opinion is the optimum way to do this and how would you determine what the optimum way is. Like is it based on how many lines of code you write or something else. Thanks in advance – Codegenesis G Jan 16 '16 at 02:06
  • @CodegenesisG By what measure do you search for an optimum? Least lines? Put everythin in one line. Least characters? Use template srings. Most readable? That is subjective, I think template strings are the way to go in this case too. Fastest? Not sure, but template strings should be just as fast as a concatenated expression. – Tamas Hegedus Jan 16 '16 at 02:16
1

ES6 template syntax from other answer is neat, and is definitely useful in some cases.

However, what you are really looking for is a lightweight templating engine.

Let me give you few reasons to use a template engine instead of concatenating strings:

  • it is THE cleanest way to solve your problem

  • you can separate your templates / data and rendering code, so it's easier to maintain

  • your get security for free: {{variables}} are automatically escaped (see how i escaped "name" variable in the example below)

  • since you have a achievementZ.join(), i assume that you wanted to loop through achievements to display it and that your templates will become more complex with loops, conditional statements etc... A templating engine can handle all that: loops, conditions and even function calls

  • no need to worry about compatibility, you can use this method pretty much anywhere

  • it is very flexible and if you want you can automatically compile your templates into js variables, so ultimately you could embed your templates into .js files and keep all the advantages above

Here is a full rewrite of your code using mustache templating engine (mustache.js) :

<!doctype html>
<head>
</head>
<body>
  <div id="main-content"></div>
</body>

<!-- here is your template -->
<script id="template" type="x-tmpl-mustache">
       <div class='body-content'>
            <h1>{{ name }}</h1><br />
            <h2> Arena Titles (Account Wide)</h2>
             {{#achievementZ}}
               {{.}}<br/>
             {{/achievementZ}}
            <br/>
            <h2>Highest Arena Ratings</h2>
            <span style='color: #000;'> {{ rating2v2.name }}</span>: {{ rating2v2.quantity }}<br/>Last Reached On: {{ rating2v2.highestDate }} <br/><br/>
            <span style='color: #000;'>{{ rating3v3.name }}</span>: {{ rating3v3.quantity }}<br/>Last Reached On: {{ rating3v3.highestDate }}<br/><br/>
            <span style='color: #000;'>{{ rating5v5.name }}</span>: {{ rating5v5.quantity }}<br/>Last Reached On: {{ rating5v5.highestDate }}<br/><br/>
            <h2>Current Arena Rating</h2>2v2 Rating: {{ wow2s }}<br /> 3v3 Rating: {{ wow3s }}<br /> 5v5 Rating: {{ wow5s }}<br /><br />
            <h2>Current RBG Rating</h2>RBG Rating: {{ wowRBGs }}<br /><br />
            <input type="button" class="homebtn" name="startGame" value="new" onclick="reloadW();">
        </div>
</script>

<!-- templating engine -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.2.1/mustache.min.js"></script>

<!-- usage -->
<script>

  var getHighestDate = function() {
    var date = new Date();
    return date.getFullYear();
  };

  // your data
  var view = {
    name: "Super <b>Joe</b>",
    achievementZ: [
      "achievement 1",
      "achievement 2",
      "achievement 3",
      "achievement 4"
    ],
    rating2v2: {
      name: "Mr Red",
      quantity: 42,
      highestDate: getHighestDate
    },
    rating3v3: {
      name: "Mr Orange",
      quantity: 69,
      highestDate: getHighestDate
    },
    rating5v5: {
      name: "Mr Black",
      quantity: 666,
      highestDate: getHighestDate
    },
    wow2s: "wow2s text...",
    wow3s: "wow3s text...",
    wow5s: "wow5s text...",
    wowRBGs: "wow RGB..."
  };

  // rendering code
  document.getElementById("main-content").innerHTML = Mustache.render(document.getElementById("template").text, view);

</script>
dchapkine
  • 191
  • 5