2009-11-17 12 views
10

Mam listę zakładek u góry mojej aplikacji, które umieszczam w ogólnym układzie w application.html.erb. Wyglądają tak:Zmiana bieżącej zakładki w szynach

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

Chcę zmienić wybraną zakładkę na "aktualną", kiedy trafię na tę stronę. Więc kiedy kliknij Edytuj profil i Edycja strony profilu obciążenia, zaczepy powinny wyglądać następująco:

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

Czy istnieje sposób, aby to zrobić poza dodaniem JavaScript do strony, która jest wyświetlana? Lub jeśli jest na ogół najlepsza praktyka do robienia tego w możliwie najdrobniejszy sposób.

Dzięki

Odpowiedz

11

Można użyć controller.class == i controller.action_name == aby dowiedzieć się dokładnie, który kontroler i działanie jesteś na

więc byłoby coś jak

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

Wierzę, że istnieje kilka sposobów, aby uzyskać bieżący adres URL na stronie, na której się znajdujesz, ale wtedy twoja "aktywna" stylizacja będzie zależała tylko od dotarcia do tej akcji przez tę ścieżkę, co nie zawsze musi mieć miejsce w zależności od trasy, w ten sposób zapewni, że widok pokazuje, co jest prawdą na podstawie co faktycznie zostało uruchomione, a nie jaki jest adres URL w pasku adresu

+0

Ahh dzięki.Ten kontroler.action_name jest dokładnie tym, czego potrzebowałem.Oddam ten jeden, ponieważ jest to ostateczne rozwiązanie, ale chciałbym może dać pół i pół. –

+0

Dobra robota, danivo – kafuchau

0

Po włączeniu strony można przekazać coś podobnego @current_tab powrotem do erb z metod kontrolera. Następnie użyj @ current_tab, aby zdecydować, która li powinna być bieżącą klasą. Alternatywnie możesz podać każdy li i id lub jakiś unikalny atrybut i po prostu zmienić klasę za pomocą wybranej przez siebie struktury JavaScript.

0

jestem tak nie twierdząc, jest to najlepszy sposób, aby to zrobić, ale jestem na tyle odważny, aby umieścić co wymyśliłem :)

Niektóre przykład linki z mojego menu Układ:

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

Potem stworzyliśmy pomocnika:

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- Dzięki za odpowiedź. Szybkie pytanie: Gdzie znajduje się nazwa kontrolera i nazwa_czynności używane do porównań? Dzięki. –

+0

http://api.rubyonrails.org/classes/ActionController/Base.html - Umieść tę metodę w aplikacji ApplicationHelper, a będzie działać. Nic przeciwko innym odpowiedziom, ale gdy raz spróbujesz, daj mi strzał, to trochę więcej DRY IMO - zachowuje całą logikę w jednym miejscu zamiast na każdym elemencie menu, który utrzymuje widok w czystości. –

6

można spróbować coś takiego:

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

... i po prostu sprawdź, z którego kontrolera pochodzisz.

+0

KChau- Dziękuję za tę odpowiedź. Ma to sens intuicyjny, ale co, jeśli dwie karty pochodzą z tego samego kontrolera? Nie sądzę, że istnieje metoda controller.controller_action, więc dokąd się udajemy? –

+0

W przypadku kart z tego samego kontrolera, dla tych konkretnych, możesz po prostu przekazać wartość @ current z powrotem do widoku. Nie mogę wymyślić bardziej suchy sposób, aby zrobić to z mojej głowy. Jeśli to zrobię, na pewno opublikuję. – kafuchau

+0

Dave, jeśli twoja akcja jest w twoich parametrach URL, lub coś, co identyfikuje twoją ścieżkę URL, z której pochodzisz, możesz użyć tego również w widoku ... więc jeśli znasz działanie z adresu URL możesz zrobić coś takiego: < li class = "<% = params [: akcja] ==" cokolwiek "? ... itd. – kafuchau

2

Można po prostu to zrobić:

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

Zrobiłem pomocnika na to, że może przyjąć dowolną liczbę argumentów, które jest przydatne dla zagnieżdżonych zasobów, ale również akceptuje jedna nazwa kontrolera, podobnie jak inne odpowiedzi.

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

lub

Przykład użycia z haml & zagnieżdżone zasobów (będzie aktywny dla każdego dostarczonego nazwami Controller):

applcation.html.haml:

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

To jest fajna sztuczka. Dodaję "return nil" wewnątrz is_active, aby upewnić się, że nic nie zwraca dla nieaktywnych kart. – Dingle

0

Zrobiłem to w pomocnik aplikacji i wydaje się działać prawidłowo:

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

Następnie nazwać tak:

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