How do I get class='active' working properly? - css

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

Related

Select all font-awesome icons

I'm trying to make a navigation bar with bootstrap on ruby on rails using haml. I am making the nav bar responsive, using the hamburger menu. When the browser is smaller than 1040px, I'd like to make all the icons larger. Is there a way to select all the icons, or do I have to manually select all of the icons?
Here is the code (application.html.haml):
%body
%header
%nav.navbar.navbar-fixed-top{role: "navigation"}
.mobile
%div.navbar-brand
%i.fa.fa-bars.bars{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"}
= link_to "Recipeazy", root_path, style: "color: #696969;"
.collapse.navbar-collapse.navbar-collapse
%ul.navbar-nav.navbar-right
.navbar-items
- if user_signed_in?
%li.nav-item
= link_to "Home", root_path
%i.fa.fa-home
%li.nav-item
= link_to "About", about_path
%i.fa.fa-info-circle
%li.nav-item
= link_to "Settings", edit_user_registration_path
%i.fa.fa-cog
%li.nav-item
= link_to "New", new_post_path
%i.fa.fa-plus-circle
%li.nav-item
= link_to "Sign Out", destroy_user_session_path, method: :delete
%i.fa.fa-sign-out
- else
%li.nav-item
= link_to "Log In", new_user_session_path
%i.fa.fa-sign-in
%li.nav-item
= link_to "Sign Up", new_user_registration_path
%i.fa.fa-user-plus
I figured out the answer.
Basically you just add the class of the size you want the icon to be. You can find the sizes here.

Rails - Class not working for linkto to a controller/action

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

bootstrap 3 collapsable not working

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 })
});

Parsing erb within erb in a view. How to add CSS class?

I have a navbar, which is showing an unread messages count. The unread count has to go within the navbar text for formatting, so I have used the below:
<li><%= link_to "My Messages #{current_user.mailbox.receipts.where({:is_read => false}).count(:id, :distinct => true).to_s}", conversations_path, class: 'small button' %></li>
How do I add a class to the count? I want to add the bootstrap navbar-unread class.
I can put:
<span class='navbar-nav'><%= current_user.mailbox.receipts.where(:is_read => false).count(:id, :distinct => true).to_s %></span>
...outside the list but then the unread count is not in the right place.
Thanks for any help, can't find an answer anywhere, or at least a better way to do this.
EDITED:
The output I need from the html would look like this:
<li>
<a class="small button" href="/converssations/link">
My Messages<span class="navbar-unread">0</span>
</a>
</li>
So I need to pass a class into a span around the ruby that starts 'current_user.mailbox...etc
It's to show the number of unread messages, which is a small number in the corner of the button.
Maybe this can help you.
Look at ActionView Helpers reference also.
<%= link_to content_tag(:span, "My Messages #{current_user.mailbox.receipts.where({:is_read => false}).count(:id, :distinct => true).to_s}", class: "navbar-nav"), conversations_path, class: "small button" %>
will have output like this
<a class="small button" href="/converssations/link">
<span class="navbar-nav">My Messages Count</span>
</a>
To achieve your mentioned behavior you can pass a block to link_to like this
<%= link_to "#your_link", class: "small button" do %>
My Message <%= content_tag(:span, "1", class: "navbar-unread") %>
<% end %>

Add an 'active' class to all active links in rails?

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.

Resources