0

There are times that I need to assign a html snippet to a javascript var, such as,

var homePage =
    '<div>' +
        '<div class="header"><h1>Page Slider</h1></div>' +
        '<div class="scroller">' +
                '<ul class="list">' +
                '<li><a href="#page1"><strong>Build Bot</strong></a></li>' +
                '<li><a href="#page2"><strong>Medi Bot</strong></a></li>' +
                '<li><a href="#page3"><strong>Ripple Bot</strong></a></li>' +
            '</ul>' +
        '</div>' +
    '</div>';

This can work good, but it makes editing a bit hard. May I know any framework can do this elegantly?

Etheryte
  • 24,589
  • 11
  • 71
  • 116
Hammer
  • 8,538
  • 12
  • 44
  • 75
  • Yes, templates is the way to go. See http://stackoverflow.com/questions/766597/using-an-html-snippet-for-a-template-in-javascript-jquery – blurfus Jun 03 '14 at 18:15
  • 2
    Templating, like Nit says, or a more fully-fledged solution in something like Knockout/Angular/(Ember? haven't used it)/etc, where you define your HTML in HTML files then bind elements to your JS model, may be worth looking into – Shai Jun 03 '14 at 18:16
  • 1
    You could also use RequireJS and import the contents of a separate html text file as a dependency. But you should just use templates. They're established because they're good. – Keen Jun 03 '14 at 18:17
  • Thanks. If I want to put a handlebars template in a separate JS to be loaded with requirejs, shall I use https://github.com/SlexAxton/require-handlebars-plugin? – Hammer Jun 04 '14 at 03:58
  • or is it a better practice to put the templates in HTML file instead? – Hammer Jun 04 '14 at 04:21
  • it ends up I am using Koorich's lightweight way of fetching html template to render,http://stackoverflow.com/questions/8366733/external-template-in-underscore – Hammer Jun 04 '14 at 08:34

4 Answers4

2

Use handlebars.js this is how is works:

Server side:

Send a JSON object back to javascript. I usually use something like this: echo json_encode(array('object_name'=>$obj));

HTML

  1. Create a container on your page. <div id="#my_template_container"></div>

Javascript:

usually in your AJAX success function:

  1. Parse your data into a JSON object:
    var my_obj= JSON.parse(data);
  2. Create a reference to the template:
    var tmpl = $("#my_layout").html();
  3. Use the Handlebars engine to compile the template:
    var theTemplate = Handlebars.compile(tmpl);
  4. Append the template to the HTML
    $('#my_template_container').html(theTemplate(my_obj));

Template

  1. Access your object in the template by it's name, in this example it would be : object_name the variable I assigned in my echo json_encode(array('object_name'=>$obj)) statement from PHP.
  2. Access properties of the object using {{Property_Name}}.
  3. To access properties of object children use the nested path operator: {{Propert_Name.ID}}

   <script id="my_layout" type="text/x-handlebars-template">
        {{#object_name}}
         '<div>' +
                '<div class="header"><h1>Page Slider</h1></div>' +
                '<div class="scroller">' +
                        '<ul class="list">' +
                        '<li><a href="#page1"><strong>{{property1}}</strong></a></li>' +
                        '<li><a href="#page2"><strong>{{property2}}</strong></a></li>' +
                        '<li><a href="#page3"><strong>{{property3}}</strong></a></li>' +
                    '</ul>' +
                '</div>' +
            '</div>';
        {{/object_name}}

        </script>
Edward
  • 3,061
  • 6
  • 32
  • 52
  • Thanks. If I want to put a handlebars template in a separate JS to be loaded with requirejs, shall I use https://github.com/SlexAxton/require-handlebars-plugin? – Hammer Jun 04 '14 at 03:58
  • or is it a better practice to put the templates in HTML file instead? – Hammer Jun 04 '14 at 04:22
  • it ends up I am using Koorich's lightweight way of fetching html template to render,http://stackoverflow.com/questions/8366733/external-template-in-underscore – Hammer Jun 04 '14 at 08:35
1

I created a very light plugin, just for the times, when you just want to use some html inside js, and do not require a lot of options provided my templating frameworks and thus want to avoid heavy js.

Coffee script

(($) ->
  utCache = {}
  $.fn.ut = (tmplID, obj) ->
    _tmpl = (str) ->
      fn = "var p=[]; p.push('" + str.replace(/[\r\t\n]/g, " ").replace(/'(?=[^%]*%>)/g, "\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g, "',$1,'").split("<%").join("');").split("%>").join("p.push('") + "'); return p.join('');"
      new Function("o", fn)
    _getData = (ele) ->
      $(ele).html utCache[tmplID](obj)
    @each ->
      ele = this
      utCache[tmplID] = _tmpl($(tmplID).html()) unless utCache[tmplID]
      _getData ele
) jQuery

Javascript

(function($) {
  var utCache;
  utCache = {};
  return $.fn.ut = function(tmplID, obj) {
    var _getData, _tmpl;
    _tmpl = function(str) {
      var fn;
      fn = "var p=[]; p.push('" + str.replace(/[\r\t\n]/g, " ").replace(/'(?=[^%]*%>)/g, "\t").split("'").join("\\'").split("\t").join("'").replace(/<%=(.+?)%>/g, "',$1,'").split("<%").join("');").split("%>").join("p.push('") + "'); return p.join('');";
      return new Function("o", fn);
    };
    _getData = function(ele) {
      return $(ele).html(utCache[tmplID](obj));
    };
    return this.each(function() {
      var ele;
      ele = this;
      if (!utCache[tmplID]) {
        utCache[tmplID] = _tmpl($(tmplID).html());
      }
      return _getData(ele);
    });
  };
})(jQuery);

You can use it simply like,

$('#my-div').ut("#my-template", { name: 'jashwant'});

when we have following HTML:

<div id='my-div'></div>

<script type='javascript' id='my-template'>
  <p><%=o.name %> welcomes you !</p>
</script>
Jashwant
  • 28,410
  • 16
  • 70
  • 105
0

Do it with Javascript's document methods.

var topdiv = document.createElement('div');
var headerDiv = document.createElement('header');
var header = document.createElement('h1');
header.innerHTML = 'Page Slider';
headerDiv.appendChild(header);

// etc....

Or use templating.

geoff
  • 2,251
  • 1
  • 19
  • 34
0

Just use backslashes to escape line breaks.

Eg:

var homePage =
    '<div> \
        <div class="header"><h1>Page Slider</h1></div> \
        <div class="scroller"> \
                <ul class="list"> \
                <li><a href="#page1"><strong>Build Bot</strong></a></li> \
                <li><a href="#page2"><strong>Medi Bot</strong></a></li> \
                <li><a href="#page3"><strong>Ripple Bot</strong></a></li> \
            </ul> \
        </div> \
    </div>';

Use \n\ instead of \ if you want to include the line breaks in the string.

karliwson
  • 3,365
  • 1
  • 24
  • 46
  • Note that ANY CHARACTERS between the `\\` and the line break will wreck this method. This allows no whitespace and no comments at the ends of these lines. – Keen Jun 03 '14 at 18:41
  • You can always put them before the backslash. – karliwson Jun 03 '14 at 19:21
  • That would include the comments in the string. – Keen Jun 03 '14 at 21:19
  • If you don't want to see comments you just don't comment. HTML comments would be included even if the file was imported by Ajax or some templating engine. – karliwson Jun 03 '14 at 22:01
  • JavaScript comments, with `//`. HTML comments are naturally part of the HTML, so of course we would want those included anyway. – Keen Jun 04 '14 at 02:08
  • Thanks for the sharing. The templates solution works better if I can put every template in its own file. – Hammer Jun 04 '14 at 04:04
  • @Cory The string is HTML code, don't know why you would need to use javascript comments in it. If you need to comment the HTML code, use HTML comments inside the string. – karliwson Jun 04 '14 at 12:53
  • @Kekas I agree that you shouldn't want to put JS comments there, but it's still important to know that it's just plain not allowed. – Keen Jun 04 '14 at 19:59