Làm cách nào để điều hướng Twitter-Bootstrap hiển thị liên kết đang hoạt động?


106

Tôi không hiểu cách Twitter Bootstrap thực hiện các liên kết hoạt động cho điều hướng. Nếu tôi có một điều hướng thường xuyên như thế này (với liên kết ruby ​​trên đường ray):

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

Làm cách nào để giữ cho nó hoạt động dựa trên liên kết được nhấp vào?


1
FYI: Tôi sử dụng gem active_link_to và chỉ định {: wrap_class =>: li}. Điều này sẽ tạo: <li class = 'active'> ... </li> khi REQUEST_URI khớp với giá trị HREF ...
Justin E

Câu trả lời:


95

Vừa đưa ra câu trả lời cho câu hỏi tương tự tại đây 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>

21
Tôi nghĩ ý tưởng ở đây là chính xác, nhưng đi thẳng đến băm params có vẻ là một ý tưởng tồi. Tương tự như vậy để lặp đi lặp lại cùng một mã. Tôi muốn giới thiệu ít nhất bằng cách sử dụng current_page? để kiểm tra bộ điều khiển / hành động hiện tại và cũng sẽ di chuyển mã vào một trình trợ giúp để tránh lặp lại mã.
Dustin Frazier

2
Tôi tự hỏi làm thế nào tôi viết giống nhau trong haml. Chuyển đổi sang haml không phù hợp với tôi. Hoặc có lẽ tôi sai ở đâu đó
benchwarmer

14
Triển khai HAML%li{:class => "#{'active' if current_page?(root_path)}"}=link_to "Home", root_path
Brian

Có cách nào thanh lịch để làm cho điều này hoạt động với đá quý Friendly_id mà không thực hiện các yêu cầu db không?
Engin Erdogan

6
Rails docs khuyến nghị sử dụng controller_nameand action_namehelpers thay vì truy cập chúng từ params hash.
Alexander Suraphel

171

Bạn có thể sử dụng một cái gì đó như (rất giống với những gì @phil đã đề cập, nhưng ngắn hơn một chút):

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

10
không hoạt động nếu bạn có quyền phụ. Con đường thay đổi nhưng bạn đang ở trong cùng một phần .. có ý nghĩa?
Jakob Dam Jensen,

3
vâng, chính xác, nếu bạn muốn đánh dấu một mục menu bất kể bạn đang chạy phương pháp nào bên trong cùng một bộ điều khiển, bạn có thể sử dụng giải pháp @Pierre:'active' if params[:controller] == 'controller1'
yorch

Vâng, đó là cách thanh lịch nhất để làm điều đó! Cảm ơn :)
squiter

2
Làm cách nào để thêm nhiều đường dẫn hơn hoặc một đường dẫn cụ thể như user_*_pathtrong <%= 'active' if current_page?(root_path) %>?
Ismoh

1
Làm thế nào bạn sẽ thêm nhiều hơn một đường dẫn để làm cho mục menu hoạt động? Ví dụ: nếu bạn có một số mục trong menu thả xuống là các thành phần của cùng một mục menu và bạn muốn đặt mục menu hoạt động khi bạn đang ở bất kỳ trang nào được tìm thấy trong menu thả xuống? Xin vui lòng cho chúng tôi biết càng sớm càng tốt.
msc,

47

https://github.com/twg/active_link_to

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

#=> <li class="active"><a href="https://stackoverflow.com/users">Users</a></li>


7
Yêu nó. Tại sao phải viết lại bánh xe?
lightyrs

Đây thực sự nên là con đường để đi ... Trừ khi bạn không muốn kéo thêm một sự phụ thuộc khác.
Mark G.

33

Tôi đã sử dụng trình trợ giúp để triển khai điều này theo kiểu trình trợ giúp biểu mẫu của Rails.

