Bagaimana cara mendapatkan navigasi Twitter-Bootstrap untuk menampilkan tautan aktif?


106

Saya tidak mengerti bagaimana Twitter Bootstrap melakukan tautan aktif untuk navigasi. Jika saya memiliki navigasi biasa seperti ini (dengan ruby ​​di rel yang menghubungkan):

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

Bagaimana cara membuatnya tetap aktif berdasarkan tautan yang diklik?


1
FYI: Saya menggunakan permata active_link_to dan menentukan {: wrap_class =>: li}. Ini akan membuat: <li class = 'active'> ... </li> bila REQUEST_URI cocok dengan nilai HREF ...
Justin E

Jawaban:


95

Baru saja membuat jawaban untuk pertanyaan yang sama di sini 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
Saya pikir idenya benar di sini, tetapi langsung ke hash params sepertinya ide yang buruk. Begitu juga untuk mengulang kode yang sama berulang kali. Saya akan merekomendasikan setidaknya menggunakan current_page? metode untuk memeriksa pengontrol / tindakan saat ini, dan juga akan memindahkan kode ke helper untuk menghindari pengulangan kode.
Dustin Frazier

2
Saya bertanya-tanya bagaimana cara menulis hal yang sama di haml. Beralih ke haml tidak berhasil untuk saya. Atau mungkin saya salah di suatu tempat
penghangat bangku

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

Adakah cara elegan untuk membuat ini berfungsi dengan permata friendly_id tanpa melakukan permintaan db?
Engin Erdogan

6
Dokumen Rails merekomendasikan penggunaan controller_namedan action_namehelper daripada mengaksesnya dari hash params.
Alexander Suraphel

171

Anda dapat menggunakan sesuatu seperti (sangat mirip dengan apa yang @phil sebutkan, tetapi sedikit lebih pendek):

<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
tidak berfungsi jika Anda memiliki subnavigasi. Jalannya berubah tetapi Anda berada di bagian yang sama .. masuk akal?
Jakob Dam Jensen

3
ya, benar, jika Anda ingin menyorot item menu apa pun metode yang Anda jalankan di dalam pengontrol yang sama, Anda dapat menggunakan solusi @Pierre:'active' if params[:controller] == 'controller1'
yorch

Ya, itu cara paling elegan untuk melakukan itu! Terima kasih :)
squiter

2
Bagaimana cara menambahkan lebih banyak jalur atau jalur tertentu seperti user_*_pathdi <%= 'active' if current_page?(root_path) %>?
Ismoh

1
Bagaimana Anda menambahkan lebih dari satu jalur untuk mengaktifkan item menu? Misalnya, jika Anda memiliki beberapa item dalam dropdown yang merupakan komponen dari item menu yang sama, dan Anda ingin mengaktifkan item menu tersebut saat Anda berada di halaman mana pun yang ditemukan di menu dropdown? Harap beri tahu kami secepatnya.
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
Suka. Mengapa menulis ulang roda?
lightyrs

Ini benar-benar harus menjadi cara untuk pergi ... Kecuali Anda tidak ingin menarik ketergantungan lain.
Mark G.

33

Saya menggunakan helper untuk mengimplementasikan ini dalam gaya form helper Rails.

