Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically load jQuery templates

For jQuery template:

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

I want to be able to dynamically load the templates from a server, rather than predefining it on the page.

The demos I saw on the projects are using predefined templates. After some research I found out that it is possible.

I try doing this and it doesn't work:

<script src="child.html" type="text/x-jquery-tmpl"></script>

I tried doing this and it doesn't work:

$(function () {
    $.get("child.html", function (data) {
        //Add template
        $.template("tmplChild", data);
    });

    //template binds before async call is done
    $.tmpl("tmplChild").appendTo("body");
});

And finally, I have get it down to the following hack:

so.html (This is the main page):

<html>
<head>
<title></title>
</head>
<body>

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.js"></script>

<script type="text/javascript" src="so.js"></script>

<script type="text/javascript">

    $(function () {
        initTemplates(templateReady);
    });

    function templateReady() {
        $.tmpl("tmplChild").appendTo("body");
    }

</script>
</body>
</html>

child.html (This is the child template)

<h1>Child Loaded</h1>

so.js (This is my hack for ajaxly loading the js templates)

function initTemplates(callback) {
    var templateUrl = "child.html";
    var templateName = "tmplChild";

    initTemplate(templateUrl, templateName, callback);
}

function initTemplate(url, name, callback) {
    var opts =
        {
            type: "GET",
            url: url,
            dataType: ($.browser.msie) ? "text" : "xml",
            success: function (data) {
                xmlCallback(data, name, callback);
            },
            error: function (x) {
                xmlCallback(x.responseText, name, callback);
            }
        }

    $.ajax(opts);
}

function xmlCallback(data, name, callback) {

    if (typeof data != "string") {
        if (window.ActiveXObject) {
            var str = data.xml;
            data = str;
        }
        // code for Mozilla, Firefox, Opera, etc.
        else {
            var str = (new XMLSerializer()).serializeToString(data);
            data = str;
        }
    }

    //only takes strings!
    $.template(name, data);

    callback();
}

And here's what I don't like about it.

  1. This doesn't work on Chrome
  2. It seems like a lot of code just to load some template
  3. I lost the ability to use $(document).ready(). I must now put all my code in this templateReady() method to be "template safe".

Is there a way around this?

Thanks,

Chi

like image 928
Chi Chan Avatar asked Nov 01 '10 20:11

Chi Chan


2 Answers

Just load the template body as simple text and forget about putting it in a dummy <script> block. You can use $.tmpl(body, params) to populate the template and turn it into a string for appending to the DOM.

The whole thing with "not really script" <script> blocks is just a convenience useful in some situations.

edit — example:

$.get("/some/url/for/a/template", function(templateBody) {
  var expandedTemplate = $.tmpl(templateBody, { param1: 0, param2: "Hello World" });
});
like image 131
Pointy Avatar answered Oct 06 '22 00:10

Pointy


If the goal is to fetch a unique template each time you get data via ajax, then you might try fetching the template at the same time and include it in your data, that is if you have the luxury of modifying the returned object (anonymous object in .Net). Then you can store the template anywhere you want and you only need 1 ajax call for both the data and the template.

like image 22
Silkster Avatar answered Oct 06 '22 00:10

Silkster