Trong một trình trợ giúp (ví dụ 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

Sau đó, trong một khung nhìn (ví dụ 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 %>

Ví dụ này tạo ra (khi trên trang 'người dùng'):

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

Điều đó thật tuyệt! Cảm ơn!
Krzysztof Witczak

Tôi thích ý tưởng này, tuy nhiên tôi muốn thêm đối số thứ ba vào hàm nav_link được gọi là html = {} sau đó được chuyển đến link_to. Bằng cách đó, bạn có thể chuyển một hàm băm html đến nav_link giống như cách bạn sử dụng link_to bình thường.
Ryan Friedman

22

Thay vào đó, hãy sử dụng liên kết này để chọn liên kết hoạt động trong điều hướng dựa trên tuyến đường hiện tại không có mã máy chủ:

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

2
Đây là giải pháp tốt nhất vì nó cũng hoạt động với menu thả xuống và tôi cũng bao gồm dòng $('li.active').closest('.dropdown').addClass('active');để đánh dấu menu chính.
Seralto

Làm thế nào để thay đổi nó để áp dụng cho các trang phụ? như example.com/home sẽ hoạt động. Tôi cần liên kết "Trang chủ" để hoạt động trong trường hợp cũng có example.com/home/page .
sportsultuttu

11

Tôi đã thành công khi sử dụng logic và ( &&) trong 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

5

Đối với mỗi liên kết:

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

hoặc thậm chí

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

3

không chắc nếu bạn đang hỏi về cách sử dụng twitter bootstrap css, hoặc phía rails. Tôi đang giả định phía đường ray.

nếu vậy hãy kiểm tra #link_to_ifphương pháp hoặc #link_to_unless_currentphương pháp


3

Hôm nay tôi có cùng một câu hỏi / vấn đề nhưng với một cách tiếp cận khác cho giải pháp. Tôi tạo một hàm trợ giúp trong application_helper.rb:

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

và liên kết trông như thế này:

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

Bạn có thể thay thế params[:action]bằng params[:controller]và đặt tên bộ điều khiển của mình trong liên kết.


2

Tôi sử dụng cái này cho mỗi li:

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


Lớp cần phải được thiết lập cho likhônga
Christopher Oezbek

2

Bạn có thể xác định một phương thức trợ giúp trong 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

Bây giờ bạn có thể sử dụng như:

create_link 'xyz', any_path mà sẽ hiển thị như

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

Hy vọng nó giúp!


1

Bạn nên tự làm điều đó bằng cách thao tác với các lớp CSS. Nghĩa là, nếu người dùng nhấp vào một số liên kết, sau đó làm điều gì đó (hành động mục tiêu), đặt liên kết trước đó không hoạt động và liên kết mới hoạt động.

Nếu các liên kết của bạn đưa bạn đến máy chủ (nghĩa là tải lại trang), thì bạn có thể hiển thị liên kết đang hoạt động một cách chính xác trên máy chủ. Mặt khác, nếu bạn đang thực hiện một số nội dung phía máy khách (chuyển đổi ngăn tab hoặc bất cứ thứ gì), bạn phải sử dụng javascript.



1

Tôi đã viết phương pháp trợ giúp đơn giản bằng cách sử dụng trình trợ giúp xây dựng trong chế độ xem current_page?khi bạn có thể chỉ định classtên tùy chỉnh trong html_optionsbăm.

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

Ví dụ (khi bạn đang trên root_pathđường):

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

1

Nhiều câu trả lời ở đây có những thứ sẽ hoạt động, hoặc câu trả lời một phần. Tôi đã kết hợp nhiều thứ để tạo ra phương pháp trợ giúp đường ray mà tôi sử dụng:

# 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

Nó có thể được làm cho thậm chí còn hấp dẫn hơn với việc kiểm tra đối số để hỗ trợ &blocktrên link_to, v.v.


1

Nhiều câu trả lời đã có, nhưng đây là những gì tôi đã viết để có được Biểu tượng Bootstrap hoạt động với liên kết hoạt động. Hy vọng nó sẽ giúp ai đó

Người trợ giúp này sẽ cung cấp cho bạn:

  1. phần tử li với liên kết chứa văn bản tùy chỉnh
  2. Biểu tượng Bootstrap3 tùy chọn
  3. sẽ hoạt động khi bạn ở đúng trang

Đặt cái này vào application_helper.rb của bạn

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

Và sử dụng liên kết:

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

Đối số cuối cùng là tùy chọn - nó sẽ thêm biểu tượng vào liên kết. Sử dụng tên của các biểu tượng glyph. Nếu bạn muốn biểu tượng không có văn bản:

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

1

Đây là những gì tôi đã làm:

Tôi đã tạo một ViewsHelper và đưa vào ApplicationController:

include ViewsHelper

Inside ViewsHelper, tôi đã tạo một phương thức đơn giản như sau:

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

Theo quan điểm của tôi, tôi làm điều này:

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

0

Bạn có vẻ như bạn cần triển khai một hệ thống định vị. Nếu nó phức tạp, nó có thể trở nên khá xấu và khá nhanh.

Trong trường hợp này, bạn có thể muốn sử dụng một plugin có thể xử lý điều đó. Bạn có thể sử dụng navigasmic hoặc đơn giản chuyển hướng (Tôi muốn giới thiệu navigasmic vì nó giữ lớp chính trong một cái nhìn, nơi mà nó thuộc về, và không có trong một số cấu hình)


0

Mã ngắn nhất 

Điều này đề cập đến CẢ HAI điều hướng và các phần tử danh sách điều hướng phụ. Bạn có thể truyền cho mảng một đường dẫn duy nhất và sẽ xử lý cả hai.

application_helper

# Active page method
def ap(p:);'active' if p.class == Array ? p.map{|m| current_page? m}.any? : (current_page? p) end

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

0

Sử dụng ruby ​​trên Sinatra ..

Tôi đang sử dụng chủ đề trần bootstrap, đây là mã điều hướng mẫu. Lưu ý tên lớp của phần tử -> .nav - vì nó được gọi trong 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

trong trang xem (hoặc một phần) thêm this: javascript, điều này cần được thực thi mỗi khi tải trang.

đoạn mã chế độ xem haml ->

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

Trong trình gỡ lỗi javascript, hãy đảm bảo rằng bạn có giá trị của thuộc tính 'href' phù hợp với window.location.pathname. Điều này hơi khác so với giải pháp của @Zitrax đã giúp tôi khắc phục sự cố của mình.


0

Cơ bản, không có người trợ giúp

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

Tôi sử dụng cái này vì tôi có nhiều hơn một lớp -

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

1
Điều này cũng sẽ hoạt động đối với bất kỳ điều hướng phụ nào ... chỉ cần sử dụng đường dẫn yêu cầu chính trong liên kết phụ.
scottkekoa

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

mảnh khảnh

li class=(active_navigation?(['events'], ['index', 'show'])) = link_to t('navbar.events'), events_path
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.