I'm trying to create a search-as-you-type search box on my Rails 7 app. The type-hit-enter search works, and it's loading in a turbo frame, but the js-driven search-as-you-type functionality is broken. The event listener for the search box isn't firing at all...when I select the box and type, nothing appears on the browser's network tab or in the JS console.
Here's the search form partial:
<div>
<%= search_form_for @q, data: { controller: "form-submission", turbo_frame: "companies", turbo_action: "advance" } do |f| %>
<%= f.search_field :search_multi, placeholder: "Search", class: "form-control search-box", data: { action: "input->form-submission#search" } %>
<% end %>
</div>
app/javascript/controllers/form_submission_controller.js:
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
search() {
clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
this.element.requestSubmit()
}, 200)
}
}
app/javascript/controllers/index.js:
// Import and register all your controllers from the importmap under controllers/*
import { application } from "controllers/application"
// Eager load all controllers defined in the import map under controllers/**/*_controller
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
eagerLoadControllersFrom("controllers", application)
// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
// import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading"
// lazyLoadControllersFrom("controllers", application)
config/importmap.rb
pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin "popper", to: 'popper.js', preload: true
pin "bootstrap", to: 'bootstrap.min.js', preload: true
I've tried Chrome and Safari.
I went so far as to rebuild my Rails app installation with the following, and then copied all of my code back over to it:
rails new app --database=postgresql --asset-pipeline=sprockets --javascript=importmap
On the JS console: getEventListeners($("#q_search_multi"))
shows nothing.
I also tried bin/rails assets:clobber && bin/rails assets:precompile
.
CodePudding user response:
Today I rebuilt the application from scratch and determined the cause: I was missing <%= javascript_importmap_tags %>
in app/app/views/layouts/application.html.erb. sigh Lesson learned. Here's the full application.html.erb:
<!DOCTYPE html>
<html>
<head>
<title>App</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%# turbo_include_tags %>
<%= javascript_importmap_tags %>
</head>
<body>
<main >
<%= yield %>
</main>
</body>
</html>
Shout out to this guide for building a search-as-you-type search box: https://www.colby.so/posts/instant-search-with-rails-6-and-hotwire