it-swarm.com.de

Der beste Weg, dem Nav in Rails 3 "aktuelle" Klasse hinzuzufügen

Ich habe einige statische Seiten in einem Navigationsmenü. Ich möchte dem aktuell angezeigten Artikel eine Klasse wie "current" hinzufügen.

Die Art und Weise, in der ich dies tue, ist das Hinzufügen von Tonnen Hilfsmethoden (jeweils für ein Element), um den Controller und die Aktion zu überprüfen.

def current_root_class
  'class="current"' if controller_name == "homepage" && action_name == "index" 
end

<ul>
  <li <%= current_root_class %>><%= link_to "Home", root_path %>

Gibt es eine bessere Möglichkeit, dies zu tun? Mein jetziger Weg ist so dumm ......

110
PeterWong

Nicht wirklich eine Antwort hier, weil ich ganz genauso benutze wie Sie. Ich habe gerade Hilfsmethoden definiert, um auf mehrere Controller oder Aktionen zu testen:

In application_helper.rb

  def controller?(*controller)
    controller.include?(params[:controller])
  end

  def action?(*action)
    action.include?(params[:action])
  end

Dann können Sie if controller?("homepage") && action?("index", "show") in Ihren Ansichten oder anderen Hilfsmethoden verwenden.

55
Yannis

Ich habe einen Helfer namens nav_link gemacht:

def nav_link(link_text, link_path)
  class_name = current_page?(link_path) ? 'current' : ''

  content_tag(:li, :class => class_name) do
    link_to link_text, link_path
  end
end

verwendet wie:

nav_link 'Home', root_path

was HTML erzeugen wird

<li class="current"><a href="/">Home</a></li>
286
Skilldrick

Verwenden Sie den Helper current_page? , um zu bestimmen, ob Sie die Klasse "current" zuweisen möchten. Zum Beispiel: 

<%= 'active' if current_page?(home_about_path) %>

Beachten Sie, dass Sie auch einen Pfad übergeben können (nicht nur einen Hash von Optionen), z. B. current_page?(root_path).

68
jpemberthy

Ich verwende diese Funktion nav_link (text, link) in application_helper.rb (Rails 3), um die Aufgabe zu erledigen, und sie rollt meine Twitter 2.0-Navigationsleisten-Links für mich. 

def nav_link(text, link)
    recognized = Rails.application.routes.recognize_path(link)
    if recognized[:controller] == params[:controller] && recognized[:action] == params[:action]
        content_tag(:li, :class => "active") do
            link_to( text, link)
        end
    else
        content_tag(:li) do
            link_to( text, link)
        end
    end
end

Beispiel:

<%=nav_link("About Us", about_path) %>
26
Peyton

So habe ich es gemacht, indem Sie eine Hilfsfunktion im application_helper hinzufügen

def current_class?(test_path)
  return 'current' if request.request_uri == test_path
  ''
end

Dann im nav, 

<%= link_to 'Home', root_path, :class => current_class?(root_path) %>

Dadurch wird der Link-Pfad anhand der aktuellen Seiten-URI getestet und entweder Ihre aktuelle Klasse oder eine leere Zeichenfolge zurückgegeben.

Ich habe das nicht gründlich getestet und bin sehr neu im RoR (bewegt sich nach einem Jahrzehnt mit PHP). Wenn dies einen großen Fehler hat, würde ich es gerne hören.

Zumindest auf diese Weise benötigen Sie nur eine Hilfsfunktion und einen einfachen Aufruf pro Link.

10
fullybaked

Um @Skilldricks Antwort auszubauen ...

Wenn Sie diesen Code zu application.js hinzufügen, wird sichergestellt, dass auch Dropdown-Menüs mit aktiven untergeordneten Elementen als aktiv markiert werden.

$('.active').closest('li.dropdown').addClass('active');

So fassen Sie den unterstützenden Code zusammen: Fügen Sie einen Helfer namens nav_link hinzu:

def nav_link_to(link_text, link_path)
  class_name = current_page?(link_path) ? 'active' : ''

  content_tag(:li, :class => class_name) do
    link_to link_text, link_path
  end
end

verwendet wie:

nav_link_to 'Home', root_path

was HTML erzeugen wird

<li class="active"><a href="/">Home</a></li>
6
TheEricMiller

Ich weiß, dass dies eine veraltete Antwort ist, aber Sie können alle diese aktuellen Seitenüberprüfungen einfach ignorieren, indem Sie einen link_to-Helper-Wrapper mit dem Namen active_link_to gem verwenden. Sie funktioniert genau so, wie Sie es möchten, und fügt eine aktuelle Klasse zum aktuellen Seitenlink hinzu

