How do I make a JavaScript function available globally in Rails 6 with Webpack?
Asked Answered
W

1

1

As a beginner on Rails 6. Whenever, i click on the Roar Link then it gives me the following error. The following files are attached below. I just want to add custom file(demo.js) into my code so that i can test the behavior of JavaScript in my following code. Java Script behavior on Rails 5 is different from the Rails 6.

Kindly give me the better solution so that i can solve my problem. I tried all of answers on stack overflow.

Application.html.erb (views/layouts/application.html.erb)

<!DOCTYPE html>
<html>
  <head>
    <title>SimpleCms</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    
  </head>

  <body>
    <%= yield %>
  </body>
</html>

demo.js (app/javascript/packs/demo.js)

function jsRoar(name) {
    alert('I am ' + name + '. Hear me roar!');
  }

application.js (app/javascript/packs/application.js)

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("packs/demo")

index.html.erb (views/demo/index.html.erb)

<h1>This is the index Page</h1>
<br/>
<%= link_to('All Subjects',subjects_path) %>

<%= link_to('Roar', '#', :onclick => "jsRoar('JavaScript'); return true;") %>

demo_controller.rb

class DemoController < ApplicationController
  
  layout 'application'
  
  def index
  render ('index')
  end

  def hello
  render ('hello')
  end

end

GEM File

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.6'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3', '>= 6.0.3.2'
# Use mysql as the database for Active Record
gem 'mysql2', '>= 0.4.4'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: 
https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
Watermelon answered 9/8, 2020 at 16:27 Comment(1)
Thank you @Michael for editing.Watermelon
A
3

You're thinking of the old way of doing it. I've explained it here:

https://mcmap.net/q/673571/-rails-5-6-how-to-include-js-functions-with-webpacker

Here's a more modern way of doing what you're trying.

<%= link_to('Roar', '#', data: {roar: 'JavaScript'}) %>

In demo.js:

document.addEventListener("turbolinks:load", function() {
  document.querySelectorAll('[data-roar]').forEach(function(roaring_link) {
    roaring_link.addEventListener('click', function(event) {
      let name = roaring_link.dataset['roar']
       alert('I am ' + name + '. Hear me roar!');
       event.preventDefault();
       event.stopPropagation();
       return false;
    });
  });
});

Note that the code in demo.js is self-contained and simply looks at the document and attaches the desired functionality to the links. You specify what links those are by adding a data attribute with the data that you wish to pass to your javascript function.

This might seem complicated but after you get the hang of it you'll find your javascript is really clean and easy to maintain.

Antho answered 20/8, 2020 at 22:57 Comment(3)
Thank you for your reply. It solves my problem. Kindly read the note at the end of question.Watermelon
@HassamSaeed It's against SO policy to ask for upvotes: meta.#324347 Just keep your question as a question without extraneous stuff.Antho
can you please answer this question? #63719029Watermelon

© 2022 - 2024 — McMap. All rights reserved.