caspg
Real-time Search with Phoenix LiveView and Tailwind
Hi everyone,
I recently implemented a real-time search feature in a Phoenix application using LiveView and Tailwind, and I wanted to share the code with the community.
The code includes an example of how to use LiveView to dynamically update the search results based on user input, as well as some optional TypeScript code to allow users to navigate the search results using the keyboard (up and down arrow keys).
You can check out a demo of the feature in action at travelermap.net (search bar is in top right corner), and I have to say, the results are super cool
! The real-time updates are seamless and make the search experience much more intuitive.
Here’s a link to the code on GitHub:
Let me know if you have any questions or feedback!
Most Liked
milangupta
Really neat ! Thank you …
I have been trying to figure out a fuzzier search than ilike … try adding this … helps with spelling mistakes etc.
|> where(fragment("SIMILARITY(p.name, ?) > .30", ^search_query))
|> order_by(fragment("LEVENSHTEIN(p.name, ?)", ^search_query))
caspg
Wikipedia modal is pure JS. I created this website as a static, non-live phoenix app. Now, I’m in the process of migrating to live views. But still, I think modals should be opened with JS commands to avoid round trips to the server.
caspg
@ghenry I’m using 1.7
I was just referencing the previous comment asking if I’m using send_update.
@maz I’m just using MapLibre - MapLibre GL JS. The map is rendered as separate LiveView with sticky: true option so it’s not re-rendered between navigations.
addstar
Nice one! I recently made a similar feature. A couple of things I noticed.
You can have multiple items highlighted if your mouse is in the results section and if you use the arrow keys. Prob not really an issue but the way I approached this was to set the attribute aria-selected on the item using a combination of keydown and mouseenter/mouseleave events.
If you have a long list of results and you use the arrow keys it doesn’t auto scroll. Look into scrollIntoView.
You should probably also use <.focus_wrap /> around your modal for accessibility.
How did did you approach changing the keyboard shortcut icon e.g. the command icon to a windows icon based on the users OS?
caspg
You just need to render SearchbarLive somewhere in your app.html.heex. In my case, I’m using live_render in my navbar:
<%= live_render(
@conn,
TravelerWeb.SearchbarLive,
id: "searchbar",
container: {:div, class: "flex items-center lg:w-full"}
) %>
You don’t need to add anything to your router. You only need to install and setup LiveView but it’s probably already done by phx generator.
Where to put files? It doesn’t really matter where you put files but there is specific phoenix convention (and Phoenix 1.7 introduced a new concepts).
My search bar “live” files are in lib/traveler_web/live/ and my module responsible for DB search is in lib/traveler/places/ (not in the traveler_web folder).
lib/traveler/places.ex
lib/traveler_web/live/searchbar_live.ex
In your case it should be:
lib/mono_phoenix_v01/monologues.ex
lib/mono_phoenix_v01_web/live/searchbar_live.ex
lib/mono_phoenix_v01_web/live/searchbar_live.html.heex
Hope that helps. You can read more about directory structure here.







