2009-11-17 3 views
10

J'ai une liste d'onglets en haut de mon application que j'inclue dans une présentation générale dans application.html.erb. Ils ressemblent à ceci:Modification de l'onglet actuel dans les 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> 

Je souhaite modifier l'onglet sélectionné dans le « courant » un, quand je frappe cette page. Alors, quand je clique sur Modifier le profil et la page se charge Modifier le profil, les onglets devraient apparaître comme suit:

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

Est-il possible de le faire en dehors de l'ajout javascript sur la page qui est affichée? Ou s'il y a ce qui est généralement la meilleure pratique pour le faire de la manière la plus sèche possible.

Merci

Répondre

11

Vous pouvez utiliser controller.class == et controller.action_name == pour savoir exactement quel contrôleur et l'action que vous êtes sur

il serait quelque chose comme

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

Je crois qu'il ya des façons d'obtenir l'URL actuelle pour la page que vous utilisez, mais votre style "actif" ne dépendra que de l'accès à cette action via ce chemin, ce qui peut ne pas toujours être le cas en fonction des routes, de cette façon, la vue montrera ce qui est vrai basé sur ce qui a été réellement exécuté, pas ce que l'URL est dans la barre d'adresse

+0

Ahh merci.Ce controller.action_name est exactement ce dont j'avais besoin.Je vais donner à celui-ci un chèque depuis sa solution finale, mais je souhaite que je –

+0

Bon travail, danivo – kafuchau

0

Lorsque vous changez de page, vous pouvez passer quelque chose comme @current_tab revenir à la erb des méthodes de régulation. Ensuite, utilisez @current_tab pour décider quel li devrait être la classe actuelle. Alternativement, vous pouvez donner chaque li et id ou un attribut unique et simplement changer la classe avec votre cadre JavaScript de votre choix.

0

Je suis donc pas invoquaient c'est la meilleure façon de le faire, mais je suis assez courageux pour poster ce que je suis venu avec :)

Quelques exemples des liens de menu de ma mise en page:

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

Puis j'ai créé cette aide:

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- Merci pour votre réponse. Question rapide: Où arrivez-vous avec controller_name et action_name utilisés pour les comparaisons? Merci. –

+0

http://api.rubyonrails.org/classes/ActionController/Base.html - Mettez cette méthode dans votre ApplicationHelper et cela fonctionnera. Rien à l'encontre des autres réponses, mais une fois que vous les essayez, donnez un coup de feu, c'est un peu plus DRY IMO - conserve toute la logique à un endroit au lieu de chaque élément de menu qui garde la vue propre. –

6

Vous pouvez essayer quelque chose comme:

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

... et vérifiez de quel contrôleur vous venez.

+0

KChau- Merci pour cette réponse. Cela a du sens intuitivement, mais que se passe-t-il si deux onglets proviennent du même contrôleur? Je ne pense pas qu'il existe une méthode controller.controller_action, alors où allons-nous? –

+0

Pour les onglets provenant du même contrôleur, pour ceux spécifiques, vous pouvez simplement renvoyer une valeur @current à la vue. Je ne peux pas penser à une façon plus sèche de le faire du haut de ma tête. Si je le fais, je serai sûr de poster. – kafuchau

+0

Dave, si votre action est dans vos paramètres url, ou quelque chose qui identifie le chemin d'URL que vous venez, vous pouvez l'utiliser aussi dans la vue ... donc si vous connaissiez votre action depuis l'URL, vous pourriez faire quelque chose comme: li class = "<% = params [: action] == 'quoi'? ... et ainsi de suite – kafuchau

2

Vous pouvez simplement faire ceci:

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

J'ai fait une aide pour ce qui peut accepter un certain nombre d'arguments qui est utile pour les ressources imbriquées, mais il accepte aussi un seul nom de contrôleur, tout comme les autres réponses.

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

Ou

Exemple d'utilisation avec HAML & ressources imbriquée (sera actif pour l'un des noms de contrôleur fournis):

applcation.html.haml:

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

C'est une bonne astuce: j'ajoute "return nil" dans is_active pour m'assurer qu'il ne retourne rien pour les onglets inactifs. – Dingle

0

Je l'ai fait dans le aide de l'application et il semble fonctionner très bien:

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

appellent ensuite comme ceci:

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