วิธีรับการนำทาง Twitter-Bootstrap เพื่อแสดงลิงค์ที่ใช้งานอยู่


106

ฉันไม่เข้าใจว่า Twitter Bootstrap ทำลิงค์ที่ใช้งานอยู่สำหรับการนำทางได้อย่างไร หากฉันมีการนำทางเป็นประจำเช่นนี้ (โดยมีทับทิมบนรางเชื่อม):

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

ฉันจะทำให้มันใช้งานได้อย่างไรตามลิงค์ที่คลิก


1
FYI: ฉันใช้อัญมณี active_link_to และระบุ {: wrap_class =>: li} สิ่งนี้จะสร้าง: <li class = 'active'> ... </li> เมื่อ REQUEST_URI ตรงกับค่า HREF ...
Justin E

คำตอบ:


95

เพิ่งตอบคำถามเดียวกันที่นี่ 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
ฉันคิดว่าความคิดนี้ถูกต้อง แต่การไปที่แฮช params โดยตรงดูเหมือนเป็นความคิดที่ไม่ดี ในทำนองเดียวกันสำหรับการทำซ้ำรหัสเดิมซ้ำแล้วซ้ำเล่า อย่างน้อยฉันอยากจะแนะนำให้ใช้ current_page? วิธีการตรวจสอบตัวควบคุม / การกระทำปัจจุบันและจะย้ายรหัสไปยังตัวช่วยเพื่อหลีกเลี่ยงการซ้ำรหัส
Dustin Frazier

2
ฉันสงสัยว่าฉันจะเขียนเหมือนกันใน haml ได้อย่างไร การแปลงเป็น haml ไม่ได้ผลสำหรับฉัน หรือบางทีฉันผิดที่ไหนสักแห่ง
benchwarmer

14
การใช้งาน HAML%li{:class => "#{'active' if current_page?(root_path)}"}=link_to "Home", root_path
Brian

มีวิธีที่สวยงามในการสร้างงานนี้ด้วยอัญมณี friendly_id โดยไม่ต้องร้องขอฐานข้อมูลหรือไม่?
Engin Erdogan

6
เอกสาร Rails แนะนำให้ใช้controller_nameและaction_nameผู้ช่วยเหลือแทนที่จะเข้าถึงจากแฮช params
Alexander Suraphel

171

คุณสามารถใช้บางสิ่งเช่น (คล้ายกับที่ @phil กล่าวถึง แต่สั้นกว่าเล็กน้อย):

<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
จะไม่ทำงานหากคุณมีการนำทางย่อย เส้นทางเปลี่ยนไป แต่คุณอยู่ในส่วนเดียวกัน .. เข้าท่าไหม?
Jakob Dam Jensen

3
ใช่ถูกต้องหากคุณต้องการไฮไลต์รายการเมนูไม่ว่าคุณจะใช้วิธีใดในคอนโทรลเลอร์เดียวกันคุณสามารถใช้โซลูชัน @Pierre:'active' if params[:controller] == 'controller1'

ใช่นั่นเป็นวิธีที่สง่างามที่สุดในการทำเช่นนั้น! ขอบคุณ :)
squiter

2
ฉันจะเพิ่มเส้นทางอื่น ๆ หรือเส้นทางเฉพาะเช่นuser_*_pathในได้<%= 'active' if current_page?(root_path) %>อย่างไร
Ismoh

1
คุณจะเพิ่มมากกว่าหนึ่งเส้นทางเพื่อให้รายการเมนูใช้งานได้อย่างไร ตัวอย่างเช่นหากคุณมีหลายรายการในเมนูแบบเลื่อนลงที่เป็นส่วนประกอบของรายการเมนูเดียวกันและคุณต้องการให้รายการเมนูใช้งานได้เมื่อคุณอยู่ในหน้าใด ๆ ที่พบในเมนูแบบเลื่อนลง? โปรดแจ้งให้เราทราบโดยเร็วที่สุด
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
รักมัน. ทำไมต้องเขียนล้อ?
lightyrs

นี่น่าจะเป็นหนทางไปจริงๆ ... เว้นแต่ว่าคุณไม่ต้องการที่จะพึ่งพาอีก
Mark G.

33

ฉันใช้ตัวช่วยเพื่อใช้สิ่งนี้ในรูปแบบของตัวช่วยแบบฟอร์มของ Rails

