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>
Related
I have the following bootstrap menu (pills) defined in a partial:
<ul class="nav nav-pills">
<li class="active">Home</li>
<li>Menu 1</li>
<li>Menu 2</li>
</ul>
Here are some sample routes:
get 'institute/:institute_id/students' => 'students#index' , as: 'students_of_institute'
get 'students/:student_id' => 'students#show'
I have referenced this partial in various views. How do I dynamically change the current active tab?
You'd have to check the current path and if it matches your link's add an active class to your li.
An easy way would be to compare params[:controller] and params[:action].
For example:
# GET /posts
params[:controller] => "posts"
params[:action] => "index"
Here is a "dirty" example. It's better to move it out to some helper:
<ul class="nav nav-pills">
<li class="<%= 'active' if params[:controller] == 'students' && params[:action] == 'index' %>"><%= link_to 'Students', students_path %></li>
</ul>
An alternative to #Uzbekjon's solution is to use the current_page? helper method. The first argument is the controller, the second (optional) is the action.
Since your navigation links will be top-level links, you will usually not need to specify the action. That way, you will still have an active pill for sub-pages in the same controller.
E.g:
<ul class="nav nav-pills">
<li class="<%= 'active' if current_page? controller: :students %>">
<%= link_to 'Students', students_path %>
</li>
</ul>
I think this is slightly more elegant.
I using gem https://github.com/seyhunak/twitter-bootstrap-rails/ and navbar helpers from them to build header.
For ex. i have a users link in my header. And if current url is '/users', users link sets active and highlighted correcrly. But if current url is '/users?top10=true', users link did not set active. Is there right behavior? Because html page for '/users' and /users?top10=true' is the same page with different content.
Is there bug or feature?
Bootstrap will only consider link as active if and only if path will match with href's value. It don't have support for query strings yet. You can use following code options to make links active/non-active with custom code:
<ul class="nav">
<li class="<%= 'active' if controller_name == 'controller1' %>">
<%= link_to "Link1", "/link1" %>
</li>
<li class="<%= 'active' if controller_name == 'controller2' %>">
<%= link_to "Link2", "/link2" %>
</li>
<li class="<%= 'active' if controller_name == 'controller3' %>">
<%= link_to "Link3", "/link3" %>
</li>
</ul>
Or you can use jQuery:
var url = window.location;
$('ul.nav a').filter(function() {
return this.href == url;
}).parent().addClass('active');
in the bootstrap navigation bar. You can get the effect of a button being clicked by adding the class active . Naturally, I want to use this on my pages. For example if I'm on the about us page I want the about us button clicked.
What is the best way to go about this? I was going to go to each page and at the bottom have a jQuery function add the class active to it. Is there a better way?
Read about current_page? here
You can add a method for handle logic with current_page?, example a method :
module ApplicationHelper
def active_class(link_path)
current_page?(link_path) ? "active" : ""
end
end
example bootstrap navbar template
<div class="navbar">
<div class="navbar-inner">
<a class="brand" href="#">Title</a>
<ul class="nav">
<li class="active">Home</li>
<li>Link</li>
<li>Link</li>
</ul>
</div>
</div>
So, on view looks like
HTML
<li class="<%= active_class(some_path) %>">
<%= link_to "text of link", some_path %>
</li>
HAML
%li{:class => active_class(some_path)}
= link_to "text of link", some_path
Or you can use request.fullpath to get current full of path if a current path have a parameter
example
<ul>
<% Contry.all.each do |c| %>
<li class="snavitem <%= active_class(contry_path(c)) %>">
<%= link_to "show #{c.name}", contry_path(c) %>
</li>
<% end %>
</ul>
and on your application_helper.rb
def active_class(link_path)
request.fullpath == link_path ? "active" : ""
end
read about request.fullpath here
in my opinion, a cleaner way to achieve that is to write a link_to_in_li method in application_helper.rb:
def link_to_in_li(body, url, html_options = {})
active = "active" if current_page?(url)
content_tag :li, class: active do
link_to body, url, html_options
end
end
then use it this way
<%= link_to_in_li "Home", root_path, id: "home_link" %>
I find the code inside li a little difficult to read.
For anyone having trouble making sense of this, here is an example with my paths and filenames laid out explicitly. As a pretty new person to rails, I was having trouble figuring it out. Thanks to the other people who answered above, as it helped me figure it out!
I placed the Bootstrap navbar in my application.html.erb file:
<div class="navbar-header">
<a class="navbar-brand" href="/">Mapper</a>
<ul class="nav navbar-nav">
<li class="<%= is_active?('/') %>"><%= link_to "Home", '/' %></li>
<li class="<%= is_active?('/main/map') %>"><%= link_to "Map", '/main/map' %></li>
<li class="<%= is_active?('/main/about') %>"><%= link_to "About", '/main/about' %></li>
</ul>
</div>
This goes in the application_helper.rb file:
module ApplicationHelper
def is_active?(link_path)
current_page?(link_path) ? "active" : ""
end
end
That's it! Now your application will dynamically add the 'active' class to whatever page is currently being viewed (i.e. it's corresponding list item in the navbar). This is much simpler (and more DRY) than adding the navbar manually to each page (view) and then updating the 'active' class.
I'll post my answer that I created based on these others because in case of CRUD views the active class wasn't been placed.
module ApplicationHelper
def active_class(name)
controller_name.eql?(name) || current_page?(name) ? 'active' : ''
end
end
My views use something like this:
<ul class="nav navbar-nav">
<li class="nav-item <%= active_class('/') %>">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item <%= active_class('leads') %>">
<a class="nav-link" href="/leads">Leads</a>
</li>
</ul>
<ul class="nav navbar-nav pull-right <%= active_class(edit_user_registration_path) %>">
<li class="nav-item ">
<a class="nav-link" href="/users/edit">Perfil</a>
</li>
<li class="nav-item">
<%= link_to('Sair', destroy_user_session_path, method: :delete) %>
</li>
</ul>
Please try this in each page, check the cotroller or action and add the css
For example:
<li class= <%= (controller.controller_name.eql?('pages') && controller.action_name.eql?('index') )? 'active':''%> ><%= link_to 'my page', pages_path%></li>
You may define a helper method in application_helper.rb
def create_link(text, path)
class_name = current_page?(path) ? 'active' : ''
content_tag(:li, class: class_name) do
link_to text, path
end
end
Now you can use like:
create_link 'xyz', any_path which would render as <li class="active">xyz</li>
Perfect for bootstrap navigation!
Why limit yourself to only li elements? And why not support multiple class names along with active? This solution lets me:
Support not only plain text but HTML inside link_to (e.g. add an icon inside the link)
Add just few lines of code to application_helper.rb
Append active to the whole class name of the link element instead of it being the sole class.
So, add this to application_helper.rb:
def active_class?(class_name = nil, path)
class_name ||= ""
class_name += " active" if current_page?(path)
class_name.strip!
return class_name
end
And on your template you can have something like this:
<div class="col-xs-3">
<%= link_to root_path, :class => active_class?("btn btn-outline-primary", root_path) do %>
<i class="fa fa-list-alt fa-fw"></i>
<% end %>
</div>
You can also specify or not a class_name and use it like this:
<li class="<%= active_class?(root_path) %>">Home</li>
Thanks to previous answers 1, 2 and resources.
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 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.