Изменение текущей вкладки в Rails

У меня есть список вкладок в верхней части моего приложения, которые я включаю в общий макет в application.html.erb. Они выглядят так:

<li class="current"><%= link_to "Home", provider_path(current_user.id), :method=> "GET"%> </li>
            <li><%= link_to "Edit Profile", edit_student_path(current_user.id) %> </li>
            <li><%= link_to "Search", provider_search_path %> </li>

Я хочу изменить выбранную вкладку на "текущую", когда я нажму эту страницу. Поэтому, когда я нажимаю кнопку "Изменить профиль" и "Редактировать профиль", вкладки должны выглядеть следующим образом:

<li><%= link_to "Home", provider_path(current_user.id), :method=> "GET"%> </li>
 <li class="current"><%= link_to "Edit Profile", edit_student_path(current_user.id) %> </li>
  <li><%= link_to "Search", provider_search_path %> </li>

Есть ли способ сделать это за пределами добавления javascript на страницу, которая отображается? Или, если это вообще лучший способ сделать это с помощью DRYest.

Спасибо

Ответ 1

Вы можете использовать controller.class == и controller.action_name ==, чтобы точно определить, какой контроллер и какое действие вы используете

так что это будет что-то вроде

<li class="<%= controller.class == ProviderController and controller.action_name == 'show' ? 'current' : '' %>"><%= link_to "Home", provider_path(current_user.id), :method=> "GET"%> </li>
<li class="<%= controller.class == StudentController and controller.action_name == 'edit' ? 'current' : '' %>"><%= link_to "Edit Profile", edit_student_path(current_user.id) %> </li>
<li class="<%= controller.class == ProviderController and controller.action_name == 'search' ? 'current' : '' %>"><%= link_to "Search", provider_search_path %> </li>

Я считаю, что есть некоторые способы получить текущий url для страницы, на которой вы находитесь, но тогда ваш "активный" стиль будет зависеть только от того, чтобы попасть в это действие по этому пути, что может не всегда быть в зависимости от маршруты, таким образом, убедитесь, что представление показывает, что истинно, на основе того, что было фактически запущено, а не того, что URL-адрес находится в адресной строке.

Ответ 2

Вы можете попробовать что-то вроде:

<li class="<%= controller.controller_path == 'provider' ? 'current' : '' %>"><%= link_to "Home", provider_path(current_user.id), :method=> "GET"%> </li>
<li class="<%= controller.controller_path == 'student' ? 'current' : '' %>"><%= link_to "Edit Profile", edit_student_path(current_user.id) %> </li>
<li class="<%= controller.controller_path == 'search' ? 'current' : '' %>"><%= link_to "Search", provider_search_path %> </li>

... и просто проверьте, из какого контроллера вы пришли.

Ответ 4

Вы могли бы просто сделать это:

<%= current_page?(:controller => 'your_controller', :action => 'index') ? 'current' : '' %>

Ответ 5

Я сделал помощником для этого, который может принимать любое количество аргументов, которое полезно для вложенных ресурсов, но также принимает одно имя контроллера, как и другие ответы.

приложения helper.rb:

 def is_active(*links)  
   links.each { |link| return "active" if params[:controller] == link }
 end

application.html.erb

<li class="<%=is_active('home')%>">...</li>

Или

Пример использования с помощью HAML & вложенный ресурс (будет активен для любого из предоставленных имен контроллеров):

applcation.html.haml

%li{:class => is_active('blogs', 'comments')}

Ответ 6

При переключении страниц вы можете передать что-то вроде @current_tab обратно в erb из методов контроллера. Затем используйте @current_tab, чтобы решить, какой ли должен быть текущий класс. В качестве альтернативы вы можете предоставить каждый ли и id или какой-то уникальный атрибут и просто изменить класс с помощью вашей рамки JavaScript.

Ответ 7

Я так не утверждаю, что это лучший способ сделать это, однако я достаточно смел, чтобы опубликовать то, что я придумал:)

Некоторые примеры ссылок меню из моего макета:

<li class="nav-calendar"><%= menu_link_to 'teachers', 'show_date', 'Calendar', calendar_url  %></li>
<li class="nav-announcements"><%= menu_link_to 'announcements', nil, 'Announcements', announcements_path %></li>

Затем я создал этот помощник:

def menu_link_to(*args, &block)
  controller = args.shift
  action = args.shift

  if controller == controller_name && (action.nil? || action == action_name)
    if args.third.nil?
      args.push({:class => 'selected'})
    else
      args.third.merge!({:class => 'selected'})
    end
  end

  link_to *args, &block
end

Ответ 8

Я сделал это в помощнике приложения и, похоже, работает нормально:

def current_page(path)
  "active" if current_page?(path)
end

Затем назовите это:

<li class="<%= current_page(root_path)%>"> <%= link_to "Home", root_path %></li>