🙆
<turbo-frame>のみでインクリメンタル検索
やりたいこと
Turbo StreamsやJavaScriptの処理を書かずに、Turbo Framesのみでサーバーサイドで絞り込んだ検索結果をレンダリングしたい。
文字が入力される度に
サーバーで検索して画面に反映する
解決策
turbo.jsで定義されているrequestSubmit()をoninputイベントから呼び出してフォームをsubmitする。
- フォームから
GET /notes?q=foo
リクエストが発生 - レスポンスを
<turbo-frame>
でレンダリング
index.html.erb
<!--検索入力-->
<%= form_tag notes_path, method: :get, data: {turbo_frame: :notes} do %>
<%= text_field_tag :q, params[:q], oninput: "requestSubmit()" %>
<% end %>
<!--検索結果表示欄-->
<%= turbo_frame_tag :notes, src: notes_path, loading: "lazy" %>
notes_controller.rb
class NotesController < ApplicationController
def index
@notes = params[:q] ? Note.where('title LIKE ?', "%#{params[:q]}%") : Note.all
end
end
notes/index.html.erb
<!--検索結果-->
<%= turbo_frame_tag :notes do %>
<% @notes.each do |note| %>
<%= note.title %>
<% end %>
<% end %>
補足
- 結局JavaScriptで実行している
- クライアントサイドに文字数制御などをロジックを追加するならStimulusで切り離した方が良さそう
Discussion