4
fuyi

Ich denke der beste Weg ist

application_helper.rb:

def is_active(controller, action)       
  params[:action] == action && params[:controller] == controller ? "active" : nil        
end

Und im Menü:

<li class="<%= is_active('controller', 'action') %>">
4
IPIvliev

Hier ist das vollständige Beispiel zum Hinzufügen einer aktiven Klasse auf der Bootstrap-Menüseite in der Rails-Ansicht.

    <li class="<%= 'active' if current_page?(root_path) %>"><%= link_to 'Home', controller: "welcome" %></li>
    <li class="<%= 'active' if current_page?(about_path) %>"><%= link_to 'About us', about_path %></li>
   <li class="<%= 'active' if current_page?(contact_path) %>"><%= link_to 'Contact us', contact_path %></li>
4
Little Phild

Ich benutze einen tollen Edelstein namens Tabs on Rails .

3
icecream

Für mich persönlich habe ich hier eine Kombination von Antworten verwendet

<li class="<%= 'active' if current_page?(inventory_index_path) %>"><a href="#">Menu</a></li>

Ich verwende materialise css und meine Art, die Hauptkategorien zusammenklappbar zu machen, ist den folgenden Code zu verwenden

$('.active').closest(".collapsible.collapsible-accordion")
            .find(".collapsible-header")
            .click();

hoffe es hilft jemandem

3
Petros Kyriakou

Die current_page?-Methode ist für mich nicht flexibel genug (sagen Sie, Sie setzen einen Controller, aber keine Aktion. Dann wird nur die Index-Aktion des Controllers als wahr zurückgegeben.)

  def nav_link_to(link_text, link_path, checks=nil)
    active = false
    if not checks.nil?
      active = true
      checks.each do |check,v|
        if not v.include? params[check]
          active = false
          break
        end
      end
    end

    return content_tag :li, :class => (active ? 'active' : '') do
      link_to link_text, link_path
    end
  end

Beispiel:

nav_link_to "Pages", pages_url, :controller => 'pages'
2
unrelativity

Ich habe eine kürzere Version von nav_link, die genau wie link_to funktioniert, aber zur Ausgabe eines umschließenden li-Tags angepasst ist. 

Fügen Sie Folgendes in Ihre application_helper.rb ein

def nav_link(*args, &block)
    if block_given?
      options      = args.first || {}
      html_options = args.second
      nav_link(capture(&block), options, html_options)
    else
      name         = args[0]
      options      = args[1] || {}
      html_options = args[2]

      html_options = convert_options_to_data_attributes(options, html_options)
      url = url_for(options)

      class_name = current_page?(url) ? 'active' : nil

      href = html_options['href']
      tag_options = tag_options(html_options)

      href_attr = "href=\"#{ERB::Util.html_escape(url)}\"" unless href
      "<li class=\"#{class_name}\"><a #{href_attr}#{tag_options}>#{ERB::Util.html_escape(name || url)}</a></li>".html_safe
    end
  end

Wenn Sie sich den obigen Code ansehen und ihn mit dem link_to-Code in url_helper.rb vergleichen, besteht der einzige Unterschied darin, dass er prüft, ob die URL die aktuelle Seite ist, und fügt die Klasse "active" einem umschließenden li-Tag hinzu. Dies liegt daran, dass ich den nav_link-Helfer mit Twitter Bootstraps nav-Komponente benutze , die Links bevorzugt, die in li-Tags eingeschlossen werden, und die "aktive" Klasse, die auf das äußere li angewendet wird.

Das Schöne an dem obigen Code ist, dass Sie einen Block in die Funktion übergeben können, genau wie Sie es mit link_to tun können.

Eine Bootstrap-Navigationsliste mit Symbolen würde beispielsweise so aussehen:

Schlank:

ul.nav.nav-list
  =nav_link root_path do
    i.icon-home
    |  Home
  =nav_link "#" do
    i.icon-user
    |  Users

Ausgabe:

<ul class="nav nav-list">
  <li class="active">
    <a href="/">
      <i class="icon-home"/>
      Home
    </a>
  </li>
  <li>
    <a href="#">
      <i class="icon-users"/>
      Users
    </a>
  </li>
</ul>

Außerdem können Sie, genau wie der link_to-Helfer, HTML-Optionen in nav_link übergeben, die auf ein Tag angewendet werden.

Ein Beispiel für die Übergabe eines Titels für den Anker:

