How to get Twitter-Bootstrap navigation to show active link?

Ruby on-RailsTwitter Bootstrap

Ruby on-Rails Problem Overview


I'm not understanding how Twitter Bootstrap does active links for the navigation. If I have a regular navigation like this (with ruby on rails linking):

<ul class="nav">
  <li class="active"> <a href="/link">Link</a> </li>
  <li class=""> <a href="/link">Link</a> </li>
  <li class=""> <a href="/link">Link</a> </li>        
</ul>

How do I keep it active based on the link clicked?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

You can use something like (very similar to what @phil mentioned, but a little shorter):

<ul class="nav">
  <li class="<%= 'active' if current_page?(root_path) %>"><%= link_to "Home", root_path %></li>
  <li class="<%= 'active' if current_page?(about_path) %>"><%= link_to "About", about_path %></li>
  <li class="<%= 'active' if current_page?(contact_path) %>"><%= link_to "Contact", contact_path %></li>
</ul>

Solution 2 - Ruby on-Rails

Just made an answer on the very same question here https://stackoverflow.com/questions/9862524/twitter-bootstrap-pills-with-rails-3-2-2

<ul class="nav">
  <li class="<%= 'active' if params[:controller] == 'controller1' %>"> <a href="/link">Link</a> </li>
  <li class="<%= 'active' if params[:controller] == 'controller2' %>"> <a href="/link">Link</a> </li>
  <li class="<%= 'active' if params[:controller] == 'controller3' %>"> <a href="/link">Link</a> </li>        
</ul>

Solution 3 - Ruby on-Rails

https://github.com/twg/active_link_to

<%= active_link_to 'Users', users_path, :wrap_tag => :li %>

#=> <li class="active"><a href="/users">Users</a></li>

Solution 4 - Ruby on-Rails

I used a helper to implement this in the style of Rails' form helpers.

In a helper (e.g. app/helpers/ApplicationHelper.rb):

def nav_bar
  content_tag(:ul, class: "nav navbar-nav") do
    yield
  end
end

def nav_link(text, path)
  options = current_page?(path) ? { class: "active" } : {}
  content_tag(:li, options) do
    link_to text, path
  end
end

Then, in a view (e.g. app/views/layouts/application.html.erb):

<%= nav_bar do %>
  <%= nav_link 'Home', root_path %>
  <%= nav_link 'Posts', posts_path %>
  <%= nav_link 'Users', users_path %>
<% end %>

This example produces (when on the 'users' page):

<ul class="nav navbar-nav">
  <li><a href="/">Home</a></li>
  <li><a href="/posts">Posts</a></li>
  <li class="active"><a href="/users">Users</a></li>
</ul>

Solution 5 - Ruby on-Rails

Use this instead to select active link in nav based on the current route without server code:

    $(document).ready(function () {
        $('a[href="' + this.location.pathname + '"]').parent().addClass('active');
    });

Solution 6 - Ruby on-Rails

I've found success using the logical and (&&) in haml:

%ul.nav
  %li{class: current_page?(events_path) && 'active'}
    = link_to "Events", events_path
  %li{class: current_page?(about_path) && 'active'}
    = link_to "About Us", about_path

Solution 7 - Ruby on-Rails

For each link:

<% if current_page?(home_path) -%><li class="active"><% else -%><li><% end -%>
  <%= link_to 'Home', home_path %>
</li>

or even

<li <% if current_page?(home_path) -%>class="active"<% end -%>>
  <%= link_to 'Home', home_path %>
</li>

Solution 8 - Ruby on-Rails

not sure if you are asking about how the twitter bootstrap css is used, or the rails side. I'm assuming the rails side.

if so checkout the #link_to_if method or the #link_to_unless_current method

Solution 9 - Ruby on-Rails

Today I had the same question/problem but with an other approach for the solution. I create a helper function in application_helper.rb:

def navMainAktiv(actionName)
    if params[:action] == actionName    
    "active"
    end
end

and the link looks like this:

<li class="<%= navMainAktiv('about')%>"><%= link_to "About", about_path %></li>

You can replace params[:action] with params[:controller] and set your controller name in the link.

Solution 10 - Ruby on-Rails

Basic, No Helper

<%= content_tag(:li, class: ('active' if request.path == '/contact')) do %>
	<%= link_to 'Contact', '/contact' %>
<% end %>

I use this since I have more than one class -

<%= content_tag(:li, class: (request.path == '/contact' ? 'active black' : 'black')) do %>
	<%= link_to 'Contact', '/contact' %>
<% end %>

