2009-11-17 9 views
10

Tengo una lista de pestañas en la parte superior de mi aplicación que incluyo en un diseño general en application.html.erb. Son similares a esto:Cambiando pestaña actual en Rails

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

que quieren cambiar la pestaña seleccionada a la "corriente" uno, cuando llegué a esa página. Así que cuando hago clic en Editar perfil y se carga la página de edición del perfil, las pestañas debe aparecer como sigue:

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

¿Hay una manera de hacer esto fuera de añadir JavaScript a la página que se muestra? O si existe lo que generalmente es la mejor práctica para hacer esto de la manera más seca posible.

Gracias

Respuesta

11

Puede utilizar controller.class == y controller.action_name == de averiguar exactamente qué controlador y la acción que está en

por lo que sería algo así como

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

Creo que hay algunas maneras de obtener la url actual para la página en la que se encuentra, pero luego su estilo "activo" dependerá de que solo llegue a esa acción a través de esa ruta, lo que puede no ser siempre el caso dependiendo de las rutas, de esta manera se asegurará de que la vista muestre lo que es verdadero en función de lo que realmente se ejecutó, no cuál es la URL en la barra de direcciones

+0

Ahh, gracias. Este controlador.nombre_de_acción es exactamente lo que necesitaba. Le daré a este un cheque ya que es la solución final, pero me gustaría podría dar la mitad y la mitad. –

+0

Buen trabajo, danivo. – kafuchau

0

al cambiar de página que podría pasar algo así como @current_tab de nuevo a la erb de los métodos de controlador. Luego use @current_tab para decidir cuál li debería ser la clase actual. Alternativamente, puede dar cada li y id o algún atributo único y simplemente cambiar la clase con su marco de JavaScript de su elección.

0

estoy por lo no reclamar esta es la mejor manera de hacer esto, sin embargo estoy lo suficientemente valiente para publicar lo que me ocurrió con :)

Algunos ejemplos de los enlaces del menú de mi diseño:

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

Entonces creé este helper:

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

Andy- Gracias por su respuesta. Pregunta rápida: ¿De dónde vienen los nombres controller_name y action_name utilizados para las comparaciones? Gracias. –

+0

http://api.rubyonrails.org/classes/ActionController/Base.html - Coloque este método en su ApplicationHelper y funcionará. No hay nada en contra de las otras respuestas, pero una vez que las pruebes dale una oportunidad, es un poco más seco IMO - mantiene toda la lógica en un solo lugar en lugar de en cada elemento del menú que mantiene la vista limpia. –

6

Usted podría intentar algo como:

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

... y simplemente compruebe de qué controlador proviene.

+0

KChau- Gracias por esta respuesta. Tiene sentido de forma intuitiva, pero ¿qué pasa si dos pestañas provienen del mismo controlador? No creo que haya un método controller.controller_action, entonces, ¿a dónde vamos desde allí? –

+0

Para pestañas del mismo controlador, para aquellas específicas, es posible que desee pasar un valor de @current a la vista. No puedo pensar en una manera más SECA de hacerlo fuera de mi cabeza. Si lo hago, me aseguraré de publicar. – kafuchau

+0

Dave, si su acción está en sus parámetros de URL, o algo que identifique el camino de URL de donde vino, podría usar eso también en la vista ... así que si conoce su acción desde la URL, podría hacer algo como: < li class = "<% = params [: action] == 'whatever'? ... y así sucesivamente. – kafuchau

2

Se podía hacer esto:

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

hice un ayudante para este que puede aceptar cualquier número de argumentos que es útil para los recursos anidados, pero también acepta un solo nombre de controlador al igual que las otras respuestas.

aplicación 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> 

O

Ejemplo de uso con HAML & anidada recurso (será activo para cualquiera de los nombres de controlador proporcionadas):

applcation.html.haml:

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

Este es un buen truco. Estoy agregando "return nil" dentro de is_active para asegurarme de que no devuelva nada para las pestañas inactivas. – Dingle

0

Lo hice en el ayudante de aplicación y que parece funcionar bien:

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

Entonces llaman así:

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