I am learning Rails 7 with the new default Importmap jsmp syntax. I have tried to follow what few tutorials are out there, but am still unable to get either jQuery or Stimulus to respond to a simple alert
function on page load.
I started over with a bare-bones Rails 7 application, ran bundle install
, followed by rails turbo:install
, rails stimulus:install
and created a Static controller to route to a Landing page at Static#Landing
.
My `landing.html.erb' file contains:
<h2>Landing</h2>
<p>
<script>
document.write("Vanilla JS is working...");
</script>
</p>
I get the expected string output, so I know Javascript is enabled in the Browser.
My importmap.rb
file contains:
# Pin npm packages by running ./bin/importmap
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 "jquery", to: "library/jquery.js" #"https://ga.jspm.io/npm:jquery@3.6.0/dist/jquery.js"
pin "jquery-ui-dist", to: "library/jquery.js" #"https://ga.jspm.io/npm:jquery-ui-dist@1.13.1/jquery-ui.js"
pin "jqtree", to: "https://ga.jspm.io/npm:jqtree@1.6.2/lib/tree.jquery.js"
pin_all_from "app/javascript/controllers", under: "controllers"
The only lines I added were the 3 invoking a form of jQuery.
I next added the 3 import
statements for jQuery, jQuery-ui-dist, and jqtree to the application.js
file. The complete file contains:
// Javascript document
// Document Name: application.js
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "jQuery"
import "jquery-ui-dist"
import "jqtree"
import "controllers"
// Configure Stimulus development experience
application.debug = false
window.Stimulus = application
// NOTE: make jquery global
window.$ = window.jQuery = jQuery;
$(function(){
window.alert("It looks like jQuery is too.");
});
export { application }
I next edited my app/assets/config/manifest.js
file to include the following:
//= link_tree ../images
//= link_tree ../icons
//= link_directory ../stylesheets .css
//= link_tree ../../javascript .js
//= link_tree ../../javascript/library .js
//= link_tree ../../../vendor/javascript .js
However, even though inline <script>
s work as outlined above, I get no response from either jQuery or Stimulus to the alert
function in application.js
. When I check my source code, I see the following:
<!DOCTYPE html>
<html>
<head>
<title>Testingjquery</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="LkQZA1mB-KU38K8S1lg_BMJWPx4HLonSyQ0s8W2vCotmw3aHIXZNDnPcJCtbgeXSTWrEuWJBZWlkOZcLe7Ru9w" />
<link rel="stylesheet" href="/assets/application-e0cf9d8fcb18bf7f909d8d91a5e78499f82ac29523d475bf3a9ab265d5e2b451.css" data-turbo-track="reload" />
<script type="importmap" data-turbo-track="reload">{
"imports": {
"application": "/assets/application-79a33b4392f09ada2a09f9c0b7de4d6479378090d98fa671caaef897dcec0de9.js",
"@hotwired/turbo-rails": "/assets/turbo.min-e5023178542f05fc063cd1dc5865457259cc01f3fba76a28454060d33de6f429.js",
"@hotwired/stimulus": "/assets/stimulus.min-b8a9738499c7a8362910cd545375417370d72a9776fb4e766df7671484e2beb7.js",
"@hotwired/stimulus-loading": "/assets/stimulus-loading-1fc59770fb1654500044afd3f5f6d7d00800e5be36746d55b94a2963a7a228aa.js",
"jquery": "/assets/library/jquery-58fa327d47526faff06ea7057a0022e9c42b2ca3a9aeea413f0e18176a63cd9f.js",
"jquery-ui-dist": "/assets/library/jquery-58fa327d47526faff06ea7057a0022e9c42b2ca3a9aeea413f0e18176a63cd9f.js",
"jqtree": "https://ga.jspm.io/npm:jqtree@1.6.2/lib/tree.jquery.js",
"controllers/application": "/assets/controllers/application-368d98631bccbf2349e0d4f8269afb3fe9625118341966de054759d96ea86c7e.js",
"controllers/hello_controller": "/assets/controllers/hello_controller-549135e8e7c683a538c3d6d517339ba470fcfb79d62f738a0a089ba41851a554.js",
"controllers": "/assets/controllers/index-2db729dddcc5b979110e98de4b6720f83f91a123172e87281d5a58410fc43806.js"
}
}</script>
<link rel="modulepreload" href="/assets/application-79a33b4392f09ada2a09f9c0b7de4d6479378090d98fa671caaef897dcec0de9.js">
<link rel="modulepreload" href="/assets/turbo.min-e5023178542f05fc063cd1dc5865457259cc01f3fba76a28454060d33de6f429.js">
<link rel="modulepreload" href="/assets/stimulus.min-b8a9738499c7a8362910cd545375417370d72a9776fb4e766df7671484e2beb7.js">
<link rel="modulepreload" href="/assets/stimulus-loading-1fc59770fb1654500044afd3f5f6d7d00800e5be36746d55b94a2963a7a228aa.js">
<script src="/assets/es-module-shims.min-d89e73202ec09dede55fb74115af9c5f9f2bb965433de1c2446e1faa6dac2470.js" async="async" data-turbo-track="reload"></script>
<script type="module">import "application"</script>
</head>
<body>
<h2>Landing</h2>
<p>
<script>
document.write("Vanilla JS is working...");
</script>
</p>
</body>
</html>
As you can see, jQuery is not being loaded at all and Stimulus is being loaded, but is unresponsive to any code references. I am new to Stimulus, intermediate with Javascript/jQuery and new to Rails 7. From what I have read, I like the conceptualization behind these radical shifts in Rails methodology, but so far, haven't been able to get it to work.
The files are all in their appropriate places according to the references to them. For illustration, this is my file tree:
-app
-assets
-config
-manifest.js
-javascript
-controllers
-application.js
...
-library
-jquery.js
-jquery-ui.js
-application.js
...
-config
-importmap.js
...
The final application.js
file contains no code that I changed and is as follows:
import { Application } from "@hotwired/stimulus"
const application = Application.start()
// Configure Stimulus development experience
application.debug = false
window.Stimulus = application
// NOTE: make jquery global
window.$ = window.jQuery = jQuery;
export { application }
Granted, there are two application.js
files that Importmaps/Stimulus/Turbo seem to rely upon, and perhaps I inserted some code into the wrong application.js
file. If so, it was because the tutorials that I was following didn't specify or clarify which file to insert certain code into.
Does anyone see a fundamental error in my code or can suggest another approach? Thanks in advance.