Enhancing User Experience with Live Search Feature using Phoenix Live View

Michael Munavu
5 min readJul 3, 2023

--

In today’s fast-paced digital world, providing users with a seamless and efficient search experience is crucial for the success of any web application. One way to achieve this is by implementing a live search feature using Phoenix Live View. Phoenix Live View, a real-time server-rendering library for Elixir, empowers developers to build dynamic, interactive web applications without relying on client-side JavaScript frameworks. In this article, we will explore how to leverage the power of Phoenix Live View to create a live search feature that instantly updates search results as users type, enhancing user experience and increasing engagement.

To get started , we will generate a new application using mysql as our database.

mix phx.new phoenix_liveview_search - database=mysql

Configure your database credentials in

config/dev.exs

and then run

mix ecto.create

to create your database .

Once your database is up and running we can now get our hands dirty ,

We will be creating Products each with a name , price and quantity .

Run the command

mix phx.gen.live Products Product products name:string price:integer quantity:integer

Add the live routes to your browser scope in lib/phoenix_liveview_search_web/router.ex

lib/phoenix_liveview_search_web/router.ex:
live "/products", ProductLive.Index, :index
live "/products/new", ProductLive.Index, :new
live "/products/:id/edit", ProductLive.Index, :edit
live "/products/:id", ProductLive.Show, :show
live "/products/:id/show/edit", ProductLive.Show, :edit

Remember to update your repository by running migrations:

mix ecto.migrate

In our routes to make sure we see the index page of the products once we open our app , we change

 get "/", PageController, :index

and replace it with

live "/", ProductLive.Index, :index

Let us run up our server

Let us add a few records .

Okay , now that we have a few records , we need to impliment a search feature , let us think about how we would do this .

We would need a form that will have an input , and we need to capture the value of this input and run a function every time it changes , we will use this value as parameters in a function that will return products with a similar name as the value passed .

We already know where to get started , we need to add the form , but remember forms in phoenix have a for={@changeset} so we first need to define our changeset in our live/product_live/index.ex

In our mount function ,we will modify it to this

def mount(_params, _session, socket) do
{:ok,
socket
|> assign(:products, list_products())
|> assign(:changeset, Products.change_product(%Product{}))}
end

Now in our index.html.heex , we will come and define our form, our form will have a phx-change event of search that we will define in our index.ex later, but first, let us define our form as follows

<.form  let={f} id="search" phx-change="search"  for={@changeset}  >

<%= text_input f, :search , placeholder: "Search" %>


</.form>

To test this search event, we can write a simple function to do this in our index.ex file

 def handle_event("search", %{"product" => product_params}, socket) do
IO.inspect(product_params["search"])

{:noreply,
socket
|> put_flash(:info, "Searching")}
end

This function should let us see the value we input into our input and should also put a flash, let us test it out.

When we search, we now see

And we also see this in our terminal.

Now we need to declare a function in our schema that will take this input and return to us products with names similar to it , for this we will use the ilike .

let us go into lib/phoenix_liveview_search/products.ex and add this

def get_search_results(search) do
query = from p in Product, where: fragment("? LIKE ?", p.name, ^"%#{search}%")
Repo.all(query)
end

This function will return us Products that have names that start with what we have searched for,

Now we need to assign products to the result of this function in our handle_event function for search in index.ex.

Our function will now look like this

def handle_event("search", %{"product" => product_params}, socket) do
{:noreply,
socket
|> assign(:products, Products.get_search_results(product_params["search"]))}
end

Now when we test out our feature it works , Congratulations .

In conclusion, the live search feature implemented using Phoenix Live View opens up a new realm of possibilities for web developers. By utilizing the power of Elixir and Phoenix Live View’s real-time rendering capabilities, we can create a highly responsive and interactive search experience for users. The live search feature provides instant feedback as users type, eliminating the need for page reloads and providing real-time updates to search results. This not only enhances the overall user experience but also improves engagement and satisfaction.

If you’re interested in exploring how to implement a live search feature using Phoenix Live View, you can find a detailed example in this GitHub repository: [https://github.com/MICHAELMUNAVU83/phoenix_liveview_search]. The repository contains the necessary code and instructions to get started with building your own live search feature. Feel free to fork the repository, experiment with the code, and adapt it to fit your specific application requirements.

With Phoenix Live View’s simplicity and efficiency, implementing a live search feature becomes a breeze, making it a valuable addition to any web application seeking to optimize user search experiences. So, why not harness the power of Phoenix Live View and take your search functionality to the next level?

GitHub repository link: [https://github.com/MICHAELMUNAVU83/phoenix_liveview_search]

--

--