caspg

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 :sweat_smile:! The real-time updates are seamless and make the search experience much more intuitive.

:point_right: Here’s a link to the code on GitHub:

Let me know if you have any questions or feedback!

Most Liked

milangupta

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

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

caspg

@ghenry I’m using 1.7 :slight_smile: 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

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

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.

Where Next?

Popular in Guides/Tuts Top

tfwright
I thought I’d share a small project I’m working on to gain some familiarty with LiveView in a Phoenix app. Github Repo Deployment It’s...
New
eclark
I’ve been working on a phoenix project lately and I wanted to use the latest versions of everything. Webpack 5 had some breaking changes ...
New
crockwave
To integrate dropdown menus in a Phoenix Liveview app, you can use a combination of js, Hooks, CSS and your .leex and .ex code. You can...
New
WolfDan
So my main OS is Windows, I do must of my work with it, Elixir and vscode elixirls works just fine when you’re working only with elixir, ...
New
malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
pinksynth
Whenever tests have to interact with an Ecto.Repo, sometimes it’s necessary to test a few different branches or paths that data can take....
New
anuragg
Hi everyone, I’m the founder of Render and we just released a guide to deploying Phoenix apps with Mix releases. Most of it is generali...
New
Jskalc
Sorry if it’s a common knowledge, but it’s something I just learned and wanted to share. I’ve seen that mind-blowing demo of hot-reload ...
New
alejandroErik
POST IN CONSTRUCTION Process for compile erlang otp 20 with odbc-unix for Oracle connections on Solaris 11.3 for 64 bits: Introductio...
New
tonydang
I recently got inertia-phoenix (an Inertia.js adapter for Phoenix) working with Svelte. Setting up the server-side rendering (SSR) with S...
New

Other popular topics Top

TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 27727 240
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New

We're in Beta

About us Mission Statement