I have a rails app using a ul as a toolbar. I want to have a style (selected) to apply to the page the user is on.
How can I do that?
This is what I have so far, but the selected style is hard coded and I'm also not sure how to know what page is selected.
<ul>
<li class="firstItem"><%= link_to "About", '/about' %></li>
<li class="item"><%= link_to "Page1", '/page1' %></li>
<li class="item selected" <%= link_to "Page2", '/page2' %></li>
<li class="item"><%= link_to "Contact", '/contact' %></li>
<li class="lastItem"><%= link_to "Blog", '/blog' %></li>
</ul>
I agree totally with Jarrod's advice, but just in case you encounter the need to process additional conditions (and want to avoid ugly embedded ruby in your HTML code), take a look at Rails' content_tag method.
With it, you can replace something like:
<li class=<%= #post.active? ? 'active' : 'suspended' %>>
<%= link_to #post.name, post_path(#post) %>
</li>
With something like:
<%= content_tag :li, link_to(#post.name, post_path(#post), :class => #post.active? ? 'active' : 'suspended' %>
And of course, sticking this code into a helper and calling it from there will earn you more elegance-points.
Hope this helps.
PS: This is my first post on Stackoverflow, please be gentle. :)
if each li is linked to different controller you can use controller_name to add or not the selected class
Here is an example from my app, it's in haml
%ul
%li
%a{:href => '/kebabs', :class => ('current' if controller_name == 'kebabs')} Admin kebabs
%li
%a{:href => '/statistics', :class => ('current' if controller_name == 'statistics')} Statistiques
%li
%a{:href => '/people', :class => ('current' if controller_name == 'people')} Admin Personnes
cheers
You can also use css for this. Give each the body each page a class and id from your controller and action names.
<body class="<%= controller.controller_name %>" id="<%= controller.action_name %>">
Then give your ul and li elements an id.
<ul id="nav'>
<li id="about"></li>
<li id="contact"></li>
<li id="blog"></li>
</ul>
Now you can reference a specific link on a specific page from your stylesheet.
body.blog#index ul#nav a#blog:link
So if you want to make section links 'sticky' you can reference them all at once, leaving out the body id.
body.blog ul#nav a#blog:link,
body.contact ul#nav a#contact:link {
background-color: red;
}
Check out more on CSS selectors.
Related
I'm trying to create a navbar that highlights the li item on which page I am.
In my code below I'm trying to use a conditional operator to see if the current path is correct. Or at least that's what I think i'm doing.
<li id="home-link" data-hook class="<%= root_path ? "active" : "" %>"><%= link_to Spree.t(:Home), spree.root_path %></li>
<% if spree_current_user %>
<li id="home-link" data-hook class="<%= products_path ? "active" : "" %>" ><%= link_to Spree.t(:products), spree.products_path %></li>
<% end %>
What I then expect to happen is that if i'm on the home page the li get's the class active,
what currently happens is that all li items get the class active.
How can I check the current path?
No, you are testing if the path helpers are true, and they are as they return a String. That's why active is always set.
Take a look at current_page?:
<% product_active = 'active' if current_page?(controller: 'products', action: 'index') %>
<li id="home-link" data-hook class="<%= product_active %>">
EDIT: As #NensiMakawana suggets, you can alternatively use the active_link_to gem.
Following a previous post I (almost) successfully implemented highlighted navigation using CSS and Rails.
<ul class="nav">
<li class="<%= "active" if params[:controller] == "sweets" %>"><%= link_to 'Sweets', sweets_path %> </li>
<li class="<%= "active" if params[:controller] == "sweets/new" %>"><%= link_to 'New Sweets', new_sweets_path %> </li>
<li class="<%= "active" if params[:controller] == "tasks" %>"><%= link_to 'Tasks', tasks_path %> </li>'Customers', customers_path %> </li>
<li class="<%= "active" if params[:controller] == "suppliers" %>"><%= link_to 'Suppliers', suppliers_path %> </li>
</ul>
The only issue is that one of my navigational items is for creating a new item rather than being to an entirely different page. I have tried the above using /new on the end of the normal controller text but it hasn't worked.
Is this method possible when navigating to the method pages or do I need to implement it in a different way? Sorry if this is a repeat question but I couldn't find anyone with the same situation.
Thanks in advance and any hints or tips are always welcome.
You can check for action as well:
if params[:action] == 'some_action'
I followed the basic railscast for using Twitter Bootstrap in Rails application. Everything was great, until I had to push to heroku, then I had some problems with pg gem, and I had to rake assets:precompile to push it ok. Finally I solved.
Now, I'm trying to use pills in my application, I have copy/paste from documentation and changed the url in href :)
<div class="container">
<div class="row">
<div class="span3">
<p> Lorem Ipsum</p>
</div>
<div class="span9">
<ul class="nav nav-pills">
<li class="active">Home</li>
<li>Products</li>
<li>Categories</li>
</ul>
</div>
</div>
</div>
When I push one of the links, I'm redirected to the right url but the selected option doesn't change to class="active". I don't know why... I thought it was the javascript but hover property works ok... I mean, when the mouse is over an option (diferent from active) its style changes ok.
I tried rake assets:clean, but no change is made
Thanks
You actually have to handle this by yourself!
Your list should look something like
<li class="<%= 'active' if params[:controller] == 'yourdefaultcontroller' %>">Home</li>
<li class="<%= 'active' if params[:controller] == 'products' %>">Products</li>
<li class="<%= 'active' if params[:controller] == 'categories' %>">Categories</li>
You need to specify in each request which tab is the active one. You can do this by relying on the name of the controller (and action if need be) that is passed in the params hash.
You can use something like this:
<li class="<%= 'active' if current_page?(root_path) %>"><%= link_to "Home", root_path %></li>
<li class="<%= 'active' if current_page?(about_path) %>"><%= link_to "About", about_path %></li>
<li class="<%= 'active' if current_page?(contact_path) %>"><%= link_to "Contact", contact_path %></li>
I used a helper to implement this in the style of Rails' form helpers.
In a helper (e.g. app/helpers/ApplicationHelper.rb):
def nav_bar
content_tag(:ul, class: "nav navbar-nav") do
yield
end
end
def nav_link(text, path)
options = current_page?(path) ? { class: "active" } : {}
content_tag(:li, options) do
link_to text, path
end
end
Then, in a view (e.g. app/views/layouts/application.html.erb):
<%= nav_bar do %>
<%= nav_link 'Home', root_path %>
<%= nav_link 'Posts', posts_path %>
<%= nav_link 'Users', users_path %>
<% end %>
This example produces (when on the 'users' page):
<ul class="nav navbar-nav">
<li>Home</li>
<li>Posts</li>
<li class="active">Users</li>
</ul>
I have a ul filled with links in my layout/application.html.erb and want the current location link be marked with class="active".
Now I'm using:
<%= link_to 'About Us', { :controller => 'aboutus' }, :class => "menu#{' active' if params[:controller] == 'aboutus'}" %>
But it looks pretty nasty to me.
Anyone has a better idea?
The link_to_unless_current method doesn't actually create a link, nor does it add a class of active. If you'd still like to do that, you can use the current_page method to check if the current page matches the route you specified:
<ul id="main_nav">
<li><%= link_to "Search", search_path, :class => ('active' if current_page?(search_path)) %></li>
</ul>
Or if you'd like to add the class on the wrapping element:
<li class="<%= 'active' if current_page?(search_path) %>">
<%= link_to "Search", search_path %>
</li>
You can use the helper method similar to link_to
its called "link_to_unless_current".
http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html ( find the details here )
HTH
An example for a root path with a li tag, i tried to do it with a content_tag, but no luck for the if case in a elegant way
<li<%= " class='active'".html_safe if current_page?(root_path) %>>
<%= link_to "Home", root_path %>
</li>
i have some issues when i keep the class in blank with bootstrap(if i remember well)
I have a list of tabs at the top of my application that I include in a general layout in application.html.erb. They look like this:
<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>
I want to change the selected tab to the "current" one, when I hit that page. So when I click Edit Profile and the Edit Profile page loads, the tabs should appear as follows:
<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>
Is there a way to do this outside of adding javascript to the page which is displayed? Or if there is what is generally best practice for doing this in the DRYest way possible.
Thanks
You can use controller.class == and controller.action_name == to figure out exactly which controller and action you are on
so it would be something like
<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>
I believe there are some ways to get the current url for the page you are on, but then your "active" styling will be dependent on only getting to that action via that path, which may not always be the case depending on the routes, this way will ensure the view shows what is true based on what was actually run, not what the url is in the address bar
You could try something like:
<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>
...and just check which controller you're coming from.
Take a look at TabsOnRails
You could just do this:
<%= current_page?(:controller => 'your_controller', :action => 'index') ? 'current' : '' %>
I made a helper for this that can accept any number of arguments which is useful for nested resources, but it also accepts a single controller name just like the other answers.
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>
Or
Example usage with HAML & nested resource(will be active for any of the provided controller names):
applcation.html.haml:
%li{:class => is_active('blogs', 'comments')}
When you switch pages you could pass something like #current_tab back to the erb from the controller methods. Then use #current_tab to decide which li should be the current class. Alternatively, you could give each li and id or some unique attribute and simply change the class with your JavaScript framework of choice.
I'm so not claiming this is the best way to do this, however I am brave enough to post what I came up with :)
Some example menu links from my layout:
<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>
Then I created this 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
I did this in the application helper and it seems to work fine:
def current_page(path)
"active" if current_page?(path)
end
Then call like this:
<li class="<%= current_page(root_path)%>"> <%= link_to "Home", root_path %></li>