Back to Basics with CloudSpokes and Meteor.js

I’m starting off 2013 by going back to basics re: my web development skills - attempting to master the core technologies - HTML, CSS and JavaScript.  I’m focusing now on JavaScript, by far the most intricate and difficult of the three.  I recently discovered the CloudSpokes Coding Challenges and thought it would be a good excuse to work hands-on with JS.

I just wrapped up my submission for CloudSpokes’ First Time Submitter Challenge for January 2013.  I built a lightweight web app used to track the status of projects.

Here’s my submission demo video:

Exploring Meteor.js was a lot of fun - in the past I’ve only really used vanilla JavaScript and some JQuery.  The neatest feature is definitely the live page updates (templates update automatically when database data changes).  There is a definite productivity boost to updating HTML/CSS, saving, and instantly seeing your changes reflected in the browser automatically.  In the future this could prove very useful for rapid prototyping web apps!

Interesting code implementation details:

// Live edits were the biggest challenge...
// When an element is double clicked, flag a session variable for "editing mode":
Template.projectList.events({
'dblclick .display .pTitle': function (evt, tmpl) {
Session.set('editing_title', this._id);
Meteor.flush(); // update DOM before focus
activateInput(tmpl.find("#pTitle"));
}};
// The editing title flag checks to see if we are in editing mode:
Template.projectList.editingTitle = function () { return Session.equals('editing_title', this._id); };
// Back in the HTML, Moustache.js templates are used to determine which view to render:
// If we are editing the title, then show a text input:
{{#if editingTitle}}
<h2><input id="pTitle" class="pTitle" type="text" value="{{Title}}" /></h2>
// otherwise, just render the current Title value
{{else}}
<label class="pTitle">{{Title}}</label>
// this pattern repeats for each Project datapoint.
// In addition to Meteor.js, I learned about Moustache.js.
// The ability to create helper methods is handy, as seen here - I'm dynamically setting the CSS color style by
// calling the helper:
<li>Status: <span class="pStatus" style="color:{{getStatusColor Status}}">{{Status}}</span></li>
// Defined as:
Handlebars.registerHelper('getStatusColor', function (status) {
switch (status) {
case "On Track":
{ return 'green'; } break;
case "Behind":
{ return '#edd72c'; } break;
case "Delayed":
{ return 'red'; } break;
default:
{ return 'black'; } break;
}
});