ในผู้ช่วย (เช่น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

จากนั้นในมุมมอง (เช่น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 %>

ตัวอย่างนี้สร้าง (เมื่ออยู่ในหน้า "ผู้ใช้"):

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

นี่มันเยี่ยมมาก! ขอบคุณ!
Krzysztof Witczak

ฉันชอบแนวคิดนี้ แต่ฉันจะเพิ่มอาร์กิวเมนต์ที่สามให้กับฟังก์ชัน nav_link ที่เรียกว่า html = {} ซึ่งจะถูกส่งไปยัง link_to ด้วยวิธีนี้คุณสามารถส่งแฮช html ไปยัง nav_link แบบเดียวกับที่คุณใช้ link_to ตามปกติ
Ryan Friedman

22

ใช้สิ่งนี้แทนเพื่อเลือกลิงค์ที่ใช้งานอยู่ในการนำทางตามเส้นทางปัจจุบันที่ไม่มีรหัสเซิร์ฟเวอร์:

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

2
นี่เป็นทางออกที่ดีที่สุดเพราะมันใช้งานได้กับเมนูแบบเลื่อนลงเช่นกันและฉันรวมบรรทัด$('li.active').closest('.dropdown').addClass('active');เพื่อเน้นเมนูหลักด้วย
Seralto

จะเปลี่ยนเป็นสมัครหน้าย่อยได้อย่างไร? เช่นexample.com/homeจะใช้งานได้ ฉันต้องการลิงก์ "หน้าแรก" เพื่อใช้งานในกรณีของexample.com/home/pageด้วย
athultuttu

11

ฉันพบว่าประสบความสำเร็จโดยใช้ตรรกะและ ( &&) ใน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

สำหรับแต่ละลิงค์:

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

หรือแม้กระทั่ง

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

3

ไม่แน่ใจว่าคุณถามเกี่ยวกับวิธีใช้ twitter bootstrap css หรือด้านราง ฉันสมมติว่าด้านราง

ถ้าเป็นเช่นนั้นชำระเงิน#link_to_ifวิธีการหรือ#link_to_unless_currentวิธีการ


3

วันนี้ฉันมีคำถาม / ปัญหาเดียวกัน แต่มีแนวทางอื่นในการแก้ปัญหา ฉันสร้างฟังก์ชันตัวช่วยใน application_helper.rb:

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

และลิงค์มีลักษณะดังนี้:

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

คุณสามารถแทนที่params[:action]ด้วยparams[:controller]และตั้งชื่อตัวควบคุมของคุณในการเชื่อมโยง


2

ฉันใช้สิ่งนี้สำหรับแต่ละli:

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


ชั้นจะต้องมีการตั้งค่าสำหรับการliไม่ได้a
คริสโต Oezbek

2

คุณอาจกำหนดวิธีการช่วยเหลือใน 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

ตอนนี้คุณสามารถใช้เช่น:

create_link 'xyz', any_path ซึ่งจะแสดงเป็น

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

หวังว่าจะช่วยได้!


1

คุณควรทำด้วยตัวเองโดยจัดการคลาส CSS นั่นคือหากผู้ใช้คลิกที่ลิงก์บางลิงก์จากนั้นทำอะไรบางอย่าง (การดำเนินการตามเป้าหมาย) ตั้งค่าลิงก์ก่อนหน้าไม่ใช้งานและลิงก์ใหม่ที่ใช้งานอยู่

หากลิงก์ของคุณนำคุณไปยังเซิร์ฟเวอร์ (นั่นคือทำการโหลดหน้าซ้ำ) คุณก็สามารถแสดงลิงก์ที่ใช้งานอยู่บนเซิร์ฟเวอร์ได้อย่างถูกต้อง มิฉะนั้นหากคุณกำลังทำบางอย่างในฝั่งไคลเอ็นต์ (สลับบานหน้าต่างแท็บหรืออะไรก็ตาม) คุณต้องใช้จาวาสคริปต์



1

ฉันเขียนวิธีตัวช่วยง่ายๆโดยใช้ build in view helper current_page?เมื่อคุณสามารถระบุclassชื่อที่กำหนดเองในhtml_optionsแฮช

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

ตัวอย่าง (เมื่อคุณอยู่บนroot_pathเส้นทาง):

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

คำตอบมากมายที่นี่มีสิ่งที่ใช้ได้ผลหรือคำตอบบางส่วน ฉันรวมสิ่งต่างๆเข้าด้วยกันเพื่อสร้างวิธีการช่วยเหลือรางนี้ที่ฉันใช้:

# 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

สามารถทำให้ดูน่าสนใจยิ่งขึ้นด้วยการตรวจสอบอาร์กิวเมนต์เพื่อสนับสนุน&blockบน link_to เป็นต้น


1

มีคำตอบมากมายแล้ว แต่นี่คือสิ่งที่ฉันเขียนเพื่อให้ Bootstrap Icons ทำงานกับลิงค์ที่ใช้งานอยู่ หวังว่ามันจะช่วยใครสักคน

ผู้ช่วยนี้จะให้คุณ:

  1. องค์ประกอบ li พร้อมลิงค์ที่มีข้อความที่กำหนดเอง
  2. ไอคอน Bootstrap3 เสริม
  3. จะเปิดใช้งานเมื่อคุณอยู่ในหน้าที่ถูกต้อง

ใส่สิ่งนี้ใน 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

และใช้ลิงค์:

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

อาร์กิวเมนต์สุดท้ายเป็นทางเลือก - จะเพิ่มไอคอนให้กับลิงก์ ใช้ชื่อของไอคอนสัญลักษณ์ หากคุณต้องการไอคอนที่ไม่มีข้อความ:

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

1

พื้นฐานไม่มีตัวช่วย

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

ฉันใช้สิ่งนี้เนื่องจากฉันมีมากกว่าหนึ่งคลาส -

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

1
สิ่งนี้จะใช้ได้กับการนำทางย่อย ๆ ด้วย ... เพียงแค่ใช้พา ธ การร้องขอพาเรนต์ในลิงค์ย่อย
scottkekoa

1

นี่คือสิ่งที่ฉันทำ:

ฉันสร้าง ViewsHelper และรวมอยู่ใน ApplicationController:

include ViewsHelper

Inside Views ช่วยด้วยฉันสร้างวิธีง่ายๆดังนี้:

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

ในมุมมองของฉันฉันทำสิ่งนี้:

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

0

คุณดูเหมือนจะต้องติดตั้งระบบนำทาง ถ้ามันซับซ้อนมันอาจจะค่อนข้างน่าเกลียดและค่อนข้างเร็ว

ในกรณีนี้คุณอาจต้องการใช้ปลั๊กอินที่สามารถจัดการได้ คุณสามารถใช้navigasmicหรือการนำทางอย่างง่าย (ฉันขอแนะนำ navigasmic เพราะจะเก็บเลเยอร์หลักไว้ในมุมมองที่เป็นของและไม่อยู่ในการกำหนดค่าบางอย่าง)


0

รหัสที่สั้นที่สุด 

สิ่งนี้เกี่ยวข้องกับทั้งองค์ประกอบการนำทางและองค์ประกอบรายการการนำทางย่อย คุณสามารถส่งอาร์เรย์ไปยังเส้นทางเดียวและจะจัดการกับทั้งสองอย่าง

application_helper

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

ดู (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

ใช้ทับทิมกับซินาตร้า ..

ฉันใช้ธีม bootstrap เปล่านี่คือตัวอย่างโค้ด navbar สังเกตชื่อคลาสขององค์ประกอบ -> .nav - ตามที่อ้างถึงในสคริปต์ java

/ 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

ในหน้าดู (หรือบางส่วน) ให้เพิ่มสิ่งนี้: จาวาสคริปต์สิ่งนี้จะต้องดำเนินการทุกครั้งที่โหลดหน้า

ข้อมูลโค้ดมุมมอง haml ->

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

ในโปรแกรมดีบัก javascript ตรวจสอบให้แน่ใจว่าคุณมีค่าแอตทริบิวต์ "href" ที่ตรงกับ window.location.pathname สิ่งนี้แตกต่างจากวิธีแก้ปัญหาโดย @Zitrax เล็กน้อยซึ่งช่วยฉันแก้ไขปัญหาได้


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

บาง

li class=(active_navigation?(['events'], ['index', 'show'])) = link_to t('navbar.events'), events_path
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.