15

It is very often I come across a situation in which I want to modify, or even insert whole blocks of HTML into a page using JavaScript. Usually it also involves changing several parts of the HTML dynamically depending on certain parameters.

However, it can make for messy/unreadable code, and it just doesn't seem right to have these little snippets of HTML in my JavaScript code, dammit.

So, what are some of your techniques to avoid mixing HTML and JavaScript?

5 Answers 5

4

The Dojo toolkit has a quite useful system to deal with HTML fragments/templates. Let's say the HTML snippet mycode/mysnippet.tpl.html is something like the following

<div>
  <span dojoAttachPoint="foo"></span>
</div>

Notice the dojoAttachPoint attribute. You can then make a widget mycode/mysnippet.js using the HTML snippet as its template:

dojo.declare("mycode.mysnippet", [dijit._Widget, dijit._Templated], {
  templateString: dojo.cache("mycode", "mysnippet.tpl.html"),

  construct: function(bar){
    this.bar = bar;
  },
  buildRendering: function() {
    this.inherited(arguments);
    this.foo.innerHTML = this.bar;
  }
});

The HTML elements given attach point attributes will become class members in the widget code. You can then use the templated widget like so:

new mycode.mysnippet("A cup of tea would restore my normality.").placeAt(someOtherDomElement);

A nice feature is that if you use dojo.cache and Dojo's build system, it will insert the HTML template text into the javascript code, so that the client doesn't have to make a separate request.

This may of course be way too bloated for your use case, but I find it quite useful - and since you asked for techniques, there's mine. Sitepoint has a nice article on it too.

Sign up to request clarification or add additional context in comments.

Comments

2

There are many possible techniques. Perhaps the most obvious is to have all elements on the page but have them hidden - then your JS can simply unhide them/show them as required. This may not be possible though for certain situations. What if you need to add a number (unspecified) of duplicate elements (or groups of elements)? Then perhaps have the elements in question hidden and using something like jQuery's clone function insert them as required into the DOM.

Alternatively if you really have to build HTML on the fly then definitely make your own class to handle it so you don't have snippets scattered through your code. You could employ jQuery literal creators to help do this.

Comments

1

I'm not sure if it qualifies as a "technique", but I generally tend to avoid constructing blocks of HTML in JavaScript by simply loading the relevant blocks from the back-end via AJAX and using JavaScript to swap them in and out/place them as required. (i.e.: None of the low-level text shuffling is done in JavaScript - just the DOM manipulation.)

Whilst you of course need to allow for this during the design of the back-end architecture, I can't help but think to leads to a much cleaner set up.

4 Comments

So do you store blocks of HTML in a back-end database or in the server-side code?
@El Ronnoco - The raw data is in the DB, but is HTMLised in server-side code. Depending on the size/complexity/overhead, it's also potentially cached in HTML format on disk for speed of access.
@El Ronnoco Obviously if you're creating a custom editor, JavaScript is the place to do it, but it just feels odd using it to kludge together blocks of HTML.
Agreed, it's a nasty business. I really dislike seeing code with strings being concatenated all through it. Same with building SQL on the fly. Yuk!
0

Sometimes I utilise a custom method to return a node structure based on provided JSON argument(s), and add that return value to the DOM as required. It ain't accessible once JS is unavailable like some backend solutions could be.

Comments

0

After reading some of the responses I managed to come up with my own solution using Python/Django and jQuery.

I have the HTML snippet as a Django template:

<div class="marker_info">
    <p> _info_ </p>
    <a href="{% url index %}"> more info... </a>
</div>

In the view, I use the Django method render_to_string to load the templates as strings stored in a dictionary:

snippets = { 'marker_info': render_to_string('templates/marker_info_snippet.html')}

The good part about this is I can still use the template tags, for example, the url function. I use simplejson to dump it as JSON and pass it into the full template. I still wanted to dynamically replace strings in the JavaScript code, so I wrote a function to replace words surrounded by underscores with my own variables:

function render_snippet(snippet, dict) {

    for (var key in dict)
    {
        var regex = new RegExp('_' + key + '_', 'gi');
        snippet = snippet.replace(regex, dict[key]);
    }

    return snippet;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.