How to insert JavaScript code in a Handlebars template? - javascript

Quoting Handlebars FAQ:
How can I include script tags in my template?
If loading the template via an inlined tag then you may need to break up the script tag with an empty comment to avoid browser parser errors:
<script type="text/x-handlebars">
foo
<scr{{!}}ipt src="bar"></scr{{!}}ipt>
</script>
Nevertheless, I can't seem to be able to implement this:
document.getElementById('output').innerHTML =
Handlebars.compile(
document.getElementById("template").innerHTML
)({});
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.10/handlebars.js"></script>
<script id="template" type="text/x-handlebars">
foo
<scr{{!}}ipt>
alert("Yay!");
</scr{{!}}ipt>
</script>
<div id="output"></div>
As you can see no Yay! is alerted.
How to make this work?

I tried the same with jQuery's .html() and it worked fine. I could narrow down on .innerHTML being the culprit when I looked into this answer.
In short, script tags inserted with .innerHTML needs to be explicitly evaluated using eval().
So below code works, if you eval the script:
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("output").innerHTML = (Handlebars.compile(
document.getElementById("template").innerHTML
))({});
eval(document.getElementById("myscript").innerHTML); // explicitly eval the script
}, false);
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.10/handlebars.js"></script>
<script id="template" type="text/x-handlebars">
foo
<scr{{!}}ipt id="myscript" src="bar">console.log("Hello")</scr{{!}}ipt>
</script>
<div id="output"></div>

Related

AngularJS complains that initialization not defined for jquery

I am getting the below error when loading my page.
Error: initialize is not defined
#http://localhost:8082/js/vendor/jquery-1.11.2.js line 339 > eval:4:3
I want to replace the jqLite with the full version of jquery. I have read several stackoverflow questions on this subject and they imply that all that is required is to load jquery before angularjs. I have done this by simply moving the declaration for jquery above the angular.js. When I do this that is when the above error occurs. It does not give the error when I move the jquery below angularjs but then I cannot use such things as angular.element.
What am I doing wrong?
As far as loading the javascript for each library all I am doing is.
<script type='text/javascript' src="js/vendor/jquery-1.11.2.js"></script>
<script type='text/javascript' src="js/vendor/angular.js"></script>
as far as using jquery instead of lqlite, I am simply trying to use angular.element
var someElement = angular.element('#someelement');
I read a blurb to load jquery before DOMContentLoaded. I am not sure how to do this. I know how to write an event handler for DOMContentLoaded, but what do I do then.
Edited answer: I usually inject my JS script code in the header all inside of an IFFE. You'd also have to make sure you have the ng-app in there to specify the module. Finally I've made sure I actually include the dependent code in the header before my code.
See fiddle here
<head>
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.js"></script>
<script>
(function() {
var testApp = angular.module("testApp", []);
function SomeController($scope) {
console.log('Started controller');
$scope.dirPanelElement = angular.element('#some-panel');
$scope.dirPanelElement.text('set test');
$scope.dirPanelElementText='got "'+$scope.dirPanelElement.text()+'" from panel'
}
testApp.controller("SomeController", SomeController);
})(); // IFFE
</script>
</head>
<body ng-app='testApp'>
<div id="content">
<div style="padding:50px">
<div data-ng-controller="SomeController">
<p align="center">Something</p>
<div id="some-panel"></div>
<div id="some-canvas">{{dirPanelElementText}}</div>
</div>
</div>
</div>
</body>

How to combine inline JavaScripts into one?

I'm fixing up a template we're using on one of our sites which has the following code
This snippet works.
<script type="text/javascript" src="http://partner.googleadservices.com/gampad/google_service.js"></script>
<script type="text/javascript">
GS_googleAddAdSenseService("ca-pub-123");
GS_googleEnableAllServices();
</script>
<script type="text/javascript">
GA_googleAddSlot("ca-pub-123", "Foo");
GA_googleAddSlot("ca-pub-123", "Bar");
</script>
<script type="text/javascript">
GA_googleFetchAds();
</script>
I've tried concatenating the static scripts like this
<script type="text/javascript" src="http://partner.googleadservices.com/gampad/google_service.js"></script>
<script type="text/javascript">
GS_googleAddAdSenseService("ca-pub-123");
GS_googleEnableAllServices();
GA_googleAddSlot("ca-pub-123", "Foo");
GA_googleAddSlot("ca-pub-123", "Bar");
GA_googleFetchAds();
</script>
However, now I'm getting an error
Uncaught ReferenceError: GA_googleAddSlot is not defined
I'm no noob when it comes to JavaScript stuff, but I can't imagine why combining the 3 inline scripts into a single <script> tag would make any difference here.
Any ideas?
google_service.js does not define GA_googleAdSlot, but it defines GS_googleEnableAllServices. When GS_googleEnableAllServices is called, it uses document.write to insert a new script element which loads a definition of GA_googleAdSlot. The new script element is inserted in the document after the end of the script element currently being executed. It's complicated, but it's your answer.
Check this out:
https://support.google.com/dfp_sb/answer/112649?hl=en
This is the piece of the document support:
DFP Small Business requires distinct blocks of JavaScript, described below. Do not combine JavaScript blocks, or your code may break.
They have clearly mentioned that you should not combine Javascript blocks!
I am not sure why, but as long as it is mentioned in the document, you have to follow the rules.

