我有一个LiveView应用程序,可以搜索机场代码。用户输入ham
时,应使用HAM
(String.upcase / 1)替换该表单字段的内容,但不这样做。但是根据我对代码的理解,应该这样做。我必须更改什么才能用大写版本替换该字段中的所有输入?
BTW:如果我向其中添加一个按钮并使用phx-submit
而不是phx-change
,则可以使用。但我想让它适用于phx-change
。
$ mix phx.new travelagent --live --no-ecto
$ cd travelagent
lib / travelagent_web / router.ex
[...]
scope "/", TravelagentWeb do
pipe_through :browser
live "/", PageLive, :index
live "/search", SearchLive
end
[...]
lib / travelagent / airports.ex
defmodule Travelagent.Airports do
def search_by_code(""), do: []
def search_by_code(code) do
list_airports()
|> Enum.filter(&String.starts_with?(&1.code, code))
end
def list_airports do
[
%{name: "Berlin Brandenburg", code: "BER"},
%{name: "Berlin Schönefeld", code: "SXF"},
%{name: "Berlin Tegel", code: "TXL"},
%{name: "Bremen", code: "BRE"},
%{name: "Köln/Bonn", code: "CGN"},
%{name: "Dortmund", code: "DTM"},
%{name: "Dresden", code: "DRS"},
%{name: "Düsseldorf", code: "DUS"},
%{name: "Frankfurt", code: "FRA"},
%{name: "Frankfurt-Hahn", code: "HHN"},
%{name: "Hamburg", code: "HAM"},
%{name: "Hannover", code: "HAJ"},
%{name: "Leipzig Halle", code: "LEJ"},
%{name: "München", code: "MUC"},
%{name: "Münster Osnabrück", code: "FMO"},
%{name: "Nürnberg", code: "NUE"},
%{name: "Paderborn Lippstadt", code: "PAD"},
%{name: "Stuttgart", code: "STR"}
]
end
end
lib / travelagent_web / live / search_live.ex
defmodule TravelagentWeb.SearchLive do
use TravelagentWeb, :live_view
alias Travelagent.Airports
def mount(_params, _session, socket) do
socket =
socket
|> assign(:airport_code, "")
|> assign(:airports, [])
{:ok, socket}
end
def handle_event(
"airport_code_search",
%{"airport_code" => airport_code},
socket
) do
airport_code = String.upcase(airport_code)
socket =
socket
|> assign(:airport_code, airport_code)
|> assign(:airports, Airports.search_by_code(airport_code))
{:noreply, socket}
end
end
lib / travelagent_web / live / search_live.html.leex
<form phx-change="airport_code_search">
<fieldset>
<label for="nameField">Airport Code</label>
<input type="text" name="airport_code" value="<%= @airport_code %>"
placeholder="e.g. FRA"
autofocus autocomplete="off" />
</fieldset>
</form>
<%= unless @airports == [] do %>
<h2>Search Results</h2>
<table>
<thead>
<tr>
<th>Airport Code</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<%= for airport <- @airports do %>
<tr>
<td><%= airport.code %></td>
<td><%= airport.name %></td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
如果我使用此表单:
<form phx-submit="airport_code_search">
<fieldset>
<label for="nameField">Airport Code</label>
<input type="text" name="airport_code" value="<%= @airport_code %>"
placeholder="e.g. FRA"
autofocus autocomplete="off" />
<input class="button-primary" type="submit" value="Search Airport">
</fieldset>
</form>
我得到此工作结果(输入fra
并单击按钮后:]
PS:使用JavaScript或CSS,有上百万种解决方案。但我想知道如何使用LiveView正确解决此问题。
JavaScript客户端始终是当前输入值的真实来源。对于任何具有焦点的给定输入,LiveView永远不会覆盖输入的当前值,即使它偏离服务器的渲染更新也是如此。
这种情况下的解决方案是使用JS hooks。