Schlank:

ul.nav.nav-list
  =nav_link root_path, title:"Home" do
    i.icon-home
    |  Home
  =nav_link "#", title:"Users" do
    i.icon-user
    |  Users

Ausgabe:

<ul class="nav nav-list">
  <li class="active">
    <a href="/" title="Home">
      <i class="icon-home"/>
      Home
    </a>
  </li>
  <li>
    <a href="#" title="Users">
      <i class="icon-users"/>
      Users
    </a>
  </li>
</ul>
2
Joe Chen

Lassen Sie mich meine Lösung zeigen:

_header.html.erb :

  <ul class="nav">
    <%= nav_tabs(@tabs) %> 
  </ul>

application_helper.rb :

 def nav_tabs(tabs=[])
    html = []
    tabs.each do |tab| 
      html << (content_tag :li, :class => ("current-page" if request.fullpath.split(/[\??]/)[0] == tab[:path]) do
        link_to tab[:path] do
          content_tag(:i, '', :class => tab[:icon]) +
          tag(:br) +
          "#{tab[:name]}"
        end
      end)        
    end

    html.join.html_safe
  end

application_controller.rb :

before_filter :set_navigation_tabs

private
def set_navigation_tabs
  @tabs = 
    if current_user && manager?
      [
        { :name => "Home", :icon => "icon-home", :path => home_index_path },
        { :name => "Portfolio", :icon => "icon-camera", :path => portfolio_home_index_path },
        { :name => "Contact", :icon => "icon-envelope-alt", :path => contact_home_index_path }
      ]
    elsif current_user && client?
      ...
    end
2
Mike Andrianov

Ich verwende einen einfachen Helfer wie diesen für Links auf oberster Ebene, so dass auf der Seite /stories/my-story der Link /stories hervorgehoben wird

def nav_link text, url

  active = (url == request.fullpath || (url != '/' && request.fullpath[0..(url.size-1)] == url))

  "<li#{ active ? " class='selected'" : '' }><a href='#{url}'>#{text}</a></li>".html_safe

end
2
complistic

Ja! Schauen Sie sich diesen Artikel an: Eine bessere Methode zum Hinzufügen einer "ausgewählten" Klasse zu Links in Rails

Legen Sie nav_link_helper.rb in app/helpers ab und es kann so einfach sein wie:

<%= nav_link 'My_Page', 'http://example.com/page' %>

Der nav_link-Helper funktioniert genauso wie der Standard-Rails-link_to-Helper, fügt Ihrem Link (oder seinem Wrapper) jedoch eine ausgewählte Klasse hinzu, wenn bestimmte Kriterien erfüllt sind. Wenn die Ziel-URL der Verknüpfung dieselbe URL wie die URL der aktuellen Seite ist, wird standardmäßig eine Standardklasse "Ausgewählt" zu der Verknüpfung hinzugefügt.

Hier gibt es einen Gist: https://Gist.github.com/3279194

UPDATE: Dies ist jetzt ein Juwel: http://rubygems.org/gems/nav_link_to

2
Dan Tello

Diese Version basiert auf @ Skilldricks Version, ermöglicht jedoch das Hinzufügen von HTML-Inhalten.

So können Sie tun:

nav_link "A Page", a_page_path

aber auch:

nav_link a_page_path do
  <strong>A Page</strong>
end

oder einen beliebigen anderen HTML-Inhalt (Sie können beispielsweise ein Symbol hinzufügen).

Hier ist der Helfer:

  def nav_link(name = nil, options = nil, html_options = nil, &block)
    html_options, options, name = options, name, block if block_given?
    options ||= {}

    html_options = convert_options_to_data_attributes(options, html_options)

    url = url_for(options)
    html_options['href'] ||= url

    class_name = current_page?(url) ? 'current' : ''
    content_tag(:li, :class => class_name) do  
      content_tag(:a, name || url, html_options, &block)
    end
  end

Entsprechend der Antwort von Skilldrick werde ich es folgendermaßen ändern:

def nav_link(*args, &block)
  is_active = current_page?(args[0]) || current_page?(args[1])
  class_name = is_active ? 'active' : nil

  content_tag(:li, class: class_name) do
    link_to *args, &block
  end
end

um es viel nützlicher zu machen.

1
Tom Chen

Ich denke, ich habe eine einfache Lösung gefunden, die für viele Anwendungsfälle hilfreich sein könnte. Das lässt mich:

  • Unterstützt nicht nur Klartext, sondern auch HTML in link_to (z. B. Hinzufügen eines Symbols innerhalb des Links)
  • Fügen Sie nur wenige Codezeilen zu application_helper.rb hinzu.
  • Hängen Sie active an den gesamten Klassennamen des Linkelements an, anstatt dass es die einzige Klasse ist.

