7

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

Chi Chan
  • 11,890
  • 9
  • 34
  • 52

3 Answers3

4

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" });
});
Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Hi Pointy. I don't have a problem loading it without using the script. Doing $.tmpl(body, '

    I am hard coded

    ') is not using
    – Chi Chan Nov 01 '10 at 20:41
  • No no; you misunderstand. The first argument to `$.tmpl()` is the **template** - you fetch it from the server and pass that in as the first parameter. The **second** parameter would be the variables you want to bind. – Pointy Nov 01 '10 at 20:43
  • Opps...haha. I swear that's a typo. But what I meant is this: if you do a $.get() you need to apply the template in the callback AFTER you define your template. And you are running into problem 3). BTW, thanks for the quick reply!! – Chi Chan Nov 01 '10 at 20:50
  • Well, that's unavoidable. Dynamically fetching content is asynchronous, so you have to do everything in a callback. Why are you fetching XML instead of just the template text? – Pointy Nov 01 '10 at 20:53
  • About the xml, I have no idea, it seems IE is not liking it when I do "text". I am pretty sure there are better ways to load it but I just want to quickly demo it to the company without worrying about compact code. – Chi Chan Nov 01 '10 at 20:58
  • About async content, I was hoping that there are some method on jQuery to do something like onPreReady or something. I have a lot of existing code that uses $(document).ready() and pluging templates into the stack will surely not work if I can't find a point to load the templates before .ready() – Chi Chan Nov 01 '10 at 21:00
2

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.

Silkster
  • 2,190
  • 15
  • 28
  • JSON data is easiest, otherwise you'll need to encode your template markup for XML. – Silkster Nov 01 '10 at 21:05
  • Good idea. I guess the goal is to extend the plugin and if the template doesn't exist, ajax load it. I will have to look into the source code I guess. – Chi Chan Nov 01 '10 at 21:07
2

Refer here: https://www.npmjs.com/package/jlate

use CDN:

<script src="https://cdn.jsdelivr.net/combine/npm/lodash,npm/jlate@0.0.2/jlate/JLate.min.js"></script>

HTML Code:

<body>
    <div>
        <jlate id="my_temp" src="template/jlate_title.html" type="template">
            Loading...
        </jlate>
    </div>
</body>

Javascript:

$$("#my_temp").jlate({ title: "sample title"});

Gurudev Kumar
  • 160
  • 1
  • 14