digitaljoel
digitaljoel

Reputation: 26574

jquery load content into script tag in firefox

I have an html page using jquery 1.7.2. Within the page I have a scrip tag like so.

<script id="navigation-template" type="text/x-handlebars-template"></script>

Further down the page I'm using javascript to load my handlebars template into the script tag using the following function:

  loadTemplate: function( templateId, elementId ) {
    if ( !elementId ) {
      elementId = templateId;
    }
    $('#'+elementId).load('/my/path/templates.html #'+templateId);
  }

This is working fine in chrome, the eclipse browser, and even IE 9 but seems to go south in Firefox.

I have debugged and the load call successfully completes and the content is returned, but a call to $('#navigation-template').html() gives an empty String.

I also had content in the script tag and called the load and saw that it was replaced by the empty string after the .load call.

Finally, if I manually perform $('#navigation-template').html( "hello" ); I see that the .html() for the script tag is changed.

If I go to a simple ajax get then I will have to parse it and get the given element rather than relying on load to get the element for me.

How do I get around this issue in firefox?

Upvotes: 0

Views: 385

Answers (3)

digitaljoel
digitaljoel

Reputation: 26574

One thing I liked about load() was that I could store all my templates in a single file and use load to select the div for the template I was interested in. I wrote a method that will load the template file and store the templates into a map of template name to template source and compiled template. I compile the template on the first access so that I don't needlessly compile all the templates every time, but only compile the ones I need when needed. It looks something like this:

var myTemplateHelperThingy = {
  loadTemplates: function() {
    $.get( '/my/path/templates.html' )
      .done(function(data) {
        var elements = $(data);
        $( 'div.template-marker-class', elements).each( function( index, element ) {
          // need to use element instead of 'this' because IE is st00pid.
          var content = $(element)[0].outerHTML; // trick from StackOverflow
          myAppObject.pageTemplates[this.id] = {
            source: content,
            template: null
          };
        });
    });
  },
  getTemplate: function( name ) {
    // get a compiled template, compiling it if necessary.
    var result = myAppObject.pageTemplates[name].template;
    if (!result) {
      myAppObject.pageTemplates[name].template = Handlebars.compile(myAppObject.pageTemplates[name].source);
    }
    return myAppObject.pageTemplates[name].template;
  },
  evalTemplate: function( data, templateName ) {
    var template = myAppObject.getTemplate(templateName);
    if (template) {
      return template(data);
    }
    else {
      // message to user here that something went wrong.
    }
  },
  showTemplate: function( targetElement, data, templateName ) {
    $(targetElement).html(bi.evalTemplate( data, templateName ));
  }
}

And templates.html looks like:

<html>
<body>
<div id="templates-wrapper-do-not-remove-or-jquery-will-not-find-the-templates">
  <div id="my-first-template" class="template-marker-class other-class">
    <!-- a bunch of content -->
  </div>
  <div id="my-second-template" class="template-marker-class another-class">
    <!-- more content -->
  </div>
</div>
</body>
</html>

Upvotes: 0

dezman
dezman

Reputation: 19368

Here is the function I use for such purposes:

Util.loadTemplates = function(ExternalTemplates) {
    $.each(ExternalTemplates, function(index, value){
        var scriptUrl = value;
        $.ajax({
            url: scriptUrl,
            dataType: 'text',
            success: function(res){
                var templateName = value.slice(value.lastIndexOf('/') + 1, value.lastIndexOf('.'));
                TEMPLATES[templateName] = Handlebars.compile(res);
            }
        });
    });
}

var ExternalTemplates = [
    'templates/application.hbs',
    'templates/people.hbs'
];

But it is better to look into doing the compiling, which turns the template into a function, before the page is sent to the client.

Upvotes: 1

Michael
Michael

Reputation: 108

You are using the type as this

<script id="navigation-template" type="text/x-handlebars-template"></script>

Try changing the type to

<script id="navigation-template" type="text/javascript"></script>

Upvotes: 0

Related Questions