Skip to content

Instantly share code, notes, and snippets.

@chrislkeller
Last active February 3, 2022 08:02
Show Gist options
  • Select an option

  • Save chrislkeller/3230081 to your computer and use it in GitHub Desktop.

Select an option

Save chrislkeller/3230081 to your computer and use it in GitHub Desktop.
Displaying data from a flat JSON file on a Handlebars.js template file rendered with AJAX.

Loading handlebars template with AJAX & displaying flat file data

There are some good resources out there for those who want to start using the handlebars JavaScript template library, so I don't want to start from scratch with it.

But I would like to try to demonstrate how I've ramped up my use of handlebars templates over the past couple months in a newsroom environment, and how it's made deploying interactive projects fairly fast.

This example will take a flat json file I created from a csv and display it in a handlebars template stored in a separate file and rendered on a web page.

Overview

The handlebars.js documentation describes adding templates to bottom of your index.html file like this:

    <script id="entry-template" type="text/x-handlebars-template">
        {{template content}}
    </script>

Coming across this after learning the basics of django templating, I really wanted a way to store handlebars templates in reusable, decoupled files that could be shared across projects.

Thankfully this function helps me to do exactly that.

// render handlebars templates via ajax
function getTemplateAjax(path, callback) {
    var source, template;
    jqueryNoConflict.ajax({
        url: path,
        success: function (data) {
            source = data;
            template = Handlebars.compile(source);
            if (callback) callback(template);
        }
    });
}

I can then call it like this, where dataDetailsTemplate.handlebars is the name of my template, and #data-details is the css selector I am targeting.

	// create projects content template
	function renderDataVisualsTemplate(data){
	    getTemplateAjax('dataDetailsTemplate.handlebars', function(template) {
	
	        // adds debugging information to console
	        handlebarsDebugHelper();
	        jqueryNoConflict('#data-details').html(template(data));
	    })
	};

Walkthrough

Let's go through the full data-script.js file, because there's a lot in there that I've kind of picked up over the last several months. I don't really have an idea if it is "correct" to programmers out there, but I know that it works and doesn't throw me errors.

In learning to use jQuery in the context of my previous CMS -- which used several jQuery libraries -- I found it just made sense to use a no conflict variable and it's something I've just stuck with:

	var jqueryNoConflict = jQuery;

When the DOM is ready I call the retriveData() function which kind of starts the whole ball rolling:

	//begin main function
	jqueryNoConflict(document).ready(function(){
	    retriveData();
	});
	//end main function

retriveData() looks for my flat JSON file, which set to a variable. It then uses jQuery's getJSON method to pull the data and run it through a function called renderDataVisualsTemplate(). This is the function that will render my handlebars template to the page with data in it.

	// grab data
	function retriveData() {
	    var dataSource = 'working-data-file.json';
	    jqueryNoConflict.getJSON(dataSource, renderDataVisualsTemplate);
	};

renderDataVisualsTemplate() gets an argument that represents my the data from my flat JSON file. Again, dataDetailsTemplate.handlebars is the name of my template and #data-details is the css selector where I will inject my template that will be filled with data.

	// create projects content template
	function renderDataVisualsTemplate(data){
	    getTemplateAjax('dataDetailsTemplate.handlebars', function(template) {
	        handlebarsDebugHelper();
	        jqueryNoConflict('#data-details').html(template(data));
	    })
	};

After that, I have my function to pull my handlebars template from an external file and compile it. I've also included a handlebars debugger, a "helper" function shows information about the data I am trying to work with.

Let's take a look at the flat JSON file I am using to hold the data that will be rendered to the page. It's structured as it is in the handlebars walkthrough.

	{"objects": [{"Source": "National Employment Law Project", "DataOrder": "1", "SourceLink": "http://www.nelp.org/", "Data": "12.29.2012", "Title": "The last day anyone will receive benefits from the Emergency Unemployment Compensation program unless Congress acts to renew it."}, {"Source": "Congressional Budget Office", "DataOrder": "2", "SourceLink": "", "Data": "$30,000,000,000", "Title": "Estimated cost to renew the Emergency Unemployment Compensation program through the end of 2013."}]} 

