Handlebars not populating template - javascript

I have a handlebars template and I'm trying to use it, but when I do, I get all the tags but with no text. Here's my HTML:
<script src="../static/js/main.js"></script>
<script src="https://cdn.jsdelivr.net/npm/handlebars#latest/dist/handlebars.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
<script id="template" type="text/x-handlebars-template">
<li class="message">
<h6>{{username}}</h6>
<p>{{message}}</p>
<p>{{date}}</p>
</li>
</script>
And in main.js:
socket.on('message', data => {
console.log('message recieved')
console.log(data.channel)
console.log(document.querySelector("#active").innerHTML)
if (data.channel === document.querySelector("#active").innerHTML) {
console.log(data.sent_by)
console.log(data.message)
console.log(data.time)
var template = Handlebars.compile(document.querySelector('#template').innerHTML);
console.log(document.querySelector('#template').innerHTML)
const context = {'username' : data.sent_by,
'message' : data.message,
'date' : data.time,};
var html = template(context);
console.log(context)
console.log(html)
document.querySelector('#view-message').innerHTML += html
}
})
All log messages are being run so the socket is receiving data and the if condition is being triggered. I've used handlebars in a previous section of the same project and it worked fine there so I'm not sure why it's not working here. Thanks!

move your script <script src="../static/js/main.js"></script> all the way to the bottom

Related

Integrate MoPub Failover tag into Media.Net Javascript

I like to add Media.Net Network via JavaScript to MoPub. The team from Media.Net send me javascript I shoudl add to MoPub Network tab. So far so good.
They send me exactly this code:
//Add this code in head section
<script type="text/javascript">
window._mNHandle = window._mNHandle || {};
window._mNHandle.queue = window._mNHandle.queue || [];
medianet_versionId = "3121199";
</script>
<script src="//contextual.media.net/dmedianet.js?cid=MYCUSTOMERKEY" async="async"></script>
//Add this code in body section
<div id="BANNERKEY">
<script type="text/javascript">
try {
window._mNHandle.queue.push(function () {
window._mNDetails.loadTag("BANNERKEY", "320x50", "BANNERKEY");
});
}
catch (error) {
}
</script>
</div>
I believe both tags should go to the network tab of MoPub like this:
But here comes the question. MoPub highly recommends to add a failover tag in case the network responds with a no fill or any other error. But my knowledge is limited to add this failover tag to the Media.Net javascript code.
<script type="text/javascript" charset="utf-8"> loaded=true; window.location="mopub://failLoad"; </script>
I added the failover tag to the catch block and it seems to work.
<script type="text/javascript">
window._mNHandle = window._mNHandle || {};
window._mNHandle.queue = window._mNHandle.queue || [];
medianet_versionId = "3121199";
</script>
<script src="//contextual.media.net/dmedianet.js?cid=MYCUSTOMERKEY" async="async">
</script>
<div id="BANNERKEY">
<script type="text/javascript">
try {
window._mNHandle.queue.push(function () {
window._mNDetails.loadTag("BANNERKEY", "320x50", "BANNERKEY");
});
}
catch (error) {
loaded= true;
window.location="mopub://failLoad";
}
</script>
</div>

Link JavaScript object within HTML