Mustache template with Javascript

I'm trying, without success, to add a javascript to a mustache template
<script id="nodeTemplate" type="text/template">
{{#myItem}}
<div class="divclass {{#myItemDet}}">
...
</div>
<script type="text/javascript">
alert('{{#myItemDet}}');
</script>
{{/myItem}}
</script>
Maybe, it is not possible with Mustache to create JS script...
--------------------------- NOTE 1
If a embeed
<script type="text/javascript"> ... <script>
inside a
<script id="nodeTemplate" type="text/template">...</script>
I suspect that mustache close the template at the first tag
Is it true?
Riccardo
--------------------------- NOTE 2
This is my solution:
1) fill with mustache several hidden divs with the class jshidden
2) Search objs with class=jshidden and append div-content as javascript
The solution now work only on Chrome... Still working
http://jsfiddle.net/ric79/zWEUK/
You are using the block form for myItemDet, rather than the value form.
Try this
<script id="nodeTemplate" type="text/template">
{{#myItem}}
<div class="divclass {{myItemDet}}">
...
</div>
<script type="text/javascript">
alert('{{myItemDet}}');
</script>
{{/myItem}}
</script>
Maybe try to obfuscate the ending </script> tag to not have the browser's parser take it for an inline script. Split it apart, just like advertisers do when writing to the document (e.g. document.write('<'+'/script>');).

Uncaught ReferenceError $ is not defined

I'm very new to JavaScript (just started a few hours ago and trying to get a script working). I went through a few tutorials on W3 and the 'hello world' code works when I paste it directly into my HTML but I'm having a problem with a script (I've had problems with other scripts as well but I am not sure what I'm doing wrong).
I have this code that I want to test in my HTML, I copied the HTML in and it looks the same then I made a file in my static folder called edit.js and copied the JavaScript into it (exactly as shown). It didn't work no errors on the page but when I click it nothing happens. I tried to paste a W3 'hello world' code in and that worked but this script does not.
I tried to inspect the code in Chrome and that's where I see the above error (under the resources tab). I can open the js file using Chrome which makes me think the js file is accessible and pointing correctly but I'm not sure how to get it working. I'm using Jinja2 as my template engine to render the HTML and in my header I have:
<script language="JavaScript" type="text/javascript" src="static/edit.js"></script>
and in my main template (the one that gets rendered on all pages) I have:
<script language="JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
edit.js:
(even putting it within the script tag directly on the page I want to use it on doesn't work)
$('#editvalue').click(function(e){$('#storedvalue').hide();$('#altervalue').show();});
$('#savevalue').click(function(e){
var showNew = $('#changevalue').val();
$('#altervalue').hide();
$('#storedvalue').show();
$('#storedvalue span').text(showNew);
});​
HTML:
(it's embedded in a larger page)
<head>
<script language="JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script language="JavaScript" type="text/javascript" src="static/edit.js"></script>
</head>
... my html code..
<div id="wrapper">
<div id="container">
<div id="storedvalue"><span>Hello</span> [edit]</div>
<div id="altervalue" style="display:none;"><input type="text" name="changevalue" id="changevalue" value="Hello"> [save]</div>
</div>
</div>
I have never been able to successfully run a JavaScript that wasn't on W3 yet. I get the same problem with other scripts even though I see people online saying they work fine for them. Do I need to do anything extra to make this work?
My two questions are:
What am I doing wrong?
Because Javascript seems to just not work when there's a problem, is there a way to get errors or information on what's actually wrong?
I read Uncaught ReferenceError: $ is not defined? and have been trying to figure this out for the last hour and can't see my problem.
First you need to place the jQuery script tag first.
Second, you need to do one of the following things:
Put your code within this function:
$(document).ready(function(){/*CODE HERE*/});
Or like this:
$(function(){
/*CODE HERE*/
});
The DOM needs to be ready before you can use it. Placing your code within anonymous functions that are executed on the ready event of the DOM is how you can do this.
Edit:
$(function(){
$('#editvalue').click(function(e){$('#storedvalue').hide();$('#altervalue').show();});
$('#savevalue').click(function(e){
var showNew = $('#changevalue').val();
$('#altervalue').hide();
$('#storedvalue').show();
$('#storedvalue span').text(showNew);
});​
});
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
Script tag for jQuery should come before your custom javascript.
Follow by edit.js
<script type="text/javascript" src="static/edit.js"></script>
Try removing the language attribute..sometimes work for me. It's obsolete now .. i think
You need to include jquery before you can use it.

javascript template image

I'm using a javascript template like this:
<script id="template" type='text/tmpl'>
<img src="{{=imagesrc}}" />
</script>
The problem is that loading that template the page would try to make a request to http://site.com/{{=imagesrc}}.
My understanding was that using the script element type should prevent what's inside from being interpreted as html?
How do I fix this? Thanks.
Not sure what you're really trying to do.. but you could try wrapping whatever is inside your script tag with CDATA:
<script>
/*<![CDATA[*/
Your stuff here
/*]]>*/
</script>

Categories