2

I need to build HTML from an jQuery ajax response. I don't like nesting ugly strings in javascript and I don't want to use mustache or any other templating script.

So I went for the approach of having a template HTML with display: none like the following:

<div id="message-template" class="message-tile" style="display: none;">
    <div class="profile-thumb"><img src="{{thumb-url}}" width="48" height="48" alt="{{person-name}}" /></div>
    <div class="message-data">
        <div class="message-info">
            <div class="sender-name">
                <a href="{{person-url}}">{{person-name}}</a>
            </div>
            <div class="posted-to">
                To <a href="{{posted-to-url}}">{{posted-to-title}}</a>
            </div>
        </div>
        <div>{{message-body}}</div>
    </div>
</div>

I want to be able to replace the strings between {{ }} with the actual values from the json object. Suppose this is the function that gets called on the jQuery.ajax onSuccess event:

function createNewElement(jsonObj) {
    var $clone = $('#message-template').clone();
    $clone.replaceString("{{person-name}}", jsonObj.personName);
    $clone.replaceString("{{thumb-url}}", jsonObj.thumbUrl);
    $clone.replaceString("{{person-url}}", jsonObj.personUrl);
    // etc
    $("#target-container").append($clone);
}

I invented the replaceString method, but is there something similar? Or do I need to traverse through each element child using find() ?

3 Answers 3

5

Actually you can use <script type = "text/template"> to create your own templates, this way it won't render on your page:

<script id="message-template" type = "text/template">

    <div class="message-tile" style="display: none;">
        <div class="profile-thumb"><img src="{{thumb-url}}" width="48" height="48" alt="{{person-name}}" /></div>
        <div class="message-data">
            <div class="message-info">
                <div class="sender-name">
                    <a href="{{person-url}}">{{person-name}}</a>
                </div>
                <div class="posted-to">
                    To <a href="{{posted-to-url}}">{{posted-to-title}}</a>
                </div>
            </div>
            <div>{{message-body}}</div>
        </div>
    </div>

</script>

Here's how you substitute your values:

function createNewElement(jsonObj) {
    var $clone = $('#message-template').html();
    $clone = $clone.replace("{{person-name}}", jsonObj.personName)
                   .replace("{{thumb-url}}", jsonObj.thumbUrl)
                   .replace("{{person-url}}", jsonObj.personUrl);
    // etc
    $("#target-container").append($clone);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Excellent! I didn't know what a script of type="text/template" was. Pretty elegant solution. Just one more question. Is there a .replaceAll because I have more than 1 occurrence of {{person-name}}
No, but I found this here on SO or you maybe can implement your own. :p
1

There is a replace() method that can accept a regex, which would make it much more flexible.

Something like this would do it...

html.replace(/\{\{([^}]+)\}\}/g, function(all, key) {                   
                return jsonObj[key] || all;
            });

That way, {{personName}} would get the value from jsonObj.personName.

2 Comments

Using the regex to replace the value by the corresponding key is a really interesting solution. Is there a format other than {{x}} that can make the regex simpler to replace {{x}} with obj.x? Maybe #[x]# or something
@TKoL Indeed you could do that, though you'd still need to escape the brackets. Double braces are pretty common in templating languages.
1
function createNewElement(jsonObj) {
    var $clone = $('#message-template').clone();
    $clone.html($clone.html().replace("{{person-name}}", jsonObj.personName));
    $clone.html($clone.html().replace("{{thumb-url}}", jsonObj.thumbUrl));
    $clone.html($clone.html().replace("{{person-url}}", jsonObj.personUrl));
    // etc
    $("#target-container").append($clone);
}

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.