How would I be able to pull the data from the JS script within my HTML? I am wanting to pull the "Title", "Description", and "Link" objects and display them within my HTML code.
Here is the code:
<div class="roadMap" id="roadMap"></div>
<script src="/siteassets/bootstrap3/js/jquery-1.8.3.min.js"></script>
<script src="/publiccdnlib/PnP-JS-Core/pnp.min.js"></script>
<script type="text/javascript" src="/publiccdnlib/es6-Promise/es6-promise.auto.js"></script>
<script type="text/javascript" src="/publiccdnlib/fetch/fetch.min.js"></script>
<script src="/publiccdnlib/slick/slick.min.js"></script>
<script src="/publiccdnlib/CommonJS/CommonJS.js"></script>
<script src="/publiccdnlib/knockout/knockout.js"></script>
<script src="/publiccdnlib/knockout/knockout.simpleGrid.3.0.js"></script>
<script src="/publiccdnlib/toastr/toastr.min.js"></script>
<script src="/publiccdnlib/dialog/open-sp-dialog.js"></script>
<!--END Scripts for O365-->
<script>
$pnp.setup({
baseUrl: "https://fh126cloud.sharepoint.com/TrainingResourceCenter/O365Training"
});
$pnp.sp.web.lists.getByTitle("O365RoadMap").items.get().then(function(z) {
console.log(z);
var result = z.results.map(a => ({
Title: `${a.Title}`,
Description: `${a.Description}`,
Link: `${a.Link}`
}))
console.log(result);
document.getElementById("roadMap").innerHTML = JSON.stringify(result, null, 2)
})
</script>
<html lang="en">
<body>
<div>
/* Code goes here */
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
</body>
</html>
I see you are using jQuery so I will answer relative to it.
Using jQuery you can put text wherever you want using the text method.
For example, if you want to put the Title data in your div you could do:
$("div").text(result.Title);
The code above will place result.Title in every div on the page (which you only have one of.).
There are so many jQuery methods you could use as-well, such as append, prepend, and html. Append will put the text after the existing content of an element. Prepend puts the text before existing content of an element. Html with replace the html inside of an element.
So if you wanted to construct the HTML elements then place them on the DOM (the web page) you could do:
$(document).ready(function(){
var head = '<h1>${result.Title}</h1>';
var desc = '<p>${result.Description}</p>';
var link = '<a src="${result.Link}">${result.Link}</a>';
$("div").html(head + desc + link);
});
To put your Title, Description, and Link on the DOM. Hope this help you, good luck!

Can't display language variables in javascript code using mustache.js

I'm trying to handle translations with Mustache.js and it works fine for some part of the code but not for another part.
<script>
function MyFunction() {
// If a submit button is pressed, do some stuff and run this function to display the result
var tmpText = "";
tmpText = "<b>{{someTextInJSfunction}}</b>"; // this is NOT OK
document.getElementById("totalText").innerHTML = tmpText;
}
</script>
</head>
<body>
<div id="sampleArea">
</div>
<script id="personTpl" type="text/template">
<span id="totalText"></span></p>
<b>{{ImpNotice}}</b> {{Contact}} // this is OK
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="js/mustache.js"></script>
<script>
$( document ).ready(function() {
var lang = 'en_us';
$.getJSON('json/'+lang+'.json', function(data) {
var template = $('#personTpl').html();
var html = Mustache.to_html(template, data);
$('#sampleArea').html(html);
});
});
</script>
When I click a Submit button, my JS function is called and depending on some calculation, some text should be displayed in the page. This is the part that doesn't work, {{someTextInJSfunction}} is displayed instead of the actual content of {{someTextInJSfunction}}.
The content of {{ImpNotice}} and {{Contact}} is correctly displayed because I assume the variables are located in the <script id="personTpl"> tags.
I'm not sure how to fix it for the variables located in my JS functions, such as {{someTextInJSfunction}}.

html5 template content (document fragment) load order on appendChild