Solution 11 - Ruby on-Rails

I use this for each li:

<li><%= link_to_unless_current('Home', root_path) { link_to('Home', root_path, class: 'active') } %></li>

Solution 12 - Ruby on-Rails

You may define a helper method in application_helper.rb

def create_link(text, path)
  class_name = current_page?(path) ? 'active' : ''

  content_tag(:li, class: class_name) do
    link_to text, path
  end
end

Now you can use like:

create_link 'xyz', any_path which would render as

<li class="active">
  <a href="/any">xyz</a>
</li>

Hope it helps!

Solution 13 - Ruby on-Rails

You should do it yourself by manipulating CSS classes. That is, if a user clicks on some link, then do something (target action), set previous link inactive and new link active.

If your links take you to the server (that is, make page reload), then you can just render active link correctly on the server. Otherwise, if you're doing some client-side stuff (switching tab panes or whatever), you have to use javascript.

Solution 14 - Ruby on-Rails

you could use tabulous for the links

article here on how to combine tabulous with twitter bootstrap and rails 3.x

Solution 15 - Ruby on-Rails

I wrote simple helper method using build in view helper current_page? when you can specify custom class name in html_options hash.

def active_link_to(name = nil, options = nil, html_options = nil, &block)
  active_class = html_options[:active] || "active"
  html_options.delete(:active)
  html_options[:class] = "#{html_options[:class]} #{active_class}" if current_page?(options)
  link_to(name, options, html_options, &block)
end

Examples (when you are on root_path route):

<%= active_link_to "Main", root_path %>
# <a href="/" class="active">Main</a>

<%= active_link_to "Main", root_path, class: "bordered" %>
# <a href="/" class="bordered active">Main</a>

<%= active_link_to "Main", root_path, class: "bordered", active: "disabled" %>
# <a href="/" class="bordered disabled">Main</a>

Solution 16 - Ruby on-Rails

Many of the answers here have things that will work, or partial answers. I combined a bunch of things to make this rails helper method I use:

# helper to make bootstrap3 nav-pill <li>'s with links in them, that have
# proper 'active' class if active. 
#
# the current pill will have 'active' tag on the <li>
#
# html_options param will apply to <li>, not <a>. 
#
# can pass block which will be given to `link_to` as normal. 
def bootstrap_pill_link_to(label, link_params, html_options = {})
  current = current_page?(link_params)

  if current
    html_options[:class] ||= ""
    html_options[:class] << " active "
  end

  content_tag(:li, html_options) do
    link_to(label, link_params)
  end      
end

It could be made even fancier with argument checking to support &block on the link_to etc.

Solution 17 - Ruby on-Rails

Many answers already, but here is what I wrote to get Bootstrap Icons working with active link. Hope It will help someone

This helper will give you:

  1. li element with link containing custom text
  2. Optional Bootstrap3 Icon
  3. will turn active when you're on the right page

Put this in your application_helper.rb

def nav_link(link_text, link_path, icon='')
  class_name = current_page?(link_path) ? 'active' : ''
  icon_class = "glyphicon glyphicon-" + icon

  content_tag(:li, :class => class_name) do
    (class_name == '') ? (link_to content_tag(:span, " "+link_text, class: icon_class), link_path)
    : (link_to content_tag(:span, " "+link_text, class: icon_class), '#')
  end
end

And use link:

<%= nav_link 'Home', root_path, 'home'  %>

Last argument is optional - it will add icon to the link. Use names of glyph icons. If you want icon with no text:

    <%= nav_link '', root_path, 'home'  %>

Solution 18 - Ruby on-Rails

Here's what I did:

I created a ViewsHelper and included in ApplicationController:

include ViewsHelper

Inside ViewsHelper I created a simple method like this:

def page_state(path)
  current_page?(path) ? 'active' : ''
end

In my view I do this:

<li class="<%= page_state(foobar_path) %>"><%= link_to 'Foobars', foobar_path %></li>

Solution 19 - Ruby on-Rails

You sound like you need to implement a navigation system. If it's complex, it might get pretty ugly and pretty fast.

In this case, you might want to use a plugin that can handle that. You could use navigasmic or simple navigation (I would recommend navigasmic because it keeps the main layer in a view, where it belongs, and not in some configuration)

Solution 20 - Ruby on-Rails

Shortest codeĀ 

This deals with BOTH nav, and sub nav list elements. You can pass either an array a single path and will deal with both.

