Tech Time

Incantations, poetry, and intellectual detritus flowing from great minds. By the engineers of Harvest.

Focus

The choir doth preach: Focus, programmer, lest ye be distracted to failure. You listen. This week you will define your goals and accomplish them. You will succeed...

Suddenly it is Friday and you know not what you have done. Your back hurts. You've knowledge-worked so hard as to cause yourself physical pain. What was it you set out Monday to achieve?

Focus is a learned skill that must be practiced. You cannot wish yourself to a focused work week or a focused life. Goals are a first step. Limits help you carve out pockets of time. Practice leads to forming one of the most powerful habits you can learn.

It is impossible to maintain focus without defining limits. Pick your goals and plan time to focus on the problem at hand. Clear a day or several mornings. Remove the distractions of email and chat. Communicate your intent.

And focus.

Plan your time to work. Plan your time not to work. Do not break your rules for any reason outside of a true emergency. You cannot be a true practitioner of a focused life if you throw your limits out on a whim. Do not check email, Twitter, and Facebook. Shut off the notifications.

As focus is engrained within you, your accomplishments will speak for themselves. Others will seek to emulate you; your sense of purpose. You will be ruthless in eliminating distractions. You will have more success in your career. You will be intentional with your free time. You will be happier.

All because you learned to focus.

In Defense Of Rem Units

Over the past couple weeks, I’ve had the opportunity to design and build Harvest’s 2012 Year In Work, which afforded me a chance to try out something new: the rem unit of measurement.

You’re probably already familiar with em units – they’ve been a common feature of CSS for the past decade – but a crash course: elements specified using em units are sized relative to the font-size of their parent element. For example, if a paragraph has a specified font-size of 2em, and the div it’s inside of has a font-size of 10px, then the effective font-size of the paragraph is 10px × 2em, which is 20px.

.parent {
    font-size: 10px; }
.parent p.child {
    font-size: 2em; /* outputs to 20px */ }

“Rem” stands for “root em”. Similar to em units, they calculate size based on an ancestor element’s font-size, except rem units always calculate against the html/root element’s base size. So if the html element has a font-size of 16px, then a paragraph with font-size of 2rem will always be 32px, regardless of the its parent div or any other element.

html {
    font-size: 16px; }
.parent {
    font-size: 10px; }
.parent p.child {
    font-size: 2rem; /* relative to html - outputs to 32px */ }

This is incredibly compelling, particularly because...

I try to avoid Em Units

Em units are useful for a variety of reasons, the most important being that they’re flexible and scalable. You can set the highest parent element, html, to have a relative font-size specified with an em value or a percentage, and it will calculate a specific value based on the browser’s default font-size. This is great for printed documents (the typical default browser print size is 12px vs. 16px for screen display), and it allows your site to scale with the user’s preference, especially in older browsers that have a harder time with page/text zoom.

However, em units have their drawbacks as well, particularly for web-apps or teams where many people touch the CSS. Consider Harvest, a web-app with thousands of lines of CSS code. We use modularized CSS for various designs and extensions used in various places throughout the app (like our calendar pop-over). If any of our styles were set in ems, then there’s a possibility that the pop-over would get added to too many different parent elements in too many different places with various font-sizes, causing it to look different each time and ruining the consistency.

As both a product designer and an HTML/CSS developer accustomed to decently-sized dev teams, I’ve learned to avoid em units for the bulk of app development. On smaller and less complicated sites, these issues are less apparent, but still necessary to keep in mind and design around.

Enter the Rem unit

I first heard about rem units a few years ago, but haven’t seen much talk or use since. I’m not sure why, though, as they have always seemed incredibly well-suited for web design – they behave much more predictably like pixels, but retain the flexibility of ems. If an element is always supposed to have a font-size of 16px at base size, regardless of the parent element, then rems make more sense than ems. It’s much easier to convert design comps into code without worrying about parent elements. The same goes for width, height, padding, margin, and all other style attributes that specify size.

