Wie bekomme ich die Twitter-Bootstrap-Navigation, um den aktiven Link anzuzeigen?

106

Ich verstehe nicht, wie Twitter Bootstrap aktive Links für die Navigation ausführt. Wenn ich eine reguläre Navigation wie diese habe (mit Ruby on Rails Linking):

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

Wie halte ich es basierend auf dem angeklickten Link aktiv?

LearningRoR
quelle
1
Zu Ihrer Information: Ich verwende den Edelstein active_link_to und gebe {: wrap_class =>: li} an. Dadurch wird Folgendes erstellt: <li class = 'active'> ... </ li>, wenn REQUEST_URI mit dem HREF-Wert übereinstimmt ...
Justin E

Antworten:

95

Ich habe gerade eine Antwort auf dieselbe Frage hier gegeben. 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>
Pierre
quelle
21
Ich denke, die Idee ist hier richtig, aber direkt zum Parameter-Hash zu gehen, scheint eine schlechte Idee zu sein. Ebenso zum wiederholten Wiederholen desselben Codes. Ich würde zumindest empfehlen, die aktuelle Seite zu verwenden? Methode zum Überprüfen des aktuellen Controllers / der aktuellen Aktion und zum Verschieben des Codes in einen Helfer, um die Wiederholung des Codes zu vermeiden.
Dustin Frazier
2
Ich frage mich, wie ich das gleiche in haml schreibe. Die Umstellung auf Haml funktioniert bei mir nicht. Oder vielleicht irre ich mich irgendwo
Bankwärmer
14
HAML Implementierung%li{:class => "#{'active' if current_page?(root_path)}"}=link_to "Home", root_path
Brian
Gibt es eine elegante Möglichkeit, diese Arbeit mit friend_id gem zu erledigen, ohne DB-Anfragen zu stellen?
Engin Erdogan
6
Rails Docs empfiehlt die Verwendung von controller_nameund action_nameHelfern, anstatt über den Parameter-Hash auf sie zuzugreifen.
Alexander Suraphel
171

Sie können so etwas verwenden (sehr ähnlich zu dem, was @phil erwähnt hat, aber etwas kürzer):

<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>
yorch
quelle
10
funktioniert nicht, wenn Sie eine Subnavigation haben. Der Pfad ändert sich, aber Sie befinden sich im selben Abschnitt. Ist das sinnvoll?
Jakob Dam Jensen
3
Ja, richtig, wenn Sie einen Menüpunkt markieren möchten, egal welche Methode Sie in demselben Controller ausführen, können Sie die @ Pierre-Lösung verwenden:'active' if params[:controller] == 'controller1'
yorch
Ja, das ist der eleganteste Weg, das zu tun! Danke :)
Squiter
2
Wie kann ich weitere Pfade oder einen bestimmten Pfad wie user_*_pathin hinzufügen <%= 'active' if current_page?(root_path) %>?
Ismoh
1
Wie würden Sie mehr als einen Pfad hinzufügen, um den Menüpunkt zu aktivieren? Wenn Sie beispielsweise mehrere Elemente in einer Dropdown-Liste haben, die Bestandteile desselben Menüelements sind, und Sie das Menüelement aktivieren möchten, wenn Sie sich auf einer der Seiten im Dropdown-Menü befinden? Bitte lassen Sie es uns so schnell wie möglich wissen.
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>

Hesham
quelle
7
Liebe es. Warum das Rad neu schreiben?
Lightyrs
Dies sollte wirklich der richtige Weg sein ... Es sei denn, Sie möchten keine weitere Abhängigkeit ziehen.
Mark G.
33

Ich habe einen Helfer verwendet, um dies im Stil der Formularhelfer von Rails zu implementieren.

