January 10, 2022
Autocomplete with Rails 7 (Hotwired turbo)
I watched the great video https://www.youtube.com/watch?v=PfCU0Nni8fI and after that, I tried to create a simpler auto-complete, without explicit turbo-stream.
The project consists of having a text field, when the user fills in and submits, the screen will show the filtered results.
The first step is: Creating a New Project (Is just a command, not too long of blablablablabla…)
The project consists of having a text field, when the user fills in and submits, the screen will show the filtered results.
The first step is: Creating a New Project (Is just a command, not too long of blablablablabla…)
rails new autocomplete # I'm Using rails 7.0.1 and Ruby 3.1
Now let's create a scaffold for the cities:
rails g scaffold city name:string
At this point, we have a 100% working CRUD but is very ugly, you can use https://simplecss.org/ to magically beautify your CRUD.
Creating a seed to generate cities, we will use the Faker gem.
# db/seeds.rb 1_000.times do City.create!(name: Faker::Address.unique.city) end
And run:
rails db:seed
Change the index method of cities_controller to search the cities based on the q parameter:
def index @cities = City.where('name Like ?', "%#{params[:q]}%") end
And change the cities/index.html.erb to this:
<p style="color: green"><%= notice %></p> <h1>Cities</h1> # data-turbo-frame: indicates that when the form is submitted only the cities in the frame will be updated <%= form_with url: cities_path, method: :get, data: {'turbo-frame': 'cities'} do |form| %> <% form.search_field :q, autofocus: true %> <% end %> # Put the list in the frame cities <%= turbo_frame_tag :cities do %> <div id="search-result"> <%= pluralize(@cities.count, 'city') %> found </div> <div id="cities-container"> <% @cities.each do |city| %> <%= render city %> <p> <%= link_to "Show this city", city %> </p> <% end %> </div> <% end %> <%= link_to "New city", new_city_path %>
_city.html.erb
<p> <strong>Name:</strong> <%= highlight(city.name, params[:q]) %> </p>
When the form is submitted, only the frame of cities will be updated, this is possible by the https://turbo.hotwired.dev/handbook/frames.
There is some overhead because there is all the HTML in the response and not just the frame, but I think it's a reasonable price to pay due to the simplicity of the solution.