Fügen Sie dies also zu application_helper.rb: .__ hinzu.

def active_class?(class_name = nil, path)
  class_name ||= ""
  class_name += " active" if current_page?(path)
  class_name.strip!
  return class_name
end

Und auf Ihrer Vorlage können Sie Folgendes haben:

<div class="col-xs-3">
  <%= link_to root_path, :class => active_class?("btn btn-outline-primary", root_path) do %>
    <i class="fa fa-list-alt fa-fw"></i>
  <% end %>
</div>

Als bonus können Sie einen class_name angeben oder nicht verwenden und wie folgt verwenden: <div class="<%= current_page?(root_path) %>">

Dank vorheriger Antworten 1 , 2 und Ressourcen .

1

So löste ich in meinem aktuellen Projekt.

def class_if_current_page(current_page = {}, *my_class)
    if current_page?(current_page)
      my_class.each do |klass|
        "#{klass} "
      end
    end
  end

Dann..

li = link_to company_path 
    class: %w{ class_if_current_page( { status: "pending" }, "active" ), "company" } do  
      Current Company
0
GN.

Mein leichter Weg - 

application.html.erb,

<div class="navbar">
    <div class="<%= @menu1_current %> first-item"><a href="/menu1"> MENU1 </a></div>
    <div class="<%= @menu2_current %>"><a href="/menu2"> MENU2 </a></div>
    <div class="<%= @menu3_current %>"><a href="/menu3"> MENU3 </a></div>
    <div class="<%= @menu4_current %> last-item"><a href="/menu4"> MENU4 </a></div>
</div>

main_controller.erb,

class MainController < ApplicationController
    def menu1
        @menu1_current = "current"
    end

    def menu2
        @menu2_current = "current"
    end

    def menu3
        @menu3_current = "current"
    end

    def menu4
        @menu4_current = "current"
    end
end

Vielen Dank.

0
Lwin Htoo Ko

Wenn Sie auch HTML-Optionen-Hash in der Ansicht unterstützen möchten. Wenn Sie es beispielsweise mit einer anderen CSS-Klasse oder -ID aufrufen möchten, können Sie die Hilfsfunktion wie folgt definieren.

def nav_link_to(text, url, options = {})
  options[:class] ||= ""
  options[:class] += " active"
  options[:class].strip!
  link_to text, url, options
end

Rufen Sie diesen Helfer in der Ansicht auf die gleiche Weise auf, wie Sie link_to helper aufrufen würden

<%= nav_link_to "About", about_path, class: "my-css-class" %>
0
Ken Hibino

Erstellen Sie eine Methode in ApplicationHelper wie folgt.

def active controllers, action_names = nil
  class_name = controllers.split(",").any? { |c| controller.controller_name == c.strip } ? "active" : ""
  if class_name.present? && action_names.present?
    return action_names.split(",").any? { |an| controller.action_name == an.strip } ? "active" : ""
  end
  class_name
end

Verwenden Sie es jetzt als Ansicht unter Anwendungsfällen.

1. Für alle Aktionen eines bestimmten Controllers

<li class="<%= active('controller_name')%>">
....
</li>

2. Für alle Aktionen vieler Controller (mit Komma getrennt)

<li class="<%= active('controller_name1,controller_name2')%>">
....
</li>

3. Für spezifische Aktionen eines bestimmten Controllers

<li class="<%= active('controller_name', 'action_name')%>">
....
</li>

4. Für spezifische Aktionen vieler Controller (mit Komma getrennt)

<li class="<%= active('controller_name1,controller_name2', 'action_name')%>">
....
</li>

5. Für einige spezifische Aktionen eines bestimmten Controllers

<li class="<%= active('controller_name', 'index, show')%>">
....
</li>

6. Für einige spezifische Aktionen vieler Controller (mit Komma getrennt)

<li class="<%= active('controller_name1,controller_name2', 'index, show')%>">
....
</li>

Ich hoffe es hilft

0
Lalit Kumar

alle diese Funktionen arbeiten mit einfachen Navigationsleisten, aber was ist mit dem Dropdown-Untermenü? Wenn ein Untermenü ausgewählt wird, sollte der oberste Menüpunkt als "aktuell" bezeichnet werden. In diesem Fall ist tabs_on_Rails die Lösung

0
user762579