In einem Helfer (zB 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

Dann in einer Ansicht (zB 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 %>

In diesem Beispiel wird Folgendes erzeugt (auf der Seite "Benutzer"):

<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>
Daniel
quelle
Das ist toll! Vielen Dank!
Krzysztof Witczak
Ich mag diese Idee, aber ich würde der nav_link-Funktion ein drittes Argument namens html = {} hinzufügen, das dann an link_to übergeben wird. Auf diese Weise können Sie einen HTML-Hash an nav_link übergeben, so wie Sie link_to normalerweise verwenden würden.
Ryan Friedman
22

Verwenden Sie diese Option stattdessen, um einen aktiven Link in nav basierend auf der aktuellen Route ohne Servercode auszuwählen:

    $(document).ready(function () {
        $('a[href="' + this.location.pathname + '"]').parent().addClass('active');
    });
Christian Landgren
quelle
2
Dies ist die beste Lösung, da sie auch mit Dropdown-Menüs funktioniert, und ich füge die Zeile hinzu $('li.active').closest('.dropdown').addClass('active');, um auch das übergeordnete Menü hervorzuheben.
Seralto
Wie ändere ich es, um es auch für Unterseiten zu beantragen? wie example.com/home wird funktionieren. Ich brauche den Link "Home", um auch im Fall von example.com/home/page aktiv zu sein .
Athultuttu
11

Ich habe Erfolg mit dem logischen und ( &&) in haml gefunden :

%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
Meltemi
quelle
5

Für jeden Link:

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

oder auch

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

Ich bin mir nicht sicher, ob Sie nach der Verwendung des Twitter-Bootstrap-CSS oder der Rails-Seite fragen. Ich gehe von der Schienenseite aus.

Wenn ja, überprüfen Sie die #link_to_ifMethode oder die #link_to_unless_currentMethode

cpjolicoeur
quelle
3

Heute hatte ich die gleiche Frage / das gleiche Problem, aber mit einem anderen Lösungsansatz. Ich erstelle eine Hilfsfunktion in application_helper.rb:

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

und der Link sieht so aus:

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

Sie können ersetzen params[:action]mit params[:controller]und Ihren Controller - Namen in der Verbindung gesetzt.

die Kraft
quelle
2

Ich benutze dies für jeden li:

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

andreofthecape
quelle
Klasse muss für linicht eingestellt werdena
Christopher Oezbek
2

Sie können eine Hilfsmethode in definieren 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

Jetzt können Sie wie folgt verwenden:

create_link 'xyz', any_path was als rendern würde

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

Ich hoffe es hilft!

Dusht
quelle
1

Sie sollten dies selbst tun, indem Sie CSS-Klassen bearbeiten. Das heißt, wenn ein Benutzer auf einen Link klickt, dann etwas tun (Zielaktion), den vorherigen Link inaktiv und den neuen Link aktiv setzen.

Wenn Ihre Links Sie zum Server führen (dh die Seite neu laden), können Sie den aktiven Link einfach korrekt auf dem Server rendern. Andernfalls müssen Sie Javascript verwenden, wenn Sie clientseitige Aufgaben ausführen (Tab-Fenster wechseln oder was auch immer).

Sergio Tulentsev
quelle
1

Sie könnten tabellarisch für die Links verwenden

Artikel hier darüber, wie man tabulös mit Twitter Bootstrap und Rails 3.x kombiniert

stephenmurdoch
quelle
1

Ich habe eine einfache Hilfsmethode mit dem eingebauten Ansichtshelfer geschrieben, current_page?wenn Sie einen benutzerdefinierten classNamen in html_optionsHash angeben können .

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

Beispiele (wenn Sie root_pathunterwegs sind):

<%= 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>
cintrzyk
quelle
1

Viele der Antworten hier haben Dinge, die funktionieren werden, oder Teilantworten. Ich habe eine Reihe von Dingen kombiniert, um diese Rails-Hilfsmethode zu erstellen, die ich verwende:

# 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

Es könnte noch &blockausgefallener sein, wenn Argumente überprüft werden, um link_to usw. zu unterstützen .

jrochkind
quelle
1

Viele Antworten bereits, aber hier ist, was ich geschrieben habe, damit Bootstrap-Symbole mit aktivem Link funktionieren. Hoffe, es wird jemandem helfen

Dieser Helfer gibt Ihnen:

  1. li Element mit Link, der benutzerdefinierten Text enthält
  2. Optionales Bootstrap3-Symbol
  3. wird aktiv, wenn Sie auf der rechten Seite sind

Fügen Sie dies in Ihre application_helper.rb ein

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

Und benutze den Link:

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

Das letzte Argument ist optional - es wird dem Link ein Symbol hinzugefügt. Verwenden Sie Namen von Glyphensymbolen. Wenn Sie ein Symbol ohne Text möchten:

    <%= nav_link '', root_path, 'home'  %>
Lukasz Muzyka
quelle
1

Folgendes habe ich getan:

Ich habe einen ViewsHelper erstellt und in ApplicationController aufgenommen:

include ViewsHelper

In ViewsHelper habe ich eine einfache Methode wie die folgende erstellt:

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

Aus meiner Sicht mache ich das:

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

Sie scheinen ein Navigationssystem zu implementieren. Wenn es komplex ist, kann es ziemlich hässlich und ziemlich schnell werden.

In diesem Fall möchten Sie möglicherweise ein Plugin verwenden, das dies unterstützt. Sie können navigasmic oder einfache Navigation verwenden (ich würde navigasmic empfehlen, da die Hauptebene in einer Ansicht bleibt, in die sie gehört, und nicht in einer bestimmten Konfiguration).

Andrei S.
quelle
0

Kürzester Code 

Dies befasst sich sowohl mit Navigations- als auch mit Subnavigationslistenelementen. Sie können entweder einem Array einen einzelnen Pfad übergeben und sich mit beiden befassen.

application_helper

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

Ansicht (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>
cb24
quelle
0

Mit Rubin auf Sinatra ..

Ich verwende das nackte Bootstrap-Thema. Hier ist der Beispiel-Navigationscode. Beachten Sie den Klassennamen des Elements -> .nav -, auf den im Java-Skript verwiesen wird.

/ 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

Fügen Sie auf der Ansichtsseite (oder teilweise) Folgendes hinzu: Javascript, dies muss jedes Mal ausgeführt werden, wenn die Seite geladen wird.

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

Stellen Sie im Javascript-Debugger sicher, dass der Wert des Attributs 'href' mit window.location.pathname übereinstimmt. Dies unterscheidet sich geringfügig von der Lösung von @Zitrax, mit deren Hilfe ich mein Problem beheben konnte.

Rishi
quelle
0

Grundlegend, kein Helfer

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

Ich benutze dies, da ich mehr als eine Klasse habe -

<%= content_tag(:li, class: (request.path == '/contact' ? 'active black' : 'black')) do %>
    <%= link_to 'Contact', '/contact' %>
<% end %>
Scottkekoa
quelle
1
Dies funktioniert auch für jede Subnavigation ... verwenden Sie einfach den übergeordneten Anforderungspfad im Sublink.
Scottkekoa
0
  def active_navigation?(controllers_name, actions_name)
   'active' if controllers_name.include?(controller_name) && actions_name.include?(action_name)
  end

schlank

li class=(active_navigation?(['events'], ['index', 'show'])) = link_to t('navbar.events'), events_path
Nazar Hlynskyi
quelle