Triggering Turbo Frame with JS

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 %>
3 Likes