I decided to try rem units for Harvest’s 2012 Year In Work to learn their strengths and weaknesses first-hand in a real world environment. I found them to be very useful, and a joy to use for a variety of reasons.

What you should know about Rem units

They help with Responsive Design

Since all rem units are relative to a single number – the html font-size – you need only set the breakpoints on this number for a simple responsive layout. Here’s the code used in the Year In Work’s Sass file:

Responsive HTML font-size

While this isn’t appropriate for every design, being able to set a base size for your entire layout for every breakpoint can be incredibly useful.

**Pro-tip:* While I used pixel values, you could use % values as well.*

Great for Rapid Prototyping

I’ve signed on to the theory of prototyping a design directly in HTML/CSS, and avoiding Photoshop altogether (sometimes). When experimenting with a design right within the browser, the last thing you want to worry about is getting the sizes exactly right.

Set the html font-size to 16px, or whatever you want, and then quickly estimate the sizes for everything else and run with them. The h1 is probably 2.5x that size, h2 probably 2x, h3 probably 1.75x... etc. It’s fast. While you can use em units for this as well, using rem units avoids the issue of having to resize the h3 after putting it inside a div with a font-size on it – which is more likely as you tend to move things around quickly during rapid prototyping.

This is how I designed the Year In Work actually... there were no layout PSDs.

**Pro-tip:* Just like with ems, you’ll find you need to use fractions like 2.25 for some values. I always stuck to .25, .5, or .75 when not using a whole number, since my base size is 16px. However, as you can see in the screenshot above, the base size can change to 13px, which at 2.25rem is 29.25px. Since you can’t have a quarter pixel, some browsers render this as 29px, others as 30px. I found this to be a minor trade-off (but something to keep in mind) for the ease of the responsive layout that I explained above.*

All sizes should be in Rem units

Some developers prefer a mix of pixels, percentages, and ems for different styles on different elements, all within the same page. Personally, I think this makes development confusing, but it can work.

This doesn’t work well when using rem units, though. Using rems on only some styles doesn’t offer any advantage – you might as well just use pixels. You have to commit to replacing all pixel values with rem units if you want the responsive advantages.

**Pro-tip:* You can use ems and rems together, though. Check out the h3 on slide 3 of The Year In Work – I didn’t feel like calculating the size of the “21”, so I gave it a font-size of 1.25 em.*

They can influence your design style

Sometimes you need an element to be only 3px – this translates to 0.1875rem... not very conducive to simplified design code. However, you can allow this to influence your design, and decide to just use 0.2rem (or 0.25rem, like I mentioned above). Often the difference isn’t important.

Or, if that 3px is a border-radius, maybe you decide to remove it entirely. Those are design decisions you have to make. I increasingly found that I prefer numbers to end in 0 or 5, or at least an even number. If an element was 9rem wide, I would just make it 10rem and see how that felt. The majority of the time it worked out just fine, and psychologically I felt like my code and design was clearer, cleaner, and easier to work with.

It’s because of this reason that rem units probably aren’t the best for sophisticated web-apps. They worked great for the Year In Work, but I don’t see us using them in Harvest anytime soon – that would probably slow down development rather than speed it up. There are just too many small pixel sizes in various places for rem units to be useful.

However, if you put the last two points together, and you fully use rems from the start while allowing yourself to design around the strengths and weaknesses of rem units, you could end up with a nice web-app that scales nicely between browser and tablet sizes and page zooms.

They do not work in IE8

This may be the biggest reason why we don’t hear about rem units too often currently, as many sites (especially web-apps) still need to support IE8. Luckily, that was not a requirement for the Year In Work, which we decided should be a showcase of some forward-thinking design and techniques.

If you’re working on a personal or small site, I doubt this will be a big issue for you.

Final Thoughts

Rem units aren’t great for every occasion, but for some sites they can be a great tool. They are worth trying regardless of what you're normally comfortable with:

  • If you’re coming from a background that always uses pixels, rems are virtually the same thing, but they add the responsiveness that was missing in your old designs.
  • If you’re coming from a background that always uses ems, rems can solve your issues of elements-within-elements becoming inconsistent and having to add multiple definitions in your stylesheet.

