1

In my application, I sometimes have to create elements dynamically, so I create them in javascript, but it make it hard for maintenance.

For example:

enter image description here

The above image is the information window when I click a point in the map, and in our application we have a similar requirement, we use javascript to create the whole DOM.

I do not think this is a good idea, any suggestion?

1
  • There are two ways to create HTML with JavaScript: Writing the HTML as strings and use innerHTML to append it. This is bad in most cases. Or use the DOM API to create the elements which is perfectly fine to do so. Of course it will still be tedious for complex elements. Commented May 14, 2011 at 12:51

3 Answers 3

4

You can extract the JS-generated HTML into the templates instantiated on the client side. Check out JQuery templates for example:

http://api.jquery.com/category/plugins/templates/

Example:

<ul id="movieList"></ul>

<script id="movieTemplate" type="text/x-jquery-tmpl">
    <li><b>${Name}</b> (${ReleaseYear})</li>
</script>

<script type="text/javascript">
    var movies = [
        { Name: "The Red Violin", ReleaseYear: "1998" },
        { Name: "Eyes Wide Shut", ReleaseYear: "1999" },
        { Name: "The Inheritance", ReleaseYear: "1976" }
    ];

    // Render the template with the movies data and insert
    // the rendered HTML under the "movieList" element
    $( "#movieTemplate" ).tmpl( movies )
        .appendTo( "#movieList" );
</script>
Sign up to request clarification or add additional context in comments.

4 Comments

unfortunately we can not use the jquery lib since we are use the prototype,I am afraid it will cause the conflict problem,so ....
Well, you can just implement that kind of mechanism yourself then. The main idea is quite straightforward: special <script type="text/x-your-tmpl">, and then replace the placeholders with real data, and insert into the DOM. See github.com/jquery/jquery-tmpl/blob/master/jquery.tmpl.js for a reference
Thank you ,I will have a try. It seems that even the template should also been defined in the js.
@hguser: Templates are just text, you can either write them in the JS (but I get the impression you're trying to avoid that) or you can have them in a separate file you demand-load from the server, or you embed on the page with display: none. And good news: Prototype has templates (details in my answer).
1

Another approach using plain jQuery (I don't know Prototype, but I guess you can do the same thing pretty similar):

Template:

<div id="template" style="display: none">
    Hello, <span class="name">[world]</span>
</</div>

Rendering:

function render(name) {
    $('#template').clone().removeAttr('id')
        .find('.name').text(name).end()
        .appendTo('body').show();
    }

render("Stack Overflow");
render("..and world");

The idea is pretty simple: put your template hidden in HTML. When you need it, find it by id, remove this id, replace the data and add the newly created element where you want it.

Comments

0

You've said you're using Prototype. You could make use of its Template class. You could even store templates on the server and demand-load them via ajax if you like (although I'd worry about the number of HTTP requests), in order to keep your code and your markup completely distinct.

For instance, here's a Prototype template for building a table row:

<tr><td>#{name}</td><td>#{description}</td></tr>

You have various options for where and how to store the template text:

  • You can put it in its own file you demand-load via Ajax, although if there are a lot of them it could start being excessive HTTP requests.
  • You can put them in your JavaScript, but then you've tied your markup to your JavaScript and I get the impression you don't want to do that.
  • You can include them in your main page with display: none, extract them as HTML, and then reuse them.

In all three of those cases, eventually you end up with a string containing the template text, e.g.:

var rowString = "<tr><td>#{name}</td><td>#{description}</td></tr>";

(But again, you may not need to put it actually in the JavaScript.)

From the string, you make a template:

var rowTemplate = new Template(rowString);

And then use it:

$('tableBodyId').insert({
    bottom: rowTemplate.evaluate({
        name:        bizobject.name.escapeHTML(),
        description: bizobject.description.escapeHTML()
    })
});

Note that (sadly) you do have to do the HTML escaping yourself (because Prototype's templates aren't specifically tied to HTML, you can use them for any situation where you have a templated string). Or you can make a fairly small change to the Template class to do it for you (that's what I did, when I was using Prototype; I actually made it possible to call functions on template items).

2 Comments

It seems that the prototype1.4 does not support template. BTW,how about if I have to bind some event to the element?
@hguser: Prototype 1.4 was superceded more than four years ago. The current version is 1.7. Regarding binding: You do that in the usual way after you've instantiated them (e.g., after insert or what-have-you).

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.