application_helper
# Active page method
def ap(p:);'active' if p.class == Array ? p.map{|m| current_page? m}.any? : (current_page? p) end
view (html.erb)
<ul class="nav navbar-nav">
  <li class="<%= ap p: home_path %>">Home</li>
  <li class="<%= ap p: account_path %>">Account</li>

  <li class="dropdown <%= ap p: [users_path, new_user_path] %>">
    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Users</a>
    <ul class="dropdown-menu" role="menu">
      <li class="<%= ap p: users_path %>">Users</li>
      <li class="<%= ap p: new_user_path %>">Add user</li>
    </ul>
  </li>
</ul>

Solution 21 - Ruby on-Rails

Using ruby on Sinatra ..

I m using bootstrap bare theme, here is the sample navbar code. Note the class name of the element -> .nav - as this is referred in java script.

/ Collect the nav links, forms, and other content for toggling
    #bs-example-navbar-collapse-1.collapse.navbar-collapse
      %ul.nav.navbar-nav
        %li
          %a{:href => "/demo/one"} Page One
        %li
          %a{:href => "/demo/two"} Page Two
        %li
          %a{:href => "/demo/three"} Page Three

in the view page (or partial) add this :javascript, this needs to be executed every time page loads.

haml view snippet ->

- content_for :javascript do
  :javascript
      $(function () {
          $.each($('.nav').find('li'), function() {
              $(this).toggleClass('active',
                  $(this).find('a').attr('href') == window.location.pathname);
          });
      });

In the javascript debugger make sure you have value of 'href' attribute matches with window.location.pathname. This is slightly different than the solution by @Zitrax which helped me fixing my issue.

Solution 22 - Ruby on-Rails

  def active_navigation?(controllers_name, actions_name)
   'active' if controllers_name.include?(controller_name) && actions_name.include?(action_name)
  end

slim

li class=(active_navigation?(['events'], ['index', 'show'])) = link_to t('navbar.events'), events_path

Solution 23 - Ruby on-Rails

This worked for me:

          <li class="nav-item <%= 'active' if current_page?(root_path) %>" >
            <%= link_to 'Home', root_path, class:"nav-link"%>
          </li>
          <li class="nav-item <%= 'active' if current_page?(tools_path) %>" >
            <%= link_to 'Tools', tools_path, class:"nav-link" %>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Request a new tool</a>
          </li>
          <li class="nav-item <%= 'active' if current_page?(home_about_path) %>" >
            <%= link_to 'About us', home_about_path, class:"nav-link"%>
          </li>

The code inside the <%= %> is just ruby, and the = means that the result of that code will be displayed on the HTML.Do this for every option you want to add in your navbar and it should work fine.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLearningRoRView Question on Stackoverflow
Solution 1 - Ruby on-RailsyorchView Answer on Stackoverflow
Solution 2 - Ruby on-RailsPierreView Answer on Stackoverflow
Solution 3 - Ruby on-RailsHeshamView Answer on Stackoverflow
Solution 4 - Ruby on-RailsDanielView Answer on Stackoverflow
Solution 5 - Ruby on-RailsChristian LandgrenView Answer on Stackoverflow
Solution 6 - Ruby on-RailsMeltemiView Answer on Stackoverflow
Solution 7 - Ruby on-Railsphil pirozhkovView Answer on Stackoverflow
Solution 8 - Ruby on-RailscpjolicoeurView Answer on Stackoverflow
Solution 9 - Ruby on-RailstheforceView Answer on Stackoverflow
Solution 10 - Ruby on-RailsscottkekoaView Answer on Stackoverflow
Solution 11 - Ruby on-RailsandreofthecapeView Answer on Stackoverflow
Solution 12 - Ruby on-RailsDushtView Answer on Stackoverflow
Solution 13 - Ruby on-RailsSergio TulentsevView Answer on Stackoverflow
Solution 14 - Ruby on-RailsstephenmurdochView Answer on Stackoverflow
Solution 15 - Ruby on-RailscintrzykView Answer on Stackoverflow
Solution 16 - Ruby on-RailsjrochkindView Answer on Stackoverflow
Solution 17 - Ruby on-RailsLukasz MuzykaView Answer on Stackoverflow
Solution 18 - Ruby on-RailsNick ResView Answer on Stackoverflow
Solution 19 - Ruby on-RailsAndrei SView Answer on Stackoverflow
Solution 20 - Ruby on-Railscb24View Answer on Stackoverflow
Solution 21 - Ruby on-RailsRishiView Answer on Stackoverflow
Solution 22 - Ruby on-RailsNazar HlynskyiView Answer on Stackoverflow
Solution 23 - Ruby on-RailsfacureyesView Answer on Stackoverflow