【本コラムは、3分で読めて、10分くらいでお試しいただけます】
piacereです、ご覧いただいてありがとございます
前回に引き続き、Phoenix LiveViewのAPI無しSPAをいじっていきます
今回は、前回作った「Qiita検索(リアルタイム検索付き)」を、業務系のWebアプリではよくある、フォームsubmitスタイルに換装してみます
なお、「Phoenix」は、ElixirのWebフレームワークです
■「ExcelからElixir入門」シリーズの目次
①データ並替え/絞り込み
|> ②データ列抽出、Web表示
|> ③WebにDBデータ表示
|> ④Webに外部APIデータ表示
|> ⑤Webにグラフ表示
|> ⑥SPAからPhoenix製APIを呼び出す(表示編)【LiveView版】
|> ⑦SPAからPhoenix製APIを呼び出す(更新編)【LiveView版】
|> ⑧Gigalixirに本番リリース
|> ⑨Elixir/PhoenixのCRUD Webアプリをリリース
|> ⑩「LiveView」ElixirサーバサイドのみでReact的SPA/リアルタイムUIが作れる
|> ⑪LiveView製Qiita検索SPAをフォームsubmitスタイルに換装
|> ⑫LiveViewのコード内HTMLをテンプレートファイルに分離
|> ⑬ElixirサーバサイドSPAをスマホで見るためにGigalixirリリース
|> ⑭Gigalixir上のLiveViewアプリに独自ドメイン名を付与して正式なアプリ公開
submit用ハンドラに書き換える
前回のハンドラは、以下の通り、「phx-change」を使った、リアルタイム入力の都度、Qiita APIを呼び出すようなハンドラでした
defmodule BasicWeb.QiitaSearchRealtime do
use Phoenix.LiveView
def render(assigns) do
~L"""
…
<form phx-change="change">
<input type="text" name="query" value="<%= @query %>" placeholder="empty" />
…
これを、submitボタンクリック時にQiita APIを呼び出すようなハンドラへと変更します
phx-submit
を使うと、submit時のみ処理を行うようにできるので、submitボタンを追加してみます
ついでに、Qiita API検索中は、フォーム操作をできなくするため、loading
というUI制御フラグも導入します
なお、handle_event("change", ~
は、今回の換装で、利用されなくなります
defmodule BasicWeb.QiitaSearchRealtime do
use Phoenix.LiveView
def render(assigns) do
~L"""
<p>
<%= if @message do %><%= @message %><% end %>
</p>
<!-- modify here---v -->
<form phx-submit="submit">
<input type="text" name="query" value="<%= @query %>" placeholder="empty" <%= if @loading, do: "readonly" %> />
Query: <%= @query %><br>
<input type="submit" value="search" onclick="blur()" <%= if @loading, do: "readonly" %> />
</form>
<table>
<tr>
<th>ID</th>
<th>タイトル</th>
<th>作成日</th>
</tr>
<%= for result <- @results do %>
<tr>
<td><%= result["id"] %></td>
<td><%= result["title"] %></td>
<td><%= result["created_at"] %></td>
</tr>
<% end %>
</table>
"""
end
def mount(_params, _session, socket) do
{:ok, assign(socket, query: "", message: "[Init]", loading: false, results: [])}
end
def handle_event("change", %{"query" => query}, socket) do
send(self(), {:submit, query})
{:noreply, assign(socket, query: query, message: "")}
end
def handle_event("submit", %{"query" => query}, socket) do
send(self(), {:submit, query})
{:noreply, assign(socket, query: query, message: "[Searching...]", loading: true)}
end
def handle_info({:submit, query}, socket) do
results = Req.get!("https://qiita.com/api/v2/items?query=#{query}").body
{:noreply, assign(socket, query: query, message: "[Complete!!]", loading: false, results: results)}
end
end
ブラウザで「http://localhost:4000/realtime
」にアクセスすると、submitボタンが付いたQiita検索SPA画面が表示されます
submitボタンクリックで、Qiita検索が実行されるようになります
リアルタイム入力とsubmitを混在させる
「phx-change」と「phx-submit」を混在させることもできます
テキスト入力の内容は、「phx-change」で画面上の検索文字列をリアルタイム更新し、submitボタンは「phx-submit」でsubmitできるようにしてみます
具体的には、formに「phx-change="change"」を追加し、「handle_event("change", ~」から「send(self(), {:submit, query})」を削除(コメントアウト)します
defmodule BasicWeb.QiitaSearchRealtime do
use Phoenix.LiveView
def render(assigns) do
~L"""
…
<!-- modify here-----------v -->
<form phx-submit="submit" phx-change="change">
…
"""
end
…
def handle_event("change", %{"query" => query}, socket) do
#send(self(), {:submit, query}) # <-- comment-out here
{:noreply, assign(socket, query: query, message: "")}
end
…
これで、検索文字列はリアルタイム反映される一方、Qiita検索は、submitボタンクリック時のみ実行されます
【参考】本コラムの検証環境
本コラムは、以下環境で検証しています(恐らくUbuntu実機やMacでも動きます)
-
Windows 10
- 実機+Elixir 1.14.2 (Erlang/OTP 25)
- Phoenix 1.6.15
- WSL2/Ubuntu 20.04+Elixir 1.14.2 (Erlang/OTP 25) ※最新版のインストール手順はコチラ
- Phoenix 1.6.15
- Docker/Debian 11.6+Elixir 1.14.2 (Erlang/OTP 25)
- Phoenix 1.6.15
- 実機+Elixir 1.14.2 (Erlang/OTP 25)
-
Windows11
- WSL2/Ubuntu 22.04+Docker Compose+Elixir 1.13.4 (Erlang/OTP 25)
- Phoenix 1.6.15
- WSL2/Ubuntu 22.04+Docker Compose+Elixir 1.13.4 (Erlang/OTP 25)
終わり
今回は、LiveViewでのフォームsubmitについて解説しました
業務系のWebアプリでは、submitボタンによる確定や更新がポピュラーなため、今回の書き方をご参考ください
また、submitとリアルタイム入力の混在についても解説しましたが、これらを混在させるモダン業務系Webアプリでは、応用が効くテクニックかと思います