I am trying to build an airport autocomplete search (following https://online.pragmaticstudio.com/courses/liveview/steps/13) with 2 fields: fly_from and fly_to. The problem is when I am done with fly_from field and try typing in fly_to field, the input value of fly_from gets cleared
defmodule WeekendWeb.AutocompleteLive do
use WeekendWeb, :live_view
alias Weekend.Airports
def mount(_, _, socket) do
socket = assign(socket, fly_from: "",
fly_to: "",
fly_from_matches: [],
fly_to_matches: []
)
{:ok, socket}
end
def render(assigns) do
~L"""
<div>
Fly_from: <%= @fly_from %>
</div>
<div>
fly_to: <%= @fly_to %>
</div>
<form phx-change="suggest_airport">
<input type="text" name="fly_from" value="<%= @fly_from %>" placeholder="Fly from" autofocus autocomplete="off" list="fly_from_matches" phx-debounce="1000">
<input type="text" name="fly_to" value="<%= @fly_to %>" placeholder="Fly to" autocomplete="off" list="fly_to_matches" phx-debounce="1000">
<button type="submit">Submit</button>
</form>
<datalist id="fly_from_matches">
<%= for match1 <- @fly_from_matches do %>
<option value="<%= match1 %>"> <%= match1 %> </option>
<% end %>
</datalist>
<datalist id="fly_to_matches">
<%= for match2 <- @fly_to_matches do %>
<option value="<%= match2 %>"> <%= match2 %> </option>
<% end %>
</datalist>
"""
end
def handle_event("suggest_airport", %{"_target" => ["fly_from"], "fly_from" => fly_from_query, "fly_to" => _fly_to_query}, socket) do
{:noreply, assign(socket, fly_from_matches: Airports.suggest(fly_from_query))}
end
def handle_event("suggest_airport", %{"_target" => ["fly_to"], "fly_from" => _fly_from_query, "fly_to" => fly_to_query}, socket) do
{:noreply, assign(socket, fly_to_matches: Airports.suggest(fly_to_query))}
end
end
defmodule Weekend.Airports do
def suggest(""), do: []
def suggest(prefix) do
Enum.filter(list_airports(), &has_prefix?(&1, prefix))
end
def list_airports do
["Senai", "Sengkang", "Sentury", "Changi", "Changkat", "Changfar"]
end
def has_prefix?(airport, prefix) do
String.starts_with?(String.downcase(airport), String.downcase(prefix))
end
end
I believe the problem is that server is unaware of the input value of fly_from when it receives the handle_event call back for “fly_to” but how can I get the input value and store it as a state in this case?
Thanks!