Either way, I hope to see more rem usage in the future. I don’t feel like it’s been fully explored yet, and think there’s some still use cases that haven’t been discovered.

Find Bugs Once and the Joy of Bug Fixing

Every programmer struggles with testing early in their career. My feedback leaving my first internship was: Barry, you do not express an interest in testing. I was allergic to it. In my defense, I already felt it was a pretty widely reviled task. As a youngster new to professional programming I was just telling the truth.

During my seven long years in corporate IT I learned that I was not so much allergic to testing as I was allergic to manual testing. Scratch that. Early in my career I had to manual test and didn't realize that automated testing was something to be embraced. By the end of my time in corporate IT I was the person shouting from the mountain top, "Why are we not writing more automated tests?!"

Where does this evolution come from? Experience. The bit starts flipping the first time you see a bug you fixed in the past reappear for a second time. Then you become 80% confident that bug fixes should arrive with tests. You become 90% confident when you see a bug fix someone else committed appear a second time because the fix went through with no tests. You become a rabid 100% adherent when you see a bug fix you reviewed appear a second time because no tests were written even though you insisted there should be tests. It might take years to get to the 100% state, but all good pragmatic practitioners of programming get there eventually.

My advice to a young programmer is to embrace the experience of battle-tested peers. Our craft is relatively young, but remember people have still been doing it a long time. I recently read The Pragmatic Programmer. As a professional programmer for nearly 15 years, it read a bit like Aristotle; almost entirely obvious. It's not obvious when you first start programming, though! Read this book.

Finally we'd like to reveal the single most important concept in testing. It is an obvious one, and virtually every textbook says to do it this way. But for some reason most projects do not. If a bug slips through the net of existing tests, you need to add a new test to trap it next time.

Once a human tester finds a bug, it should be the last time a human tester finds that bug. The automated tests should be modified to check for that particular bug from then on, every time, with no exceptions, no matter how trivial, and no matter how much the developer complains and says, "Oh, that will never happen again."

Because it will happen again. And we just don't have the time to go chasing after bugs that the automated tests could have found for us. We have to spend our time writing new code – and new bugs.

Finding joy

Step back and consider all the possible work you do. The overtly glamorous work of new products and new features results in a shower of praise from customers and teammates alike. If you really consider the results of that work, really think about it, you understand that these new features and products heap only pain on your team. New bugs, new maintenance, new risks, new support requests. Important things happen with new things: praise, morale, customer acquisition, and the bottom line all grow. Yet even with very well designed features the net result to the team is pain.

From this perspective bug fixing is a beautiful thing. It is the only place where you can have a positive impact on the entire team. A bug fix, with tests mind you, will: reduce the noise disrupting future support programmers, please customers now and into the future, reduce the cost of maintenance to the product, and reduce load on the customer support team. While you're fixing bugs, everyone else is adding bugs to the product. You are removing pain and thereby making the life of everyone else on the team every so slightly better. You are protecting most of the team from even having to think about all of this pain, if only for a short time.

Keep this in mind the next time you are writing a test for a trivial bug fix. Embrace the opportunity, the beauty, of the situation.

photo credit: EJP Photo via photopin cc

A Week to Learn and a Lifetime to Master

Twice per year Harvest has a team hack week. We seek to get the mental juices flowing; exploring many things we do not get to experience in our day-to-day. It's a wonderful time of experimentation, quick wins, and rapid failures.

This hack week we discovered a suggestion can go a long way. As we thought about our goals for the week, we decided to focus on internal tools. Our hack weeks are pretty much open season, so working on tools was by no means a requirement. Yet the suggestion resulted in a flood of ideas. We discovered that a lot people at Harvest indeed felt like we were lacking in our tools.

