I am having my first play with HandlebarsJS and I am looking to use multiple arrays within it. Is this possible?
I have setup a Codepen template but I am struggling to implement the data from 2 arrays and from an external URL. I have tried this with MustacheJS too, but I believe that only allows one array and no filtering- unlike Handlebars
Here is the external JSON
and the CodePen
<!-- REQUIRED - Display site name, url and title in top section. With product data below using the "other array-->
<script id="myTemplate" type="text/x-handlebars-template">
{{content}}
</script>
<div id="contentArea"></div>
<script>
var data = {"content": "Hello, World!"};
var source = $("#myTemplate").html();
var template = Handlebars.compile(source);
var html = template(data);
$("#contentArea").text(html);
</script>
Here is my first template attempt but failing to integrate the JSON array at the moment
It's possible using {{#each}} block helper. I also registered my own helper {{{s}}}, which simply returns it's argument JSON.stringify()'ied, so I can print those arrays. How you fetch them is another problem, I Copy & Paste them into the Javascript part of the code for simplicity. Also, here's JS fiddle:
var data = {"content": "Hello, World!", "multipleArrays": [
[
{
"productimage": "https://c.static-nike.com/a/images/t_PDP_864_v1/f_auto/i0lfddlghaiwfqlvlqay/air-vortex-shoe-fmq6pS.jpg",
"producturl": "https://www.nike.com/gb/t/air-vortex-shoe-fmq6pS"
},
{
"productimage": "https://c.static-nike.com/a/images/t_PDP_864_v1/f_auto/cmuof8adhfipkvd0f43r/air-max-95-shoe-XPTbV2mM.jpg",
"producturl": "https://www.nike.com/gb/t/air-max-95-shoe-XPTbV2mM"
}
],
[
{
"sitename": "Nike",
"sitetitle": "Nike. Just Do It.. Nike.com",
"siteurl": "https://www.nike.com/gb/en_gb/"
}
]
]};
Handlebars.registerHelper('s', function(arg) {
return JSON.stringify(arg);
})
var source = $("#myTemplate").html();
var template = Handlebars.compile(source);
var html = template(data);
$("#contentArea").html(html);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.11/handlebars.min.js"></script>
<!-- REQUIRED - Display site name, url and title in top section. With product data below using the "other array-->
<script id="myTemplate" type="text/x-handlebars-template">
<h1>Content: {{content}}</h1>
<hr>
<h2>Stringified multiple arrays:</h2>
{{{s multipleArrays}}}
<hr>
{{#each multipleArrays}}
<h2>Item {{#index}}</h2>
{{{s this}}}
<br>
<br>
{{/each}}
</script>
<div id="contentArea">
</div>
Related
I've got an MJML template which compiles to HTML, and am wanting to load variables from a JSON file to the template. I'm new to HTML, JS & Handlebars so could be really off track here.
My MJML template, test.mjml, looks something like:
<mjml>
<mj-body>
<mj-raw><script type="text/javascript" src="handlebars-v4.7.3.js"></script></mj-raw>
<mj-raw><script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script></mj-raw>
<mj-section>
<mj-text><mj-raw>
<script id="test-template" type="text/x-handlebars-template">
<div>
<p>
Hello my name is {{name}}.
</p>
</div>
</script>
</mj-raw></mj-text>
</mj-column>
</mj-section>
I have a JSON file, data.json:
{
"name": "John",
"height": "175cm",
"occupation": "Teacher",
}
And a JS file, test.js:
$(document).ready(function() {
var template = $('#test-template').html();
var compiledTemplate = Handlebars.compile(template);
$.getJSON('data.json', function (data) {
var context = data;
}
});
var html = compiledTemplate(context);
$(document.body).append(html);
Does anyone know how to do this / what I'm doing wrong?
If I replace jQuery's getJSON method with an inline JSON, it works.
I want to parse JSON data that I am getting from url in handlebars.
What I tried is I got the JSON data from the url.
I defined it into data object.
I want to know how can I parse the data using handlebars.js
I am new to handlebars.js
Is there any other way in which we can get without defining each property?
Because my JSON data is huge.
for eg.
reportData = {
inquiryId= data.data[0].inquiryId;
}
HTML code:
<script id="address-template" type="text/x-handlebars-template">
{{#with data}}
<p> My id is {{{inquiryId}}}</p>
{{/with}}
</script>
<div class="content-placeholder"></div>
JS code:
var reportData= {};
$(document).ready(function () {
$.ajax({
type:'GET',
url: reportURL,
success : function (data){
var inquiryId= data.data[0].inquiryId;
var theTemplateScript = $("#address-template").html();
console.log(theTemplateScript);
// Compile the template
var theTemplate = Handlebars.compile(theTemplateScript);
// Define our data object
reportData=data;
console.log(reportData);
// Pass our data to the template
var theCompiledHtml = theTemplate(reportData);
// Add the compiled html to the page
$('.content-placeholder').html(theCompiledHtml);
}
})
});
JSON:
{
"success":true,
"errors":{
},
"authenticated":true,
"program":1,
"data":[
{
"id":1,
"date":1505756267000,
"name":"AKKAYA, JORGE",
"productName":"Credit Profile",
"inquiryId":726608
}
]
}
My output is:
My id is
Can anyone help me out?
Thanks in advance.
In your Json, data contains array and in your html you are treating it like single object. So please use the below handlebar format to iterate over it.
{{#with abc}}
{{#each this}}
<p> My id is {{{inquiryId}}}</p>
{{/each}}
{{/with}}
Let's say I have some model with html field. This field contains some handlebars code. For example
<div class="foo">
{{model.title}}
</div>
The problem is when I'm trying to iterate over models and render html field, it doesn't evaluate handlebars code inside it.
{{#each models as |model|}}
{{{model.html}}}
{{/each}}
Here's an idea, create a Handlebars helper, that will compile handlebars.
With this sample, I believe you can build something that will suit your needs:
<script type="text/javascript" src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars.min-latest.js"></script>
<script>
var data = [{
"title": "Hey",
"subtitle": "I'm an inner handlebar template.",
"html": '<h1>{{title}}</h1><h2>{{subtitle}}</h2>'
}, {
"title": "Nice!",
"html": '<h1>{{title}}</h1>'
}];
/** Handlebar helper that will compile the content passed, with the data at index **/
Handlebars.registerHelper("compile", function(content, index) {
var template = Handlebars.compile(content);
return template(data[index]);
});
var content = '{{#each .}}\
{{{compile html #index}}}\
{{/each}}';
var template = Handlebars.compile(content);
document.body.innerHTML = template(data);
</script>
I never used ember, but I believe you can make it work easily ;)
I have code below. I need to populate a JSON object using mustache. Unfortunately, it shows nothing to me.
<script type="text/javascript">
var data = "[{"PR_ID":23096,"P_ID":23014},{"PR_ID":33232,"P_ID":23014},{"PR_ID":33308,"P_ID":23014},{"PR_ID":33309,"P_ID":23014}]";
var template = $("#template").html();
Mustache.parse(template);
var rendered = Mustache.render(template, data);
$('#PatrList').html(rendered);
</script>
<body>
<div id="PatrList"></div>
<script id="template" type="x-tmpl-mustache">
{{ #. }}
<div>
PR_ID: <h2> {{PR_ID}} </h2> ---- P_ID: <h2> {{P_ID}} </h2>
</div>
{{ /. }}
</script>
</body>
The problem is that var data is a string and not an object. You need to remove the outer quotation marks or parse the string to an object (given that the delimiter is escaped properly within the string) e.g. with JSON.parse(str) or eval
I created a helper in Handlebars to help with logic, but my template parses the returned html as text rather than html.
I have a quiz results page that is rendered after the quiz is completed:
<script id="quiz-result" type="text/x-handlebars-template">
{{#each rounds}}
{{round_end_result}}
{{/each}}
<div class="clear"></div>
</script>
For each of the rounds, I use a helper to determine which template to render a round's result:
Handlebars.registerHelper("round_end_result", function() {
if (this.correct) {
var source = '';
if (this.guess == this.correct) {
console.log("correct guess");
var source = $("#round-end-correct").html();
} else {
var source = $("#round-end-wrong").html();
}
var template = Handlebars.compile(source);
var context = this;
var html = template(context);
console.log(html);
return html;
} else {
console.log("tie");
}
});
Here is a template that describes a correct round (let's take say it rendered the #round-end-correct template):
<script id="round-end-correct" type="text/x-handlebars-template">
<div></div>
</script>
Here is what gets rendered:
<div></div>
Not as HTML, but as text. How do I get it to actually render the HTML as HTML, rather than text?
I assume that unescaping in Handlebars works the same as in vanilla Mustache.
In that case use triple mustaches to unescape html, i,e: {{{unescapedhtml}}}, like:
<script id="quiz-result" type="text/x-handlebars-template">
{{#each rounds}}
{{{round_end_result}}}
{{/each}}
<div class="clear"></div>
for ref see:
http://mustache.github.com/mustache.5.html
Geert-Jan's answers is correct but just for reference you can also set the result to "safe" directly inside the helper (code from handlebars.js wiki)
Handlebars.registerHelper('foo', function(text, url) {
text = Handlebars.Utils.escapeExpression(text);
url = Handlebars.Utils.escapeExpression(url);
var result = '' + text + '';
return new Handlebars.SafeString(result);
});
With that you can use regular double handlebars {{ }} and handlebars won't escape your expression.