Stimulus not Adding Listeners to Search Form Input

481 views Asked by At

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.

1

There are 1 answers

0
Mitch On BEST ANSWER

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 class="container">
      <%= 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