The number of hack week ideas piled up like never before. It was wonderful! Leading up to previous hack weeks there was a bit of a struggle collecting project ideas. Sometimes it is hard to pull oneself out of one's daily work to think about what one would do if given a week to work on anything. Providing a theme was great for idea generation.

Yet at the conclusion of the week many did not feel very "hacky" about what was accomplished. In a lot of ways hack week turned out to be a work week viewed from a different perspective. It was not quite as exhilarating as previous hack weeks, which we approached with reckless abandon.

As beneficial as the theme was for idea generation, it definitely took away from the hack vibes. That was unfortunate. I will not say that themes are verboten from future Harvest hack weeks. Perhaps an abstract suggestion of "speed" or "green" could serve as an effective constraint and trigger ideas without limiting the distance one might travel away from one's comfort zone. We want our hack weeks to be wild and invigorating.

To focus on the positive, a great discovery was made during Harvest's latest hack week: the need to maintain and act upon a list of all the things our development team has thought about to make our tools, process and systems better. Some of the tools created during hack week are already being used by our team. Many of the projects laid groundwork for future improvements. When the team focused on looking for deficiencies in our process and tools they found many opportunities. Recognizing this fact has given us the motivation to continuously shore up our internals, making us as nimble as possible for whatever the future brings.

ActiveResource XML bug fix for Rails 3.0.19

The past two weeks have been abuzz with security patches for Rails. Yesterday's in particular is quite serious, and if you haven't upgraded yet, you really should.

This morning, we noticed an issue with a few of our applications that are still running Rails v3.0.x. There is currently a bug for security-patched Rails v3.0 applications serving XML data to ActiveResource consumers (think of a typical Rails XML API).

This bug was noticed 2 years ago by jaw6 and his fix was committed to Rails v3.2 and v3.1, but not v3.0. This wasn't an issue until yesterday's security upgrade.

Now if the latest version of ActiveResource requests XML data from a Rails v3.0 server, they may raise an odd error Hash::DisallowedType: Disallowed type attribute: "yaml"

We have just had a pull request merged into Rails that will fix this issue in v3.0.20 and should be released soon. Until then, if you need to apply this immediately you can have Bundler use this code directly from GitHub:


# In your Gemfile
gem "rails", :git => 'https://github.com/rails/rails.git', :branch => '3-0-stable'

Improving My Vim Skills

I recently attended the Vim Masterclass online course lead by vimcasts.org's Drew Neil. It was a great learning experience and I immediately bought Drew's book, Practical Vim, to learn even more. This got me thinking about why I love Vim and why, after more than two years, I'm still finding myself striving to improve my Vim skills.

Why Learn Vim

It might seem a little odd to talk about having skills in a text editor. Certainly, I've never thought about improving my TextMate skills. I believe the reason is that Vim feels more like programming than it feels like a typing tool. Just as composing JavaScript functions creates the behavior in a web page, Vim commands generate the JavaScript file itself. If you think about Vim commands as a language to be learned, it will make more sense why it's a skill to be developed over time. Consider the following command:

22Gfzdaw

Without getting into the specifics, this line means, “Go to line 22, move the cursor to the first occurrence of the letter ‘z’ and delete the entire word.” Doesn't this seem like coding? Obscure coding, for sure, but once you understand the syntax, it's pretty powerful. Even though the biggest hurdle to understanding Vim is having to memorize such terse commands, there are plenty online tutorials to teach the mnemonics that will help you remember them.

Best Practices

Just like a programming language, there are many different ways to achieve the same outcome. And, just like a programming language, there are best practices to get the most out of what you type. In his online course, Drew Neil talks about what he calls “The Dot Formula.” In Vim, the Dot Command (pressing the dot key) will repeat a command. Since a lot of what we do as developers is repetitive in nature, this is a really handy feature. However, to get the most out of the Dot Command, you need to consider how you type your commands.

viwcfoo

ciwfoo