To render the data, the handlebars template is structured just as it would be if it was inline on the index.html page, save for wrapping it in a script tag.

	<div>		 
	    {{debug}}
	    <h2>Flat file data displayed on a handlebars.js template loaded with ajax</h2>
	    {{#objects}}
	        <p>{{Title}}: <strong>{{Data}}</strong><br />
	        -- <a href="{{SourceLink}}" target="_blank"><em>{{Source}}</em></a></p>
	    {{/objects}}
	</div>

In this case, I'm asking that every instance of an object

	{{#objects}}

	{{/objects}}

be rendered to the page and structured in a certain way.

    <p>{{Title}}: <strong>{{Data}}</strong><br />
    -- <a href="{{SourceLink}}" target="_blank"><em>{{Source}}</em></a></p>

My HTML page isn't any special, other than have a div that will have all kinds of data injected into it thanks to handlebars.

<div id="data-details"></div>

I've found several practical applications of this demonstration, but your mileage might very. All it really takes though is some imagination and a need.

For instance, I came from shops that used the same CMS, where I could add html, css and JavaScript to a CMS "asset" which would then be wrapped up in the site header, rail and footer. Here at SCPR, I've been lucky enough to have mentors who wanted to and helped to create something similar.

For instance, this project is on a custom template that lies outside of the CMS. The header and footer are each handlebars templates, external files that are added to each project. Need to change a link in the footer? Change it in one place and it's changed on all project pages that use the template. Same goes for the header.

License

The MIT License

var jqueryNoConflict = jQuery;
//begin main function
jqueryNoConflict(document).ready(function(){
retriveData();
});
//end main function
// grab data
function retriveData() {
var dataSource = 'working-data-file.json';
jqueryNoConflict.getJSON(dataSource, renderDataVisualsTemplate);
};
// create projects content template
function renderDataVisualsTemplate(data){
getTemplateAjax('dataDetailsTemplate.handlebars', function(template) {
handlebarsDebugHelper();
jqueryNoConflict('#data-details').html(template(data));
})
};
// render handlebars templates via ajax
function getTemplateAjax(path, callback) {
var source, template;
jqueryNoConflict.ajax({
url: path,
success: function (data) {
source = data;
template = Handlebars.compile(source);
if (callback) callback(template);
}
});
}
//end
// add handlebars debugger
function handlebarsDebugHelper(){
Handlebars.registerHelper("debug", function(optionalValue) {
console.log("Current Context");
console.log("====================");
console.log(this);
});
};
// end
<div>
{{debug}}
<h2>Flat file data displayed on a handlebars.js template loaded with ajax</h2>
{{#objects}}
<p>{{Title}}: <strong>{{Data}}</strong><br />
-- <a href="{{SourceLink}}" target="_blank"><em>{{Source}}</em></a></p>
{{/objects}}
</div>
<title>flat-file > > ajax > handlebars</title>
<link rel="stylesheet" href="http://current.bootstrapcdn.com/bootstrap-v204/css/bootstrap.css" type="text/css" />
<style type="text/css">
/*
body background using Crayola crayon color from
Ben Welsh gist: https://gist.github.com/4348665
*/
body {background: #926EAE;}
#data-container {background: #fff; width: 960px; margin: 0 auto 0 auto; padding: 15px;}
#data-details {margin: 10px auto 0 auto;}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<body>
<div id="data-container">
<div id="data-details"></div>
</div>
</body>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.0.rc.1/handlebars.min.js"></script>
<script type="text/javascript" src="data-script.js"></script>
{"objects": [{"Source": "National Employment Law Project", "DataOrder": "1", "SourceLink": "http://www.nelp.org/", "Data": "12.29.2012", "Title": "The last day anyone will receive benefits from the Emergency Unemployment Compensation program unless Congress acts to renew it."}, {"Source": "Congressional Budget Office", "DataOrder": "2", "SourceLink": "", "Data": "$30,000,000,000", "Title": "Estimated cost to renew the Emergency Unemployment Compensation program through the end of 2013."}, {"Source": "National Employment Law Project", "DataOrder": "3", "SourceLink": "http://www.nelp.org/", "Data": "400,000", "Title": "Estimated number of Californians receiving benefits from the Emergency Unemployment Compensation program, which is set to expire Jan. 2."}, {"Source": "National Employment Law Project", "DataOrder": "4", "SourceLink": "http://www.nelp.org/", "Data": "2,100,000", "Title": "Estimated number of Americans receiving benefits under the Emergency Unemployment Compensation program that would lose their unemployment benefits come January if Congress doesn’t act."}, {"Source": "National Employment Law Project", "DataOrder": "5", "SourceLink": "http://www.nelp.org/", "Data": "940,000", "Title": "Estimated number of Americans whose state unemployment benefits will end in the first quarter of 2013, and would be eligible for benefits under the Emergency Unemployment Compensation program."}, {"Source": "National Employment Law Project", "DataOrder": "6", "SourceLink": "http://www.nelp.org/", "Data": "February 2012", "Title": "The date when the Emergency Unemployment Compensation program was last renewed by Congress."}, {"Source": "U.S. Department of Labor", "DataOrder": "7", "SourceLink": "http://www.ows.doleta.gov/unemploy/supp_act.asp", "Data": "June 30, 2008", "Title": "The date the Emergency Unemployment Compensation program was created."}, {"Source": "National Employment Law Project", "DataOrder": "8", "SourceLink": "http://www.nelp.org/", "Data": "10", "Title": "The number of times Congress has renewed the Emergency Unemployment Compensation program since it was first created in the summer of 2008."}, {"Source": "National Employment Law Project", "DataOrder": "9", "SourceLink": "http://www.nelp.org/", "Data": "37 percent", "Title": "Estimated percent of Californians that have been unemployed more than a year since 2008, when the Emergency Unemployment Compensation program was created to help the long-term unemployed."}, {"Source": "National Employment Law Project", "DataOrder": "10", "SourceLink": "http://www.nelp.org/", "Data": "5,000,000", "Title": "Estimated number of Americans that have been without work for six months or longer"}, {"Source": "U.S. Department of Labor", "DataOrder": "11", "SourceLink": "http://workforcesecurity.doleta.gov/unemploy/docs/potential_weeks_map.pdf", "Data": "26 weeks", "Title": "Cap on unemployment benefits by the least generous states."}, {"Source": "National Employment Law Project", "DataOrder": "12", "SourceLink": "http://www.nelp.org/", "Data": "14 to 47 weeks", "Title": "The range of maximum benefits states offer, subsidized by the Emergency Unemployment Compensation program."}, {"Source": "U.S. Department of Labor", "DataOrder": "13", "SourceLink": "http://workforcesecurity.doleta.gov/unemploy/docs/potential_weeks_map.pdf", "Data": "73 weeks", "Title": "Maximum length of benefits for new claimants in California under the Emergency Unemployment Compensation program."}, {"Source": "Center on Budget & Policy Priorities", "DataOrder": "14", "SourceLink": "http://www.cbpp.org/cms/index.cfm?fa=view&id=3164", "Data": "Nine states", "Title": "Number of states with unemployment rates above 9 percent in which workers are eligible for up to 47 weeks of additional benefits under the Emergency Unemployment Compensation program."}, {"Source": "U.S. Department of Labor", "DataOrder": "15", "SourceLink": "http://www.nelp.org/", "Data": "$40,000,000,000", "Title": "Estimated amount of money brought into the state of California by those receiving benefits from the Emergency Unemployment Compensation program since it began in July 2008."}]}
@rullymartanto
Copy link

Hi chrislkeller,
I am beginner on using google data analytics,.. I have download your script but It's doesn't work,..
I Need to know how using json file from data analytic and display it in html table..
Thanks for help

@Dhiraj1411
Copy link

Hi chrislkeller,
I am using handlebars.js, I am not able to get the row json from HTML. I am only getting [object, object]...
Could you please help me with it.
http://stackoverflow.com/questions/35819697/how-to-pass-json-object-from-html-to-javascript-file/35823060#35823060
Thanks in advance !
Regards,
Dhiraj

@gerwitz
Copy link

gerwitz commented Jun 22, 2017

It's great that you're showing people how to do this with lightweight libraries. Kudos!

@locohost
Copy link

As I'm reading I'm thinking "Is this server-side Backbone.js?".

@brunorilla
Copy link

Great post!
Do you have a version using only Vanilla JS?

@natmallow
Copy link

awesome thank you for the time saver!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment