Help us understand the problem. What is going on with this article?

LiveViewでSPAを作る②: API無しQiita検索SPAをフォームsubmitスタイルに換装

fukuoka.ex代表のpiacereです
ご覧いただいて、ありがとうございます :bow:

前回に引き続き、Phoenix LiveViewのAPI無しSPAをいじっていきます

今回は、前回作った「Qiita検索(リアルタイム検索付き)」を、業務系のWebアプリではよくある、フォームsubmitスタイルに換装してみます

なお、「Phoenix」は、ElixirのWebフレームワークです

内容が、面白かったり、役に立ったら、「いいね」よろしくお願いします :wink:

submit用ハンドラに書き換える

前回のハンドラは、以下の通り、「phx-change」を使った、リアルタイム入力の都度、Qiita APIを呼び出すようなハンドラでした

lib/lv_sample_web/live/qiita_search_realtime.ex
defmodule LvSampleWeb.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", ~」は、今回の換装で、利用されなくなります

lib/lv_sample_web/live/qiita_search_realtime.ex
defmodule LvSampleWeb.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( _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 = Json.get( "https://qiita.com", "/api/v2/items?query=#{ query }" )
        { :noreply, assign( socket, query: query, message: "[Complete!!]", loading: false, results: results ) }
    end
end

ブラウザで「http://localhost:4000/realtime」にアクセスすると、submitボタンが付いたQiita検索SPA画面が表示されます
image.png

submitボタンクリックで、Qiita検索が実行されるようになります
image.png

リアルタイム入力とsubmitを混在させる

「phx-change」と「phx-submit」を混在させることもできます

テキスト入力の内容は、「phx-change」で画面上の検索文字列をリアルタイム更新し、submitボタンは「phx-submit」でsubmitできるようにしてみます

具体的には、formに「phx-change="change"」を追加し、「handle_event( "change", ~」から「send( self(), { :submit, query } )」を削除(コメントアウト)します

lib/lv_sample_web/live/qiita_search_realtime.ex
defmodule LvSampleWeb.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 } )
        { :noreply, assign( socket, query: query, message: "" ) }
    end
    

これで、検索文字列はリアルタイム反映される一方、Qiita検索は、submitボタンクリック時のみ実行されます

終わり

今回は、LiveViewでのフォームsubmitについて解説しました

業務系のWebアプリでは、submitボタンによる確定や更新がポピュラーなため、今回の書き方をご参考ください

また、submitとリアルタイム入力の混在についても解説しましたが、これらを混在させるモダン業務系Webアプリでは、応用が効くテクニックかと思います

次回は、「LiveView用のHTMLをテンプレートファイルに分離」します

p.s.「いいね」よろしくお願いします

ページ左上の image.pngimage.png のクリックを、どうぞよろしくお願いします:bow:
ここの数字が増えると、書き手としては「ウケている」という感覚が得られ、連載を更に進化させていくモチベーションになりますので、もっとElixirネタを見たいというあなた、私達と一緒に盛り上げてください!:tada:

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away