RSS

CEK.io

Chris EK, on life as a continually learning software engineer.

Typeahead and Gon: A How-To Guide (Part 1 of 2)

I’m currently working on a project with users and messages (full Github repo here). The main functionality is complete—the first 80%, if you will—but there’s plenty more to do—Avi has emphasized that the finishing touches, the final 20%, can drag on for much longer than anticipated. One aspect of that final 20% was a key front end feature: typeahead.

If you think you don’t know what typeahead is, you’re mistaken. You do know what typeahead is, you just might now it as autocomplete. I choose to refer to it specifically as typeahead, because I used Twitter’s typeahead.js (Twitter’s engineers wrote a handy blog post about it).

Typeahead.js is “a flexible JavaScript library that provides a strong foundation for building robust typeaheads,” which means it supplements jQuery with the .typeahead() method. This method, when passed a dataset, can compute suggestions for a given suggestion. At the end of the day, it makes form inputs dynamic and prettier.

The How-To

I implemented this into my Rails app and—surprise!—there’s a Ruby Gem that packages typeahead.js specifically for the Rails asset pipeline. This guide will cover that twitter-typeahead-rails gem and a couple other requisite pieces (the Gon gem, javascript assets, html in the views, etc.).

This process really breaks down to two main steps: (1) making a dataset accessible to the view by getting Rails variables into Javascript (Gon does that) and (2) using that dataset with the .typeahead JavaScript method.

1. The Gon gem

  • Watch this RailsCast. Seriously, Ryan Bates covers Gon very well and in just over six minutes. Then again, you could try to save those six minutes by skipping ahead to the next couple steps.

  • Add the gem (copy the following to your Gemfile): gem 'gon'.

  • Add <%= include_gon %> to the head of your html, right under the title attribute (probably in the application.html.erb view). Your html should look something like this:
    (application.html.erb) download
    1
    2
    3
    4
    5
    6
    7
    
    <!DOCTYPE html>
    <html>
      <head>
        <title>TenderMessenger</title>
        <%= include_gon %>
          ...other scripts, etc.
      </head>
    

  • Add Gon to your controllers. The idea is to assign your Rails variable to a Gon variable (which will become a JavaScript variable). In my case, trying to pass users’ names and images, it looked like this:
    (some_controller.rb) download
    1
    2
    3
    4
    5
    
    def index
      gon.usernames = User.pluck(:name)
      gon.gravatars = User.all.map { |user| user.gravatar }
      # ...other code that belongs in the controller action
    end
    
    You can assign any array to the Gon variable. Both of my examples return arrays by calling methods (ActiveRecord query for usernames and mapping image links), but you could just as easily do gon.variable = [example1, example2, example3] (though, as we’ll see, you could add this data straight into your JavaScript file)

  • Assign that Gon variable to a JavaScript variable. In whatever .js file you choose, assign gon.whatever to var whateverVariable. Continuing my example:
    (random.js) download
    1
    2
    3
    4
    
    // Other javascript...
    var gravatars = gon.gravatars
    var usernames = gon.usernames;
    // More javascript
    
    Try adding alert(whateverVariable) (in my example alert(users)). Look at that–your dataset has made it from Rails to JavaScript! (Yes, I have funny test users).

I will post Part 2 of this blog tomorrow, which will cover using this JavaScript variable with the .typeahead() method to create a fancy typeahead like the one with Tenderlove below. I may combine it all into one post. But this seems long enough for now.

Edit:Here’s part 2!

Resources