User Live Search with Stimulus, Turbo Frames and PgSearch

Curated ago by @jeremysmithco

Description

Here’s a solution I’ve used on a project to add a user switcher dropdown with typeahead search to a navbar. It uses the pg_search gem for Postgres full-text search.

There are a lot of blog posts out there with similar solutions, with terms like: typeahead, autocomplete, autosuggest, instant search.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%= tag.div(data: { controller: "live-search", live_search_hide_class: "hidden" }) do %>
  <%= form_tag users_searches_path, method: :get, data: { turbo_frame: "user_search", live_search_target: "form" } do %>
    <%= text_field_tag :query, "", placeholder: "Search users", data: { action: "live-search#process", live_search_target: "query" }, autofocus: true, autocomplete: "off", class: "w-full text-sm border-gray-300 rounded shadow-inner mb-2" %>
  <% end %>

  <%= turbo_frame_tag "user_search", src: users_searches_path, loading: "lazy", class: "flex flex-col overflow-y-scroll min-h-[28px] max-h-80" do %>
    <p class="px-1 py-1 text-sm text-gray-500">Loading…</p>
  <% end %>
<% end %>

<hr class="my-2">

<%= link_to "View All Users", users_path, class: "block px-1 py-1 text-sm text-blue-500 hover:bg-blue-500 hover:text-white" %>
<%= link_to "Create New User", new_user_path, class: "block px-1 py-1 text-sm text-blue-500 hover:bg-blue-500 hover:text-white" %>

The Turbo frame includes “Loading…” text, which will be replaced with an initial set of users when the frame lazy loads.