8

I've used this video http://railscasts.com/episodes/102-auto-complete-association-revised to set up an autocomplete search input in a form for my app. (The video may be for members only so I'll post my code as well. Essentially it searches a column of the DB (name) and autocompletes in a dropdown as you type. This all works fine however, what I'd like the form to do is submit the ID that correlates to the name, not the name itself.

I'm assuming theres no simple way to do this in just the view. Any help would be great. Code below, let me know if any other code would be helpful.

Thanks

Controller:

def game_name
  game.try(:name)
end

def game_name=(name)
  self.game = Game.find_by_name(name) if name.present?
end

Coffee:

jQuery ->
 $('#play_game_name').autocomplete
  source: $('#play_game_name').data('autocomplete-source')

In the view:

   <%= f.label :game_name, "Search for a game" %>
   <%= f.text_field :game_name, :class => "mlm mtm", data: {autocomplete_source: Game.order(:name).map(&:name)} %> 
Clayton Correia
  • 263
  • 1
  • 3
  • 16
  • If You have get value when you press DownKey or UpKey, look for [this post][1] [1]: http://stackoverflow.com/questions/8045773/jquery-ui-autocomplete-downarrow-uparrow – Fist Jan 09 '14 at 07:20

2 Answers2

12

In addition to doing as @LukasSvoboda suggested, you can also override the select event callback, which gets triggered when you select an item from the dropdown. In the callback, you can set the text field (which doesn't need to be submitted) to the "label" of the selected item and set the value of a hidden field of the game id (which does need to be submitted) to the "value" of the selected item.

In coffee:

jQuery ->
  $('#play_game_name').autocomplete
    source: $('#play_game_name').data('autocomplete-source')
    select: (event, ui) ->

    # necessary to prevent autocomplete from filling in 
    # with the value instead of the label
    event.preventDefault()

    $(this).val ui.item.label
    $('#game_id').val ui.item.value

In markup:

<%= text_field_tag nil, nil, :id => 'play_game_name', :class => "mlm mtm", data: {autocomplete_source: Game.order(:name).map { |t| { :label => t.name, :value => t.id } } %>
<%= f.hidden_field :game_id, id: 'game_id' %> # tailor to your model
cdesrosiers
  • 8,862
  • 2
  • 28
  • 33
  • Thanks for your answer. The autocomplete still works but everything after doesn't appear to be working. The search input still displays the value after clicking the drop down and the hidden input does not gain a value. Odd. It's like everything after the autocomplete isn't working. There's no JS errors =\ – Clayton Correia Nov 21 '12 at 23:00
  • My indentation was a little off, but I assume you fixed that on your end. Have you tried placing an alert in the select callback to see if it's at least firing? – cdesrosiers Nov 21 '12 at 23:52
  • Yeah, I fixed the indentation on my end. I cleaned up a bunch of other JS because I figured something elsewhere was causing me some problems. When I stip back everything except jquery and jquery UI I get the following error: "Uncaught ReferenceError: ui is not defined". Super strange, any thoughts? – Clayton Correia Nov 25 '12 at 20:01
  • Check that `$('#play_game_name').data('autocomplete-source')` is returning valid json. If not, try adding `.to_json` to the end of `Game.order(:name).map { |t| { :label => t.name, :value => t.id }`. – cdesrosiers Nov 25 '12 at 21:49
  • I'm an idiot, ignore my last comment. You code works. Thanks so much! – Clayton Correia Nov 25 '12 at 21:49
3

By the http://api.jqueryui.com/autocomplete/#option-source you can set data to the autocomplete.

You need to change the text_field line like:

<%= f.text_field :game_name, :class => "mlm mtm", data: {autocomplete_source: Game.order(:name).map { |t| { :label => t.name, :value => t.id } } %>

For more advanced features consider to use select2 or chosen.

Lukas Svoboda
  • 588
  • 1
  • 4
  • 10
  • Thanks a bunch for your answer! A couple notes: There's a } missing in your code (not a problem, fixed it up on my end). Your solution works but the ID is displayed in the input after the autocomplete. Would there be a simple way to display the Game name and submit the ID without the user ever seeing the ID number? – Clayton Correia Nov 18 '12 at 19:44