views:

456

answers:

2

In my application, users pick train stations from an autocompleting text field. Since there aren't many train stations (~100), I'd prefer for the field to autocomplete based on the contents of a client-side array rather than querying the server each time the user types a character (the goal is to make the autocomplete more responsive).

My question is how to do this in Rails in a maintainable, non-hacky way. My current solution is just putting this line at the bottom of index.html.erb:

<%= javascript_tag "var stations = #{Station.all.map {|s| s.name}.to_json}" %>

but this isn't great (for one thing, I have to remember the "stations" variable name while I'm working on application.js).

+1  A: 

In your application.js, on document ready, do an ajax call to fill a local array with the values.

document.observe("dom:loaded", function() {
  var stations;
  new Ajax.Request(url, {
    method: 'get',
    onSuccess: function(transport) {
      stations = transport.responseText;
    }
  });
});

My example might not work perfectly (as I use jQuery through jrails now), but it should give the right impression.

Mike Trpcic
+2  A: 

You can make a dynamically generated Javascript view file similar to how I show here.

Basically if you have a controller action (such as a javascripts controller stations action). It might look like this.

# in controllers/javascripts_controller.rb
def stations
  @stations = Station.all
end

you can then make a JavaScript view file like this...

// in views/javascripts/stations.js.erb
var stations = <%= @stations.map(&:name).to_json %>;
// ...

That javascript file can contain whatever javascript you want, so you can likely move some of application.js code there. You can then include this just like any other javascript file.

<%= javascript_include_tag 'stations' %>

This assumes it's under the 'javascripts' path which happens to be the case if you have a javascripts controller. Otherwise you'll have to pass the full path.

This does have the downside by making one more request to the Rails app, but you can likely add page caching to that js action to optimize that.

ryanb
The problem with this is that you can potentially put server side code into a publicly viewable location.
Mike Trpcic
The stations.js.erb view file is not located in the public directory. It is under views with the other templates. So you have no risk of exposing it as you would any other template.
ryanb