Over a million developers have joined DZone.

Adding a Dynamic Calendar to HarpJS

· Java Zone

Microservices! They are everywhere, or at least, the term is. When should you use a microservice architecture? What factors should be considered when making that decision? Do the benefits outweigh the costs? Why is everyone so excited about them, anyway?  Brought to you in partnership with IBM.

Another day, another HarpJS recipe. Can you tell what I'm excited about lately? For today's demo, I've built a simple dynamic calendar for HarpJS. There are probably many different ways to handle this (you could simply embed a Google Calendar as I describe here), but here is how I solved it.

I decided that I'd use the FullCalendar jQuery plugin for the display of the calendar. I've used it before with a ColdFusion demo and I like how easy it is use. I also knew it supported loading events from an Ajax source. HarpJS lets you build more than just dynamic HTML pages. You can build dynamic XML and JSON files as well. This recipe describes how you can generate XML for a RSS feed. A similar method could be used to generate JSON as well.

I began by creating an events folder. Inside of this folder I created a few files to represent my events. I'm not doing anything fancy with that so I won't bother sharing the code. I then created a _data.json file. This is what will drive the JSON feed.

{
	"a":{
		"title":"Event A",
		"date":"2/14/2014",
		"allDay":true
	},
	"b":{
		"title":"Event B",
		"date":"2/13/2014 2:00 PM"
	},
	"events":{
		"layout":false
	}
}

The first two items represent my events. Title and date should make sense. I'll explain allDay in a second. The final item represents the file that will generate my JSON feed. By default Harp wraps your pages in layout templates. But for a JSON feed that layout would break the code that parses it. By adding layout:false I'm telling Harp to not wrap that file with the regular site layout. (This causes another small problem and I'll discuss that more at the end.)

Next - I created my front end. This is taken straight from the FullCalendar sample files so it isn't too excited, but here it is:

<link href='/fullcalendar/fullcalendar.css' rel='stylesheet' />
<link href='/fullcalendar/fullcalendar.print.css' rel='stylesheet' media='print' />
<script src='/lib/moment.min.js'></script>
<script src='/lib/jquery.min.js'></script>
<script src='/lib/jquery-ui.custom.min.js'></script>
<script src='/fullcalendar/fullcalendar.min.js'></script>
<script>

	$(document).ready(function() {
	
		$('#calendar').fullCalendar({
			header: {
				left: 'prev,next today',
				center: 'title',
				right: 'month,agendaWeek,agendaDay'
			},
			editable: true,
			timezone:"America/Chicago",
			events: {
				url: '/events/events.json',
				error: function() {
					$('#script-warning').show();
				}
			},
			loading: function(bool) {
				$('#loading').toggle(bool);
			}
		});
		
	});

</script>


<div id='script-warning'>
	crap broke.
</div>

<div id='loading'>loading...</div>

<div id='calendar'></div>

The only thing here really interesting is the url option in full calendar. Note that I'm pointing to /events/events.json. My real file is events/events.json.ejs. Harp will serve it up without the EJS extension and even automatically use the right content type based on the JSON extension. Cool! Now let's look at the code.

[
	<% 
	var events = Object.keys(public.events._data);
	for(var i=0; i<events.length; i++) { 
		if(events[i] !== "events") {
			event = public.events._data[events[i]];
	%>
		{
			"title":"<%- event.title %>",
			"start":"<%- event.date %>",
			"url":"/events/<%- events[i] %>.html"
			<% if(event.allDay) { %>
			,"allDay":<%- event.allDay %>
			<% } %>
		}
			<% if(i+2 < events.length) { %>,<% } %>
	<% 
		}
	} 
	%>
]

Ok, not the prettiest code, but let's break it down. I begin by getting the keys from my data and looping over it. I skip the events key - remember, it is there only so that I can disable layout. For each event I output the title and date. The start label is used there because that's what FullCalendar wants. Speaking of - FullCalendar also requires that you tell it when an event is over the entire day. If you don't, it makes a guess as to a time. That's why I included allDay in my JSON data and you can see me using it here. Finally, I use a bit of logic to determine if I'm at the end of my loop. If I'm not, I output a comma.

So yeah - this is ugly - and it was pretty easy for me to break it. The output was pretty - but the code was gross. I then figured out that it will silly for me to create JSON when the server could do it instead. Here is version two:

<%
var eventData = [];
var events = Object.keys(public.events._data);
for(var i=0; i<events.length;i++) {
	if(events[i] !== "events") {
		var eventOb = {};
		event = public.events._data[events[i]];
		eventOb.title = event.title;
		eventOb.start = event.date;
		eventOb.url = "/events/" + events[i] + ".html";
		if(event.allDay) {
			eventOb.allDay = event.allDay;	
		}
		eventData.push(eventOb);
	}
}

%>

<%- JSON.stringify(eventData) %>

A heck of a lot cleaner, right? And then I end with a simple call to JSON.stringify. Much simpler. And that's it! Here is a screen shot of the calendar displaying the events powered by HarpJS and the dynamic JSON feed.

Discover how the Watson team is further developing SDKs in Java, Node.js, Python, iOS, and Android to access these services and make programming easy. Brought to you in partnership with IBM.

Topics:

Published at DZone with permission of Raymond Camden, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}