The requestSubmit
method did not work in my case, I think because the search form was already nested in higher level form (autocomplete field in a form).
What I like to do now for simple actions that trigger a Turbo Stream is to use request.js to send the HTTP request.
It has a responseKind option that you can set to turbo-stream
. It will set the Accept Header to text/vnd.turbo-stream.html
so the backend will respond with a Turbo Stream.
I think this trick deserves to be better known from Hotwire devs!
// autocomplete_controller.js
import { get } from "@rails/request.js"
export default class extends Controller {
search({ target: { value } }) {
get(`/search?query=${value}`, {
responseKind: "turbo-stream"
})
}
}
<div data-controller="autocomplete">
<input
type="search"
autocomplete="off"
data-action="keyup->autocomplete#search"
>
<turbo-frame id="autocomplete_results"></turbo-frame>
</div>
# search_controller.rb
class SearchController < ApplicationController
def index
@results = ...
respond_to do |format|
format.turbo_stream
end
end
end
# app/views/search/index.turbo_stream.erb
<%= turbo_stream.update("autocomplete_results") do %>
<ul>
<% @results.each do |result| %>
<li><%= result %></li>
<% end %>
<ul>
<% end %>