Di helper (mis. 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

Kemudian, dalam tampilan (mis. 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 %>

Contoh ini menghasilkan (saat berada di halaman 'pengguna'):

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

Ini bagus! Terima kasih!
Krzysztof Witczak

Saya suka ide ini, namun saya akan menambahkan argumen ketiga ke fungsi nav_link yang disebut html = {} yang kemudian diteruskan ke link_to. Dengan cara itu Anda dapat meneruskan hash html ke nav_link dengan cara yang sama seperti Anda menggunakan link_to secara normal.
Ryan Friedman

22

Gunakan ini sebagai gantinya untuk memilih tautan aktif di nav berdasarkan pada rute saat ini tanpa kode server:

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

2
Ini adalah solusi terbaik karena berfungsi dengan menu dropdown juga, dan saya menyertakan baris $('li.active').closest('.dropdown').addClass('active');untuk menyorot menu induk juga.
Seralto

bagaimana cara mengubahnya untuk menerapkan sub-halaman juga? seperti example.com/home akan berfungsi. Saya perlu tautan "Beranda" untuk aktif dalam kasus example.com/home/page juga.
athultuttu

11

Saya telah menemukan kesuksesan menggunakan logical dan ( &&) di 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

Untuk setiap tautan:

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

atau bahkan

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


3

Hari ini saya memiliki pertanyaan / masalah yang sama tetapi dengan pendekatan lain untuk solusinya. Saya membuat fungsi pembantu di application_helper.rb:

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

dan tautannya terlihat seperti ini:

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

Anda dapat mengganti params[:action]dengan params[:controller]dan mengatur nama pengontrol Anda di tautan.


2

Saya menggunakan ini untuk setiap li:

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


Kelas harus ditetapkan untuk litidaka
Christopher Oezbek

2

Anda dapat menentukan metode pembantu di 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

Sekarang Anda bisa menggunakan seperti:

create_link 'xyz', any_path yang akan dirender sebagai

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

Semoga membantu!


1

Anda harus melakukannya sendiri dengan memanipulasi kelas CSS. Artinya, jika pengguna mengklik beberapa link, kemudian melakukan sesuatu (tindakan target), mengatur link sebelumnya tidak aktif dan link baru aktif.

Jika tautan Anda membawa Anda ke server (yaitu, membuat halaman dimuat ulang), maka Anda dapat membuat tautan aktif dengan benar di server. Jika tidak, jika Anda melakukan beberapa hal sisi klien (beralih panel tab atau apa pun), Anda harus menggunakan javascript.



1

Saya menulis metode helper sederhana menggunakan build in view helper current_page?ketika Anda dapat menentukan classnama kustom dalam html_optionshash.

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

Contoh (saat Anda dalam root_pathperjalanan):

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

Banyak dari jawaban di sini memiliki hal-hal yang akan berhasil, atau jawaban sebagian. Saya menggabungkan banyak hal untuk membuat metode penolong rel ini yang saya gunakan:

# 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

Itu bisa dibuat lebih menarik dengan pemeriksaan argumen untuk mendukung &blocklink_to dll.


1

Sudah banyak jawaban, tapi inilah yang saya tulis untuk membuat Ikon Bootstrap bekerja dengan tautan aktif. Semoga Ini akan membantu seseorang

Pembantu ini akan memberi Anda:

  1. elemen li dengan link yang berisi teks kustom
  2. Ikon Bootstrap3 opsional
  3. akan aktif saat Anda berada di halaman yang benar

Taruh ini di application_helper.rb Anda

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

Dan gunakan tautan:

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

Argumen terakhir adalah opsional - ini akan menambahkan ikon ke tautan. Gunakan nama ikon mesin terbang. Jika Anda menginginkan ikon tanpa teks:

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

1

Inilah yang saya lakukan:

Saya membuat ViewsHelper dan disertakan dalam ApplicationController:

include ViewsHelper

Di dalam ViewsHelper saya membuat metode sederhana seperti ini:

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

Dalam pandangan saya, saya melakukan ini:

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

0

Anda terdengar seperti Anda perlu menerapkan sistem navigasi. Jika rumit, mungkin akan menjadi sangat jelek dan cukup cepat.

Dalam kasus ini, Anda mungkin ingin menggunakan plugin yang bisa mengatasinya. Anda bisa menggunakan navigasmic atau navigasi sederhana (saya akan merekomendasikan navigasmic karena itu membuat lapisan utama dalam tampilan, tempatnya, dan tidak dalam beberapa konfigurasi)


0

Kode terpendek 

Ini berhubungan dengan KEDUA nav, dan elemen daftar sub nav. Anda dapat melewatkan salah satu larik jalur tunggal dan akan menangani keduanya.

application_helper

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

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

Menggunakan ruby ​​di Sinatra ..

Saya menggunakan tema bootstrap telanjang, berikut adalah contoh kode navbar. Catat nama kelas elemen -> .nav - karena ini disebut dalam 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

di halaman tampilan (atau sebagian) tambahkan ini: javascript, ini perlu dijalankan setiap kali halaman dimuat.

potongan tampilan haml ->

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

Dalam debugger javascript, pastikan Anda memiliki nilai atribut 'href' yang cocok dengan window.location.pathname. Ini sedikit berbeda dari solusi oleh @Zitrax yang membantu saya memperbaiki masalah saya.


0

Dasar, Tidak Ada Pembantu

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

Saya menggunakan ini karena saya memiliki lebih dari satu kelas -

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

1
Ini akan bekerja untuk sub navigasi juga ... cukup gunakan jalur permintaan orang tua di sub tautan.
scottkekoa

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

ramping

li class=(active_navigation?(['events'], ['index', 'show'])) = link_to t('navbar.events'), events_path
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.