I needed to underline the active menu item for a submenu. I found I could use the following in my menu. I could do that by applying class:
<li><%= link_to "* RFQ", rfq_path(1), class: get_rfqs_class() %></li>
and have a helper item of
def get_rfqs_class
if controller_name == 'rfqs'
return 'active'
end
end
I have a get_xxx_class() for each item and a corresponding helper.
That works great. However, I needed to do a little different link_to for another menu item
<li> <%= link_to "Pre Production Meeting", controller:
'pre_production_meetings', action: 'show', id: 1 ,
op_id: $current_opportunity, class: get_pre_production_meetings_class() %> </li>
The problem is that the different link_to format results in the underline not showing. If I do an inspect, it does show the class as active but I don't see the underline
Pre Production Meeting
I tried using divs and spans with the following code but had no luck.
<% if controller_name == 'pre_production_meetings' then %>
<li> <%= link_to "Pre Production Meeting", controller: 'pre_production_meetings', action: 'show', id: 1 , op_id: $current_opportunity, class: get_pre_production_meetings_class() %> </li>
<% else %>
<li> <%= link_to "Pre Production Meeting", controller: 'pre_production_meetings', action: 'show', id: 1 , op_id: $current_opportunity %></li>
<% end %>
Is there something where using a link_to to a controller/action the way I did will prevent the class from being properly applied?
Also, I inspected the styles for a menu item that was working as expected
ul.art-hmenu>li>a.active {
padding: 0 12px;
margin: 0 auto;
color: #145366;
text-decoration: underline;
}
If I inspect the pre production meetings style, I don't see the a.active but see a.hover
ul.art-hmenu>li>a:hover, .desktop ul.art-hmenu>li:hover>a {
color: #000000;
text-decoration: none;
}
If I change the text-decoration to underline, then I see the underlining as expected.
That instance of link_to uses this format:
link_to(body, url_options = {}, html_options = {})
You need to surround your url options in curly braces so the link looks like this:
<a href="/pre_production_meetings/1" class="active">
Your class has been embeded into the url rather than the html.
This should solve your problem:
<%= link_to "Pre Production Meeting",
{controller: 'pre_production_meetings', action: 'show', id: 1 ,
op_id: #current_opportunity},
class: get_pre_production_meetings_class() %>
Also, the $ is probably a typo. I'm assuming it is an #.
I'm trying to style links with Rails' link_to helper and Bootstrap CSS styles.
Here's one of my links:
<%= link_to 'Home', controller: 'welcome', :class => "btn btn-primary" %>
The style gets applied to the link, however the url that link_to generates has the css class as a parameter in it, suggesting I'm doing something wrong, like this:
/welcome/index?class=btn+btn-primary
Why is this happening and is there a better way to apply css styles to links?
Try this
<%= link_to "Home", controller: "welcome", action: "your_action", :class => "btn btn-primary" %>
OR
<%= link_to "Home", welcome_path, :class => "btn btn-primary" %>
The class should be in html_options encapsulated between curly braces:
link_to(body, url, html_options = {})
Try
<%= link_to 'Home', controller: 'welcome', {:class => "btn btn-primary"} %>
I have a rails app with bootstrap 3, and the menu is not collapsing. Also when I resize sometimes the three bars show up for the collapse menu but the normal menu items are still there just squeezed together next to it. Here is the haml thanks in advance.
%nav.navbar.navbar-inverse{role: 'navigation' }
%div.container-fluid
%div.navbar-header
%button.navbar-toggle{type: 'button', 'data-toggle' => 'collapse', id: 'menu-toggler', 'data-target' => '.navbar-collapse'}
%span.icon-bar
%span.icon-bar
%span.icon-bar
= link_to (image_tag 'logo.png', class: 'logo'), root_path, class: 'navbar-brand', 'data-no-turbolink' => true
%div.collapse.navbar-collapse
%ul.nav.navbar-nav.navbar-right
%li.active= link_to '<i class="icon-dashboard"></i> Dashboard'.html_safe, root_path, 'data-no-turbolink' => true
%li= link_to '<i class="icon-signout"></i> Logout'.html_safe, destroy_user_session_path, method: :delete
%li= link_to '<i class="icon-envelope"></i> Contact Us'.html_safe, new_contact_request_path
%li.dropdown
%a.dropdown-toggle{href: '#', 'data-toggle' => 'dropdown'}
%i.icon-gears
Profile
%b.caret
%ul.dropdown-menu
%li= link_to 'Manage email addresses', emails_path
%li= link_to 'Edit Account', edit_user_registration_path
%li= link_to 'Setup Wizard', setup_wizard_home_index_path
%li= link_to 'Cancel Account', cancel_account_home_index_path
Did you add //= require bootstrap to your javascript manifest?
After looking through the bootstrap docs I ended up doing this. To get the drop down toggle to work. Still not sure why some of the menu will remain at a certain size and the dropdown option will show up along side.
$('#nav-toggle').click(function(){
$('.collapse').collapse({ toggle: false })
});
I am trying to get my nav-tabs styled and working properly. I believe I am not setting up the class="active" the correct way. It sets my first TAB/PAGE active by default, but when I click on either one of my other TABS/PAGES it still Highlights(background-color active) on my first TAB/Page.
How do I configure it to Highlight the active/clicked-on Tab?
This is what I have right now for my code:
<ul class="nav nav-tabs">
<li class="active"><%= link_to "Active Projects", projects_path %></li>
<li><%= link_to "Delinquent Projects", delinquent_projects_path %></li>
<li><%= link_to "Completed/Closed Projects", closed_projects_path %></li>
</ul>
Thanks
When rendering the navbar, you should check current path. If it's, say, "/users", then you highlight "Users" menu item and not others. If it's "/orders", you highlight "Orders". And so on.
Here's a little gem to do this work for you: active_link_to.
active_link_to 'Users', '/users'
# => Users
I think so you need to create a helper like
def active_link_to(text, link)
content_tag(:li, :class => request.fullpath == link ? 'active' : nil) do
link_to text, link
end
end
A simple solution is checking the controller param since every action would have the same active tab.
<li class=<%= params[:controller] == "users" ? "active": "" >
(I may have syntax errors since I'm getting rusty, specially with the quotes).
Every other solution listed here should work too.
GL & HF!
https://github.com/twg/active_link_to
gem 'active_link_to'
Then simplify your code to:
<ul class="nav nav-tabs">
<%= active_link_to "Active Projects", projects_path, :wrap_tag => :li %>
<%= active_link_to "Delinquent Projects", delinquent_projects_path, :wrap_tag => :li %>
<%= active_link_to "Completed/Closed Projects", closed_projects_path, :wrap_tag => :li %>
</ul>
Edit: Didn't notice answer above. At least here's an example :)
Basically, I have a lot of code that looks like this:
link_to t('.profile'), business_path(#business), class: '#{'active' if current_page? business_path(#business)}'
which isn't very DRY.
I was wondering if anyone knows a good way to modify the link_to helper itself to automatically add an 'active' class to all links to the current page.
If it helps, I'm open to using HAML or SLIM.
I wrote simple helper method using build in view helper current_page? when you can specify custom class name in html_options hash.
def active_link_to(name = nil, options = nil, html_options = nil, &block)
active_class = html_options[:active] || "active"
html_options.delete(:active)
html_options[:class] = "#{html_options[:class]} #{active_class}" if current_page?(options)
link_to(name, options, html_options, &block)
end
Examples (when you are on root_path route):
<%= active_link_to "Main", root_path %>
# Main
<%= active_link_to "Main", root_path, class: "bordered" %>
# Main
<%= active_link_to "Main", root_path, class: "bordered", active: "disabled" %>
# Main
I faced same requirement and here is my solution.
Create a method within ApplicationHelper
def active_class(link_path)
current_page?(link_path) ? "active" : ""
end
And inside your view:
<li class="<%= active_class('/') %>">
<%= link_to 'HOME', root_path %>
</li>
It's a solved problem, just use active_link_to gem. Your example simplifies to this:
= active_link_to t('.profile'), business_path(#business)
This is a good case for writing your own helper that wraps the link_to. In your application_helper.rb you can write a method active_link_to that takes the same params as link_to + current_page, and then just calls link_to like you are doing above.
as per rails 6.1 now we have helper for html class name
the helper example
class_names("foo", "bar")
# => "foo bar"
class_names({ foo: true, bar: false })
# => "foo"
class_names(nil, false, 123, "", "foo", { bar: true })
# => "123 foo bar"
you could use it like this
<%= link_to 'Home', root_path, class: class_names('nav-link', { active: current_page?(root_path) }) %>
it will produce html like this
<a class="nav-link active" href="/">Home</a>
the doc is here
Here's the helper I use. I add an optional "match_text" parameter for added flexibility (for instance, if I want to mark a link as active when the actual request path is a child page of the link's destination.)
def link_to_active(text, destination, options = {})
match_text = options.delete(:match_text)
classes = options[:class].present? ? options[:class].split(" ") : []
classes << "active" if request.fullpath.downcase == destination.downcase || (match_text && request.fullpath.downcase.include?(match_text.downcase))
options = options.except(:class)
options.merge!(:class => classes.join(" ")) unless classes.empty?
link_to(text, destination, options)
end
Great solution if you're using rails 6.1+.
Also works great when passing a block.
def active_link_to(text = nil, path = nil, **opts, &block)
link = block_given? ? text : path
opts[:class] = class_names(opts[:class], { active: current_page?(link) })
if block_given?
link_to link, opts, &block
else
link_to text, path, opts
end
end
I did the same that #egyamado. I needed to use AwesomeIcons too, so:
A helper:
def active_class?(link_path)
'active' if current_page?(link_path)
end
And it was my view:
<%= link_to my_controller_page_path,
:title => "My Controller Page",
:class => "other_name_class #{active_class?(my_controller_page_path)}" do %>
<i class="fa fa-fighter-jet"></i> My Controller Page
<%end%>
In another kind of Link, for example inside a Li.
#In this case I put a extra validation in root_path
<li class="nav-class <%=active_class?(my_controller_page_path)%> <%='active' if current_page?(root_path) %>">
<%= link_to my_controller_page_path,
:title => "Page 1",
:class => "other_name_class" do %>
Page 1
<%end%>
</li>
<li class="nav-class <%=active_class?(my_controller_page_2_path)%>">
<%= link_to my_controller_page_2_path,
:title => "Page 2",
:class => "other_name_class" do %>
Page 2
<%end%>
</li>
It worked for me.
This is my custom method to handle this issue.
def active_link_to(name = nil, options = nil, html_options = nil, &block)
if current_page?(options)
active_class = html_options[:active_class] ? html_options[:active_class] : 'has-text-danger'
html_options[:class] << "#{html_options[:class]} #{active_class}"
end
link_to(name, options, html_options, &block)
end
html_options[:active_class] is a custom hash.
Now I can dynamically change styles of my active link.
<%= active_link_to "Menu", root_path, class: 'has-text-dark', active_class: 'has-text-danger' %>
Here's a basic example from which you can expand:
module ApplicationHelper
def active_link_to(text, path, **opts, &block)
css_class = opts[:class]
case opts[:endpoint]
when String then css_class.concat(' active') if current_page? opts[:endpoint]
when Array then css_class.concat(' active') if opts[:endpoint].include? request.path
end
if block_given?
link_to path, class: css_class, &block
else
link_to text, path, class: css_class
end
end
end
# app/views/layout/_navbar.html.erb
# Using multiple endpoints
<%= active_link_to 'Home', root_path, class: 'some-class', endpoint: ['', '/', '/home'] %>
# Using a single endpoint
<%= active_link_to 'Admin', admin_path, class: 'some-class', endpoint: '/admin' %>
# Using a block
<%= active_link_to admin_path, class: 'some-class', endpoint: '/admin' do %>
<h1>Administration</h1>
<% end %>
nav.slim:
li class="nav-item"
= active_link_to 'Users', users_path, "nav-link"
application_helper.rb:
def active_link_to(title, path, class_css, options = {})
if current_page?(path)
class_css = "#{class_css} active"
options.merge!('aria-current': "page")
end
link_to title, path, class: class_css, **options
end
Use link_to_unless_current and then give it the look of an active link in CSS.