0

I'm new to javascript and I'm having issues getting a custom function to work in a Rails 5 app. I'm trying to add a simple function that sets an active link in a bootstrap navbar heading. I got everything to work in a codepen but when I add it to my Rails app it's not working. I know javascript is running because I'm using bootstrap and those functions work properly. I also think the script is loading by checking the sources in Chrome Developer tools and it is there. However, setting a breakpoint never gets triggered.

I've read through about 30 similar questions and none of them helped fix my issue, so I'm really hoping someone can get me past this roadblock.

Here is the code I wrote:

HTML

<nav class="navbar navbar-light bg-light navbar-expand-md fixed-top header-bg">
  <%= link_to image_tag(asset_path('jungers_farm/jungers_logo.png'),
                  width: '50', height: '50'),
                 root_path, class:'navbar-brand col-4 menu-brand' %>
  <button class="navbar-toggler" type="button" data-toggle="collapse"
          data-target="#navbar-list-2" aria-controls="navbarNav" aria-expanded="false"
          aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbar-list-2">
    <ul class="navbar-nav justify-content-center" id="main-nav-list">
      <li class="nav-item">
        <%= link_to 'Home', root_path, class: 'nav-link active' %>
      </li>
      <li class="nav-item">
        <%= link_to 'Training', page_path('training'), class: 'nav-link' %>
      </li>
      <li class="nav-item">
        <%= link_to 'Breeding', page_path('breeding'), class: 'nav-link' %>
      </li>
    </ul>
  </div>
</nav>

Javascript

$('.navbar-nav .nav-link').click(function(){
  $('.navbar-nav .nav-link').removeClass('active');
  $(this).addClass('active');
})

Application.js file (my code is in custom.js in app/assets/javascripts)

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, or any plugin's
// vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery3
//= require popper
//= require rails-ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require custom
//= require_tree .

Here is the codepen showing that it works in that environment and what I'm trying to accomplish.

Codepen

UPDATE So, my initial problem was the code was not loading after the DOM because of turbolinks. I added the following code and now it is running.

$( document ).on('turbolinks:load', function() {
    ... original code ...
})

However, the code is not running as it does in my codepen. The active link is not changing as expected. The link that was originally marked as active stays active regardless of the link clicked. Is there some other load issue for the page I'm missing?

3
  • are you sure your javascript is loading AFTER your dom is finished loading? Commented May 25, 2020 at 19:53
  • Put a console.log just before and also inside the click handler and see which one is getting printed. If only the first one, your javascript is running before dom is built. Commented May 25, 2020 at 19:56
  • Ok, I figured out Turbolinks was preventing the code from running. However, it is not working as it does in the codepen. It almost appears as if it is being changed back to original (page reloaded) after the script runs, is that possible? Or is the CSS not being applied to the edited change? I guess I'm not sure on the ordering of events in Rails. Commented May 25, 2020 at 21:45

1 Answer 1

2

So, I discovered that when using Turbolinks in Rails 5 you have to use a Turbolinks event to ensure you trigger your javascript code. I regular JQuery $(window) doesn't always do the trick. For example you can do the following to trigger your code once after the initial page load, and again after every Turbolinks visit.

$( document ).on('turbolinks:load', function() {
  $('.navbar-nav .nav-link').click(function(){
    $('.navbar-nav .nav-link').removeClass('active');
    $(this).addClass('active');
  }) 
})

Turbolinks 5

You can read more on the Turbolinks events here: Turbolinks Events. And more on Turbolinks 5 here: Turbolinks 5.

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

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.