In the above two lines, they both will change a word to foo. The first command will use visual mode to highlight the word then change it to ‘foo’. This is nice because you see what you are about to change. However, you don't get the full power of the Dot Command. If you moved over to another word and pressed the dot key, you get unexpected results. Now try the second command. This one changes the word under the cursor to 'foo' without using visual mode. Now move to another word and press the dot key. That works as expected.

Although the above is a somewhat trivial example, it shows that really understanding the mechanics behind Vim's syntax can help you to be more efficient.

Coolest Thing I've Learned

I'm trying to get my point across without writing an insanely long post about Vim. So, I'm going to leave you with this one command that I learned from the Vim MasterClass that I was the most impressed with. The ‘normal’ command.

:10,20 normal A;<enter>

This essentially says, “Append a semi-colon to the end of each line on lines 10 through 20”. We are able to write one command to affect 10 lines of code. Additionally, you can use the Dot Command in normal mode to repeat the above on another selection of lines.

:30,40 normal .<enter>

Always Learning

This has barely touched the surface of what Vim can do. If you've never tried Vim, I hope I've made you curious. If you do use Vim, I hope I've given you something you haven't seen before.

The Secret to a Successful Distributed Team? Ask Aretha.

I’ve been at Harvest for more than two years, and in that time I’ve seen our team grow from 8 to 25 people. A large portion of our team is in NYC, but we’ve also got coworkers in 6 US states, Hungary and Canada. On top of that, Harvesters have also been know to take “work-cations” where they travel somewhere outside of the office, but work a full day as if they hadn’t left.

With a group scattered all over the place, it’s really important that the people who join our team can be counted on to deliver. I’ve been lucky enough to be involved in the hiring process at Harvest and, though I think I’ve done a fair job, I’ve never really nailed down a checklist of qualities someone should have before they’re allowed to join the Harvest fold.

Over the past two months, I’ve been working from the road as my wife and I tour the US and southern Canada. The trip has afforded me some time to visit four of my remote coworkers and spend a few days working with them on their home turf. Working in remote coworkers’ natural environments has given me a little perspective into how their day works and how they view our teammates. It’s also given me a better sense of who they are as people.

My trip has gotten me back to thinking about what makes a good coworker and my conclusions aren’t exactly rocket science: you want someone who builds things that she’s proud of and who cares about her tools and methodology, you want someone you can trust to sit and work and not play video games all day, and you want someone who can have a conversation with you even though your worldviews may not always be 100% lined up.

It turns out that these qualities can be summed up in one perfectly magical word: respect.

When talented people respect each other, building a web application feels like no big deal. Digging in on a hard problem isn’t as intimidating when you know there are 9 other developers who have your back. It’s more comfortable to argue a position you believe in when you know your opinion will receive real consideration. It’s easy to point out to someone a potentially better way to do something when you know they’re not going to freak out that you stuck your nose into their turf.

Harvest’s culture of respect isn’t something that can be artificially generated or forced upon a team. Respect can’t be learned from a company handbook or a few weeks of training – respect comes from a lifetime of experience interacting with other people. You can hire all the genius rockstar ninja magicians you want, but hiring even one person who holds his coworkers in contempt will poison the well for everyone.

The next time I’m asked to talk with a candidate, I’m going to put R-E-S-P-E-C-T at the top of my checklist.

Introducing Sidetap

When we began working on the New Harvest Mobile Timesheet, we set out some basic tenets that we wanted to guide the project: ease of use, speed and feel.

Of the three tenets, my responsibilities for the project mostly focused on making the app feel nice to use. We love the way iOS feels and wanted Harvest on the iPhone to feel as much like a native app as possible. Building a web interface that feels like a native app is a risky proposition because the closer you get to simulating native behavior, the more noticeable the little differences become (this is the web vs. native “uncanny valley”, if you will). Nevertheless, we focused on a few specific areas that we most associate with the feel of iOS apps: scrolling and animation between views.

