Dopplr adds SMS/Email/Twitter slurping

2008-07-07 20:00:00 -0400

My friend Matt Jones is one of the design leads on Dopplr, “an online tool for business travelers.” It’s a rather slick utility for anybody who does a lot of traveling and wants to share that information with others, connect up in various cities, track their travels, etc. That’s not all it does, but those are the very basics of it.

Anyway, Matt has an excited post out on their blog about some new features they just added – mainly the ability for you to not only send in your trip information via E-mail, SMS, or Twitter, but you can literally forward eTickets and various other itinerary confirmations from airlines and bookers straight to Dopplr, and have it enter all the trip info for you. Check out the slick video demonstration!

This is a huge ease-of-use improvement to their already great service, cutting down on double entry and making manual entry much easier. If you’re a reader of our site, or you use our tools, you’ll know we’re total geeks for streaming information into tools and using command-line interfaces. Nice job, fellas!

Modifying auto_complete for realistic use

2008-06-26 20:00:00 -0400

We use the Rails auto_complete plugin in both PingMe and Tempo, and while it’s incredibly handy, it takes a little bit of hacking to use it on a page where it will be used more than once. In the main time screen on Tempo any of the entries can be opened for editing, meaning more than one can be open at once, and each has its own auto complete field for tags:

Similarly in PingMe, we’ve got a list of pings on the screen, each a potential edit form (more than one can be edited at once), with auto complete on the tags field:

In this situation, when each form has the text_field_with_auto_complete in use, each has the same DOM ID: object_method, so ping_tags in PingMe and entry_tags in Tempo. Screwy things happen when you try to remotely update a DOM ID used more than once on a page, and those screwy things tend to change based on your browser, but basically the auto_complete plugin out-of-the-box will not work in this scenario.

We got around this by doing a bit of monkey patching to the auto complete plugin. This is what the initial text_field_with_auto_complete method looks like inside the plugin’s auto_complete_macros_helper.rb:

def text_field_with_auto_complete(object, method, tag_options = {}, completion_options = {})
(completion_options[:skip_style] ? "" : auto_complete_stylesheet) +
text_field(object, method, tag_options) +
content_tag("div", "", :id => "#{object}_#{method}_auto_complete", :class => "auto_complete") +
auto_complete_field("#{object}_#{method}", { :url => { :action => "auto_complete_for_#{object}_#{method}" } }.update(completion_options))

What we do is add an extra, optional parameter to this method that accepts an id, that we then patch in as the dom id we’ll use:

module AutoCompleteMacrosHelper
def text_field_with_auto_complete(object, method, tag_options = {}, completion_options = {}, object_id = nil)
field_id = (object_id.nil?) ? "#{object}_#{method}" : "#{object}_#{object_id}_#{method}"
(completion_options[:skip_style] ? "" : auto_complete_stylesheet) +
text_field(object, method, tag_options.merge({:id => field_id})) +
content_tag("div", "", :id => "#{field_id}_auto_complete", :class => "auto_complete") +
auto_complete_field(field_id, { :url => { :action => "auto_complete_for_#{object}_#{method}" } }.update(completion_options))

Now, on the form/template itself, we use this to generate the text field and type ahead div (we’re using HAML, not RHTML):

= text_field_with_auto_complete :entry, :tag_s, {:size => 50}, { :indicator => "entry_#{}_tag_s_form_loader", :frequency => 0.4, :tokens => ' ' },
= image_tag 'loading.gif', {:id => "entry_#{}_tag_s_form_loader", :style => 'display: none;'}
.auto_complete{:id => "entry_#{}_tag_s_auto_complete", :style => "display: none;"}

You’ll notice that each dom id is of the format entry_#id_tag_s_*.

In our controller, we have a few things that we need, nothing that complex:

auto_complete_for :entry, :tag_s

def auto_complete_for_entry_tag_s
unless params[:entry].nil? || params[:entry][:tag_s].blank?
tags = @current_user.tags.collect{|tag|[:ping][:tag_s].downcase) == 0 ? : nil}.compact
render :partial => 'autocomplete', :locals => { :items => tags }

Finally, we create a partial called ‘_autocomplete.haml’ that cranks through the items when the suggestions are displayed:

- items.each do |item|
%li.autocomplete_item= h item

Happily, this isn’t very different from the way the plugin recommends you do things, but allows you to support more than one field on the page at once when you have multiple instances of an object. I’m actually a bit surprised that there isn’t an inherent facility in the plugin for this, but it’s good learning for anyone looking to see how it’s done.

I should note that the above doesn’t denote how we really select out the set of tags for a user in Tempo, but it’s a simple example of how one might do it ;-)

Deep Thought

2008-06-25 20:00:00 -0400

With the new smart timers, I no longer need PingMe to remind me to sum up my time for the day. Thanks, old buddy!

(Although the street cleaning reminders are still pretty clutch…)

Workstreaming in Tempo Time Tracker

2008-06-24 20:00:00 -0400

We’re very excited to officially announce the latest Tempo upgrade.

This time around we decided to try something big. Really big. A game changer. Something that would begin to redefine the way people track time. We decided to reinvent the traditional time tracking timer in a way that doesn’t suck. And thus, the Workstream release was born.

As the name implies worktreaming borrows heavily from the concept of lifestreaming. It’s not a new term but we have our own take on it: you “stream” updates directly into Tempo as you start working on tasks. We track exactly how long you spend on each item as you make updates. There’s no need to explicitly enter hours or manually track time – we do all the work for you. You get an exact log of everything you’ve worked on, tagged, assigned to projects, shareable with colleagues, accessible through RSS, and ready for reporting.

Imagine using Twitter and messaging Tempo as you change streams and switch between projects. Or, use our new Dashboard Widget, the Bookmarklet, the Tempo application proper, your mobile phone, email, whatever. How you stream is up to you but the fluid approach leaves you free to think about the task at hand.

Visit our documentation for more details on how workstream timers work.

Honorable Mentions

In addition to the core workstreaming functionality we’ve added a ton of other supporting functionality to Tempo.


We’ve vastly improved the iPhone interface from our previously release. Now it looks and feels just like an iPhone app ought to, and provides you with the new timing features and a view into time you’ve already logged. Check it out on you iPhone at

Dashboard Widget

Users of Mac OS X can work really seamlessly with Tempo using our new Dashboard widget. A command-line interface and a view of recent time entries gives you the most important features.


Tempo now sports it’s own API. Use it to integrate with internal systems or 3rd party services.

Delegated Management & Proxy Time Entry

Tempo now makes managing teams even easier. First, any member of your project can be made a manager (including users on free account plans), allowing them to view the dashboard statistics, and manage the team roster. Managers can also perform “proxy time entry”, allowing them to enter and edit time entries on behalf of other people on the team. This rocks for groups where only one person is responsible for handling all the time entry.

Stream-lined Interface

We over-hauled Tempo’s interface to make it more intelligent and easier to work with. The ‘Add Entry’ tab provides a command-line interface for quickly entering time records or kicking off timers complete with type-ahead lookup when you start entering your tags!

The full web interface is sparser by hiding optional fields.

Lock and Unlock

Project managers can now easily lock and unlock individual time entries.

Smart Defaults

The web entry form remembers the last project you billed to, and whether you started a timer or not, saving you time when creating new records.


We hope you’ll find some of Tempo’s new features useful and we look forward to your feedback!

Deep Thought

2008-06-24 20:00:00 -0400

Git log commits remind me of summer afternoons. Like last week.

(Guess who hasn’t updated his time in a bit?)

((The new timer helps keep me straight nowadays!))