如何让 Twitter-Bootstrap 导航显示活动链接?

我不明白 Bootstrap 是如何为导航设置活动链接的。如果我有一个像下面这样的常规导航(通过 Ruby 在轨道上链接) :

<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>

我如何保持它的活动基于链接点击?

85475 次浏览

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

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.

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)

Just made an answer on the very same question here 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>

you could use tabulous for the links

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

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>

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.

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>

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>

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');
});

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

I use this for each li:

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

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>

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.

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>

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'  %>

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!

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>

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.

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 %>

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>
  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

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.