Early on, we looked very closely at the Hacker News mobile interface built by Lim Chee Aun. Not only did it work great on iOS, but he took painstaking steps to document the experience in a massive blog post (part 1, part 2) that should be required reading for anyone building a web app targeted at iOS devices. His project didn’t work on Android or other platforms, but we were hopeful that we would be able to use his work as a starting point and bring a lot of that functionality back to Android. However, after building some early prototypes, it became clear that delivering a unified iOS-like experience to all mobile platforms was not going be a worthwhile pursuit.

Enter Sidetap

We decided to change tack and build a framework that delivers a satisfying but more simplistic interface to most mobile browsers. The basic interface doesn’t include things like fixed headers, content panel animations or hidden address bars, but it works in a way that doesn’t make it feel half-assed. If iOS5+ is detected, we enhance the interface to include the missing features and deliver a more robust, native-feeling interface.

We call our new framework Sidetap after the side-based navigation it was built around (the kind of side navigation you can find in iOS apps like Facebook and Sparrow).

Sidetap tries to be useful by not doing too much. It focuses on the hardest problems to solve which leaves you to think about how your content looks and works. These are the things that Sidetap does best:

Scrolling

Replicating iOS scrolling used to be a tremendous hassle and entire JavaScript libraries were written to attempt the feat. As of iOS 5, it has become a breeze — just add -webkit-overflow-scrolling: touch to an HTML element that has some kind of overflow set on it. There are some gotchas, but working with this has been pretty nice.

In our case, the element that gets scrolled is nestled three layers deep inside the content panel. Using three divs help stop the browser from scrolling past the element when you reach the bottom of the div. If you’re curious about this technique, you should read this discussion on Github.

Animation

All animations in Sidetap are powered by webkit-animation which run silky-smooth thanks to hardware acceleration built into mobile Safari. We’ve included two types of bi-directional content panel animations to start (slide-up and slide-over), but plan to include more in future releases.

Hiding the Address Bar

We wanted to take advantage of as much of the screen real estate as we could, so that meant hiding the address bar and keeping it hidden. Hiding the address bar is simply done by scrolling the page to the 0 y-coordinate. However, because Sidetap’s main container is set to 100% of the browser window, there wasn’t enough actual content to scroll anything. To get around this, we apply a large amount of padding to the body element on page load and then scroll to 0. After a delay, we reset the container to 100% height and remove the body padding. This gives us a div that’s the perfect window height and an address bar that’s gone away.

Fixed Headers

Fixed headers should be easy, right? On desktop browsers, using position: fixed is a reliable way to keep an element in the same position regardless of how a page is scrolled, but fixed positioning wasn’t built into mobile Safari until iOS5. We tried using position: fixed in an early Sidetap prototype and, unfortunately, the current implementation does not meet expectations (see Remy Sharp’s thorough treatise on all that is wrong with fixed positioning).

Luckily, there was a relatively simple workaround (thanks to the fact that we abandoned fixed headers on non-iOS platforms). To create our fixed headers, we just position them absolutely in the content-panel (which has a non-scrolling height of 100%) and then add the appropriate padding to our scrollable sub-divs. Piece of cake!

Works With the JS MVC of Your Choice

Though we built Sidetap alongside Backbone.js, it is not a requirement and Sidetap could operate alongside any MVC framework of your choice (or no framework at all). Sidetap’s job is simply to take content and animate it — it’s not opinionated about where that content comes from (though it does expect it to follow the basic markup pattern).

Just instantiate Sidetap and store a reference to it. To add and animate to new content, reference the class and Sidetap handles all the fun. Here’s how this looks in a Timesheet view (using Backbone):

Harvest.sidetap.slideToNewContent($@el)

That’s it.

What’s Next

Sidetap isn’t perfect and there are a few things that we’ve targeted for improvement:

  • Header animation: iOS header animation is surprisingly complicated and Sidetap doesn’t even come close to getting it right.
  • Touch events: there is a natural delay in touch events in mobile Safari for which several libraries have been created. Getting one of these libraries integrated would be nice.
  • More iPad friendly: The navigation should stay visible on the iPad when in landscape orientation.

