An app I'm working on requires time shown as 'time ago'. I was initially using a clunky jQuery plugin to accomplish this but I found a better solution with Moment.js. The result is the reason I love Angular, a clean and simple directive I can use so easily:

<span timeago="{{someDate}}" />

or as a filter

<span>{{someDate | timeago}}</span>

For regular date functions, you can use the existing date filter.

The full code is only a few lines of code:

app.filter('timeago', function(){
  return function(date){
    return moment(date).fromNow();

app.directive('timeago', function() {
  return {
    link: function(scope, element, attrs){
      attrs.$observe("timeago", function(){

So why use a directive over a filter? The filter will run if the digest runs, but a directive can force a digest with $timeout. So the main reason is so you can have this update in real time, you'd only need to add a $timeout() and setInterval(). I didn't do that here, but it'd be pretty easy to add.

And a working demo:

Aug 19

With AngularJS we see a few ugly issues with loading apps and large datasets which are easily fixed. One is called an "flash of unstyled content", that's basically raw visible Angular templates before rendering. Adding a style to your stylesheet can resolve this. The other issue is empty tables as data is loading. When the data comes back from your server, it rudely explodes into your DOM. So here's a technique I use to solve both issues at once.


First, we need two styles. The "invisible" style, and the "visible" style. We'll use a CSS transition between the two to give us a nice fade. I call these two styles "fade" and "in", inline with how bootstrap styles work. In fact, if you've got bootstrap, very similar styles already exist in your sheet.

.fade {
  opacity: 0;
  -webkit-transition: opacity 0.25s ease-in;
  -moz-transition: opacity 0.25s ease-in;
  -o-transition: opacity 0.25s ease-in;
  -ms-transition: opacity 0.25s ease-in;
  transition: opacity 0.25s ease-in;
  opacity: 1;

Pretty simple right? It's actually only two property, opacity and transition. The rest is just browser compatibility prefixes.


So how do we make this work? It's way easier than you think. You simply add the "fade" class to the element you want to fade in, then use ng-class to add the "in" class when your data is read.

<div class="fade" ng-class="{in:data.length}">
This will fade in when data becomes available

Yes, it's that easy. Just to prove it, here's a working JSBin. It resolves the data after waiting 1.5seconds. If you missed the fade in, just refresh the bin.

Aug 9

I just finished the first release of a new web app: SpriteHero. A CSS Sprite making tool built entirely in JavaScript and HTML.

I originally wrote SpriteHero as an AIR app a few years ago. I used to love making apps with Flex, AIR, actionscript, even MXML. I never would have imagined that I'd have more fun making an application in plain old HTML and JavaScript. But then came along amazing tools like Bootstrap and AngularJS. AngularJS is a javascript framework a that lets you create dynamic components in a declarative style. Another huge plus for HTML5/JavaScript is the WAI-ARIA standard which provides accessibility to rich internet applications. Live bindings that actually work better than the Flex Framework ever did seal the deal.

I will be publishing the code for SpriteHero on github shortly.

Dec 1

Had a great time presenting this morning at Capital Camp DC! Surprisingly good crowd for a 9am Saturday session.
Here's a link to my presentation on performance at CapitalCampDC:

Contact me if you have any questions.

Jul 28

So this has been out there for awhile, but it just started getting some marketing attention: Brackets, an opensource IDE.

I like the idea of an opensource editor built in HTML/CSS/Javascript so I gave it a shot. Obviously, it's too new to be really replace your every day tools, but it does have some promising features. Not only that, but it's SUPER easy to work on. So here's a few extnesions I wrote.


Type a familiar trigger, hit a keystroke, and bam, you've got a snippet. You can create new snippet templates with JSON (XML soon) and if you don't like keystrokes, you can use the tool bar by going to "View -> Snippets."
Snippets inline widget
Snippets control panel
Download and place in extensions/user


The GitHub extension aims to do integration of the GitHub api direclty into Brackets. For the time being, it mostly only does gists. You can post your current document or current selection to a gist.
GitHub context menu
Download and place in extensions/user

Jun 26

I will be doing a lighting talk at this month's NodeDC meeting. I'll be talking about brackets, an opensource IDE built with HTML/Javascript. If you've wondered what I've been up too, come say hi!

Jun 21

You can check out the session code here: on GitHub.

The presentation will be in the community area today at 11am. Come check it out! The slides are attached in case you want to follow along.

Oct 5

I just confirmed that I'll be speaking at 360Max on October 5th, 2011 at 10am. This is a conference within a conference (Adobe Max). My presentation will be on Native Process in Adobe Air. I gave a similar talk a few months ago at the Capital Area Flex Users-group. This will be my first Adobe Max so I'm pretty excited. Schedule/Info here:

Aug 18

Here's a link to my presentation, Source code will be posted here shortly. Or you can search to see some outdated code from DrupalCon SF and DesignCamp Boston.

Jul 22

Well somehow I got pretty booked up in July and August. Here's the schedule:

CapitalCamp is sold out and RIACon is selling out fast! DC Flex Usersgroup is always free!

Jun 22


Subscribe to Front page feed