Dynamically add active class to bootstrap li in Rails
Solution 1
Read about current_page?
here
You can add a method for handle logic with current_page?
, example a method :
module ApplicationHelper
def active_class(link_path)
current_page?(link_path) ? "active" : ""
end
end
example bootstrap navbar template
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="#">Title</a>
<ul class="nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
</div>
</div>
So, on view looks like
HTML
<li class="<%= active_class(some_path) %>">
<%= link_to "text of link", some_path %>
</li>
HAML
%li{:class => active_class(some_path)}
= link_to "text of link", some_path
Or you can use request.fullpath
to get current full of path if a current path have a parameter
example
<ul>
<% Contry.all.each do |c| %>
<li class="snavitem <%= active_class(contry_path(c)) %>">
<%= link_to "show #{c.name}", contry_path(c) %>
</li>
<% end %>
</ul>
and on your application_helper.rb
def active_class(link_path)
request.fullpath == link_path ? "active" : ""
end
read about request.fullpath here
Solution 2
in my opinion, a cleaner way to achieve that is to write a link_to_in_li
method in application_helper.rb:
def link_to_in_li(body, url, html_options = {})
active = "active" if current_page?(url)
content_tag :li, class: active do
link_to body, url, html_options
end
end
then use it this way
<%= link_to_in_li "Home", root_path, id: "home_link" %>
I find the code inside li
a little difficult to read.
Solution 3
For anyone having trouble making sense of this, here is an example with my paths and filenames laid out explicitly. As a pretty new person to rails, I was having trouble figuring it out. Thanks to the other people who answered above, as it helped me figure it out!
I placed the Bootstrap navbar in my application.html.erb file:
<div class="navbar-header">
<a class="navbar-brand" href="/">Mapper</a>
<ul class="nav navbar-nav">
<li class="<%= is_active?('/') %>"><%= link_to "Home", '/' %></li>
<li class="<%= is_active?('/main/map') %>"><%= link_to "Map", '/main/map' %></li>
<li class="<%= is_active?('/main/about') %>"><%= link_to "About", '/main/about' %></li>
</ul>
</div>
This goes in the application_helper.rb file:
module ApplicationHelper
def is_active?(link_path)
current_page?(link_path) ? "active" : ""
end
end
That's it! Now your application will dynamically add the 'active' class to whatever page is currently being viewed (i.e. it's corresponding list item in the navbar). This is much simpler (and more DRY) than adding the navbar manually to each page (view) and then updating the 'active' class.
Solution 4
I'll post my answer that I created based on these others because in case of CRUD views the active class wasn't been placed.
module ApplicationHelper
def active_class(name)
controller_name.eql?(name) || current_page?(name) ? 'active' : ''
end
end
My views use something like this:
<ul class="nav navbar-nav">
<li class="nav-item <%= active_class('/') %>">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item <%= active_class('leads') %>">
<a class="nav-link" href="/leads">Leads</a>
</li>
</ul>
<ul class="nav navbar-nav pull-right <%= active_class(edit_user_registration_path) %>">
<li class="nav-item ">
<a class="nav-link" href="/users/edit">Perfil</a>
</li>
<li class="nav-item">
<%= link_to('Sair', destroy_user_session_path, method: :delete) %>
</li>
</ul>
Solution 5
Please try this in each page, check the cotroller or action and add the css
For example:
<li class= <%= (controller.controller_name.eql?('pages') && controller.action_name.eql?('index') )? 'active':''%> ><%= link_to 'my page', pages_path%></li>
Alain Goldman
I write tons of code and I drink the same amount of coffee for fuel. React / React-Native / Ruby / Rails / Meteor / Solidity / Truffle
Updated on June 24, 2022Comments
-
Alain Goldman almost 2 years
in the bootstrap navigation bar. You can get the effect of a button being clicked by adding the class
active
. Naturally, I want to use this on my pages. For example if I'm on the about us page I want the about us button clicked.What is the best way to go about this? I was going to go to each page and at the bottom have a jQuery function add the class
active
to it. Is there a better way? -
rails_id almost 11 yearsYou not says on your questions if you are using haml. updated answer
-
Alain Goldman almost 11 yearsSorry but you got it to work thank you. But why wouldn't %li{:class => is_active?(some_path)} work?
-
rails_id almost 11 yearsGlad to help!, have you added
is_active?
method on helper? -
Alain Goldman almost 11 yearsno i did what you said and got it to work i'm just curious as to why %li{:class => is_active?(some_path)} would not work
-
rails_id almost 11 yearsbecause you don't have
is_active?
method on helper,is_active?(some_path)
will callis_active?
method. -
Chizaram Chinedu over 9 yearsGood solution. Perfect for me.
-
R Milushev over 9 yearsVery clever in Rails way.
-
samuelkobe over 9 yearsEasiest answer I found. Also, if you need to have multiple classes on the <li> element you can simply add the additional classes like so:
content_tag :li, class: "#{active} other-class" do
-
scottknight about 9 yearsThis works great, I've been trying many other solutions and this is the best for me.
-
Pete about 9 yearsBeing overly pedantic here, but methods ending in question mark should probably return boolean values, not a CSS class string.
-
geostima over 8 yearsthank very much this helped me way more than the other answers since I too am very new to rails.
-
user2553863 over 6 yearsI think this is the best solution I've read up to now. It is DRY, and it only requires to add
_in_li
to the url helpers you might already have, because it takes the same arguments. Thanks.