Give It a Try

We realize there are no shortage of mobile frameworks available today, but we just didn’t find one that fit our desired style of navigation or didn’t include a lot of bloat (Sidetap is only 2k minified and gzipped). We feel that Sidetap fills this space nicely by trying to do as little as possible (just animate, baby).

We’re releasing Sidetap as an open source project today and we encourage you to try it out and see how it feels. Our sample app shows just how simple switching between content can be. Your contributions, issues and suggestions are very welcome.

Harvey: A Second Face for Your JavaScript

When media queries finally reached a state of good support across a lot of browsers, we started to make our web applications adapt to our users’ devices by optimizing the layout to focus on the content.

But now that we’ve grown to like and incorporate this new adaptive approach, what’s next? We set foot on fairly new grounds not too long ago and so we are still discovering new corners of this land we call Responsive Web Design. One of the things that we will explore next is the ability to add different modes of interaction to our sites, i.e., conditionally executing different JavaScript based on the screen dimensions of the rendering device.

While the browser (or rather, most browsers…) do a pretty good job when it comes to media queries in CSS, there is no easy and, more importantly, simplified tool for the JavaScript camp… until now!

Adapt or Die.

While we were working on the new site for WalkaboutNYC, I ran into different scenarios where it was necessary to change the UI drastically and pull in additional content for larger screens.

We built WalkaboutNYC “mobile first” to ensure that the site — especially the schedule and itinerary pages — was accessible on a wide range of different devices and could easily be used on-the-go by all attendees on the day of the event.

This approach allowed us to focus on only the most important and fundamental content and resulted in a single codebase of clean and semantic markup for the site. However, with increasing screen size, we wanted to enrich the user experience with enhanced navigation elements and offer a wider set of features which went beyond merely changing the layout. We had to change the DOM!

UI elements: Initially, we use native select boxes for more natural UX on small screens (e.g., phones), but then transform them into a list of radio buttons as soon as the screen is wide enough:

External resources: To avoid long load and processing times on small and less capable devices, we decided not to include social media sharing options on those devices. Instead, they are dynamically injected after the page is loaded — and only on large screens:

…Now It’s as Easy as Flipping A Coin

Instead of using the tradional, more cluttered and less reliable methods of checking the screen width in JavaScript and/or listening to window.onresize() to detect changes, I wrote Harvey.

Harvey executes certain parts of your JavaScript depending on the current device’s type, screen size, resolution, orientation, or any of the same media query types you would use in CSS. Harvey is originally written in CoffeeScript, weighs only 3k (1k gzipped) and has no external dependencies.

Once you attach a condition to Harvey (in the form of a valid CSS media query), you can register three callbacks for it. The first one, setup(), will be called the first time your media query becomes valid. The second and third callbacks, on() and off(), are executed each time that media query becomes valid or invalid, respectively:

Harvey.attach('screen and (min-width:600px)', {
    setup:  function() {},
    on:     function() {},
    off:    function() {}
});

Of course, you can attach as many media queries as you want using the same syntax. And all the media queries used in Harvey can be completely independent of the media queries you may be using in your CSS.

Harvey includes a modified version of Scott Jehl's and Paul Irish’s matchMedia polyfill as well as some bug fixes uncovered by Nicholas Zakas. It’s built on top of the matchMedia interface as defined in W3C’s CSSOM View Module.

Get Out There and Explore

Help us push the borders of frontend development to new undiscovered territories! Get the code, find out how it works, and use it in your own projects. Feel free to contribute and to extend Harvey with your own ideas!

An Experiment with Backbone.js

We are launching a new mobile web interface for Harvest today. It introduces a redesigned mobile time tracking interface and a new Team Status page, both of which are kept up to date regardless of updates being made on other devices. It is also technically implemented differently than most of the Harvest UI. We wanted to experiment with some cutting-edge technologies, and this is the result!

