1

In my view I'm trying to call a JavaScript function which I've placed in application.js:

/* Set the width of the side navigation to 250px */
function openNav() {
  document.getElementById("mySidenav").style.width = "250px";
}

/* Set the width of the side navigation to 0 */
function closeNav() {
  document.getElementById("mySidenav").style.width = "0";
}

This is my HTML:

<div id="mySidenav" class="sidenav">
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
  <a href="#">About</a>
  <a href="#">Services</a>
  <a href="#">Clients</a>
  <a href="#">Contact</a>
</div>

<span style="font-size:30px;cursor:pointer" onclick="openNav()">&#9776; open</span>

If I put this in my view within <script></script> tags, then it works. My application.js works and it's being compiled but for some reason it only works if the JavaScript is in the actual view of the html.erb file. But if it's in application.js in my pack folder, although it builds the JavaScript file, it returns this error in the console:

(index):23 Uncaught ReferenceError: openNav is not defined
    at HTMLSpanElement.onclick ((index):23)

How can I get this to work in my pack/application.js file rather than having it in the theme in a <script> tag?

1
  • Please don't edit your question to tell us you found a solution. Questions are specifically for the question, just as answers are only for answers. SO isn't a message list or a forum, it's like an online text book, where you just created a new article. It's more formal than either of the other two types of sites. The tour and "How to Ask" and its linked pages discuss this. Commented May 6, 2020 at 3:54

2 Answers 2

4

"Rails 5/6: How to include JS functions with webpacker?" worked:

window.closeNav = function() {
  document.getElementById("mySidenav").style.width = "0";
}

window.openNav = function() {
  document.getElementById("mySidenav").style.width = "250px";
}

Can anyone explain why in Rails 6?

Sign up to request clarification or add additional context in comments.

Comments

1

It is unclear why the function openNav() does not work in Rails 6. I would suspect that it has to do with the changes from Sprockets to Webpacker. I did find a solution that may be more conventional than adding the methods to the "window" object. Adding methods or properties directly to the "window" object could inadvertently overwrite defaults. I took guidance from the RailsGuides.

https://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html

I added an "id" to the Open and Close elements and removed their "onclick" properties. Adding the ids allowed me to target them in the side_nav.js file to add a "click" event listeners.

Index.html.erb

<div id="mySidenav" class="sidenav">
  <a href="#" class="closebtn" id="close-nav >&times;</a>
  <a href="#">About</a>
  <a href="#">Services</a>
  <a href="#">Clients</a>
  <a href="#">Contact</a>
</div>

<span id="open-nav>Open</span>

<%= javascript_pack_tag 'side_nav' %>

I am using Turbolinks, and so I wait to add the event listeners until after the Turbolinks loads to make sure that the DOM is finished rendering. This will make sure the "id" are available to be targeted. If you are not using Turbolinks you may be able to change it out for "DOMContentLoaded".

javascript\packs\side_nav.js

window.addEventListener("turbolinks:load", () => {
  // Open
  document.getElementById('open-nav').addEventListener("click", e => {
    e.preventDefault();
    document.getElementById("mySidenav").style.width = "250px";
  });

  // Close
  document.getElementById('close-nav').addEventListener("click", e => {
    e.preventDefault();
    document.getElementById("mySidenav").style.width = "0";
  });
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.