consider the following code -->
<template id="foo">
<script type="text/javascript">
console.log("00000000");
</script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
console.log(11111111);
</script>
<script type="text/javascript">
console.log(22222222);
var xyz = $;
console.log(33333333);
</script>
</template>
now on appending this to the DOM
var template = document.getElementById('foo')
var clone = document.importNode(template.content,true);
document.appendChild(clone);
gives this output in console -->
00000000
11111111
22222222
Uncaught ReferenceError: $ is not defined
So the question in general is -->
How to properly load into DOM, an html <template> that has
an external script (like jQuery in this case), followed by an inline script having some dependency on it.
Also - this does not happen if template tag is removed -->
<script type="text/javascript">
console.log("00000000");
</script>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
console.log(11111111);
</script>
<script type="text/javascript">
console.log(22222222);
var xyz = $;
console.log(33333333);
</script>
How in the latter case, does the browser download it synchronously?
Is it possible to have blocking script download (line by line) in the former case (with template) ?
The problem is that the script is loaded async. That means that it start to load the script from the web, but continues running the code below. So in that case it will execute code below without having loaded jQuery yet.
You only need to load it once, so you could do it at the start, and only once:
var template = document.getElementById('foo')
var clone = document.importNode(template.content,true);
document.body.appendChild(clone);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<template id="foo">
<script type="text/javascript">
console.log(00000000);
</script>
<script type="text/javascript">
console.log(11111111);
</script>
<script type="text/javascript">
console.log(22222222);
var xyz = $;
console.log(33333333);
</script>
</template>
Another option would be to make sure code below is only executed once the file is loaded:
var template = document.getElementById('foo')
var clone = document.importNode(template.content, true);
document.body.appendChild(clone);
<template id="foo">
<script type="text/javascript">
console.log(00000000);
</script>
<script type="text/javascript">
function scriptOnload() {
console.log(11111111);
console.log(22222222);
var xyz = $;
console.log(33333333);
}
</script>
<script onload="scriptOnload()" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</template>
Here's how I handle it in my application (with jQuery):
//Load the template from an external file and append it to the HEAD of the document
$.get("/path/to/your_external_template_file.html", function (html_string) {
$('head', top.document).append(
new DOMParser().parseFromString(html_string, 'text/html').querySelector('template')
);
}, 'html');
//Locate the template after you've imported it
var $template = $("#top_template_element_id");
//If you want to reuse the content, be sure to clone the node.
var content = $template.prop('content').cloneNode(true);
//Add a copy of the template to desired container on the page
var $container = $('#target_container_id').append(content);

Handlebars duplicating ajax output on click

I'm using Handlebars to print out a list of books, where if you click on the title of a book you get a new div showing details. I'm able to print out the list and click on the book title to get details, but every title I click outputs the details from the first book that I clicked instead of the details for that book itself. I believe this has something to do with binding but haven't found a syntax that seems to work. Here's my HTML & Handlebars code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Library</title>
</head>
<body>
<div class="main"> <div id="book-list-items"></div></div>
<div id="book-details-items"></div>
<script src="js/jquery-1.11.1.min.js"></script>
<script src="js/handlebars-v1.3.0.js"></script>
<script src="js/main.js"></script>
<script id="book-list-template" type="text/x-handlebars-template">
<div class="book-list">
<h3 class='template title'>{{title}}</h3>
</div>
</script>
<script id="book-details-template" type="text/x-handlebars-template">
<div class="book-details">
<h3 class='template title'>{{title}}</h3>
<h4 class='template year'>{{year}}</h4>
<h4 class='template rating'>{{rating}}</h4>
</div>
</script>
</body>
</html>
And here's the JavaScript:
$(document).ready(function(){
var source = $('#book-list-template').html();
var source2 = $('#book-details-template').html();
var template = Handlebars.compile(source);
var template2 = Handlebars.compile(source2);
$.ajax({
type:'GET',
url: 'https://....',
data:{ api_key: '....'
}
}).done(
function(data){
populate_template(data)
});
var populate_template = function(data){
data.results.forEach(function(book){
var html = $(template(book));
$('.main').append(html);
html.click({book:book}, book_info)
})
}
var book_info = function(event){
id = event.data.book.id
$.ajax({
type:'GET',
url: 'https://....' + id,
data:{ api_key: '....'
}
}).done(function(data){
var html2 = template2(data);
$(document).trigger('change', event.currentTarget);
$(document).on('change', function(e, listing){
e.preventDefault();
$(listing).replaceWith(html2)
});
});
};
});
Can anyone tell me where I'm going wrong? I assume it's in the #book-details-template script but am stuck on what the syntax would be.
I suppose because the "change" listener on document stays active from the first call and in the followings call it's duplicated and so on...
Try to eliminate the listener and put the template into the book-details-items:
$("#book-details-items").html(html2);

Categories

Resources