On the initial page load we serve a thin shell along with some bootstrapping data, then use JavaScript to draw user interface on the client side. Updates to the timesheet happen through background requests to the server using a REST-like API. Driving it all is Backbone.js, a framework that brings some order to client-side web-app development. It does this by bringing a few concepts to the browser: Models, Collections and Views.

Backbone Models

Models are the basic objects the application operates upon. In Harvest's case, one such Model could be Project. Usually there is a 1:1 mapping between the Backbone Models and backend Models (database tables), but this is not strictly necessary. For example, on the frontend we have a RecentProjectTask Model used to ease project task selection that does not have a direct match in the database.

The best part about Backbone Models is actually related to another Backbone feature called Events and how they interact with Views. In a framework like Rails, a Model is a passive object that gets operated on by a controller or perhaps another Model. Backbone Models, on the other hand broadcast events that are processed by Views subscribing to them. There is a useful decoupling between action and reaction.

Backbone Collections

Collections are a set of Models basically corresponding to a set of rows in a backend database, though again this need not be so. They also have the same Event love that Models have.

Backbone Views

Views are responsible for presenting the user interface and responding to user events. For this reason Backbone Views, are more than just passive string generators. In fact, as a best practice, the HTML for the user interface should be stored in Templates instead. The choice of how Templates are implemented is not determined by Backbone. Unlike some opinionated frameworks, not much is set in stone by Backbone.

Beside being able to react on events, the next best thing about Views is the ability to nest them. This nesting drives the structure of the code starting from the UI mockup, for example:

This screen suggests at least three different kinds of Views. First, there is the top container responsible for the header, the navigation to other days, the opening of the menu, etc. Second, there is the View shown in pink that draws out all the entries. This View is tied to a Backbone Collection.

On the third level, there are small individual Views tied to each entry present on the screen. Some of these are outlined in blue in the above picture. Nesting occurs naturally, the top container View creates the next level of Views below. The containing view may also referrences to its child Views in instance variables, but this is usually no necessary. The a nested View takes on an active role and does not strictly need to be operated on by its parent.

For example, when you delete timesheet entry the corresponding View (outlined in blue above) will get notified via a destroy event and will have the opportunity to remove itself accordingly. The deleted timesheet entry was part of a Collection that also gets notified, which in turn notifies the containing View, ultimately allowing a different Total Hours value to be displayed on screen. Control can flow entirely through events without needing instance variables.

It Is a Sour Cherry

The advantage of using a framework like Backbone is its ordered method for creating fluid interactions. Ajax made partial screen updates possible, but making this fluid is difficult if you're rendering parts of the UI on the backend.

For example, on the current non-mobile Harvest Timesheet interface, when you start a timer the response is instant, even though the save operation may actually happen a few milliseconds later. The JavaScript will redraw the UI before the operation completes, especially when we know no reasons why the backend should return with an error in the future. Since everything related to the UI is in JavaScript, there is no longer a risk of redrawing differently on page load compared to redrawing on UI interactions.

It is not all that sweet, though. JavaScript, for all its expressiveness (and lately speed), is still no match for the wide body of helpers and libraries available on the backend, especially when than backend is as full-featured as Rails. If you want to textilize timesheet notes, it is easy on the backend but most likely it is a missing library or a buggy one on the frontend. Want to format timestamps in a friendly way like “9 minutes ago”, easy in Rails, but not implemented on the frontend.

Even worse: error handling on the browser is primitive at best. Whereas we capture a full stack trace along with headers and other information for later analysis upon a Ruby exception, there is nothing universally supported and as comprehensive in JavaScript. Rails functional tests are suddenly no longer enough and you need to look into tools like capybara-webkit to exercise your JavaScript programmatically.

If you compare the development speed of a Backbone-based UI to one driven entirely by Rails, then the latter will always win. However, we rarely create interfaces in pure Rails these days, so the choice is actually between using a framework like Backbone or writting ad-hoc JavaScript to do much of the same. Backbone is not a replacement for Rails; rather it brings order to your JavaScript code.