We've moved discussions to Discord

Setting active nav links / menus

Seth Cox
New to rails in general and Jumpstart in particular. Is there existing functionality in Jumpstart for me to use to set active states on my navigation items/menus. I haven't learned Javascript yet, so I'm a bit lost in this department.
John Chambers
Hi Seth Cox ,

Yes there's a helper built in to JSP for this. You can add your own tailwind classes.

You can do this if it's only one path:

<%= nav_link_to products_path, class: "rounded-md py-2 px-3 text-sm leading-5 font-medium text-white focus:outline-none focus:bg-light-blue-800 transition duration-150 ease-in-out", inactive_class: "hover:bg-light-blue-800", active_class: 'bg-black bg-opacity-25' %>

Or this for multiple paths:

<%= nav_link_to products_path, class: "rounded-md py-2 px-3 text-sm leading-5 font-medium text-white focus:outline-none focus:bg-light-blue-800 transition duration-150 ease-in-out", inactive_class: "hover:bg-light-blue-800", active_class: 'bg-black bg-opacity-25', starts_with: ["/search", "/listings"] %>

 
Oh interesting! Thanks  John Chambers !
John Chambers One clarifying question: How would you recommend adding a menu icon with this method so that the text and icon are linkable? I typically do something like below, but I noticed that isn't compatible with the nav_link_to helper. Thank for you help!

<%= link_to products_path, class: "some-class" do %>
<i>Icon</i>
<p>Products</p>
<% end %>

John Chambers
Hey Seth Cox I created my own helper method for this.

Won't lie it's ugly!
I'm sure there's a way to refactor the original method to work with blocks too


def nav_block_link_to(name = nil, options = nil, html_options = nil, &block)
    
    html_options, options, name = options, name, block if block_given?
    options ||= {}
    

    ###

    html_options[:class] = Array.wrap(html_options[:class])
    active_class = html_options.delete(:active_class) || "active"
    inactive_class = html_options.delete(:inactive_class) || ""

    active = if (paths = Array.wrap(html_options[:starts_with])) && paths.present?
      paths.any? { |path| request.path.start_with?(path) }
    else
      # request.path == path
      request.path == options
    end

    classes = active ? active_class : inactive_class
    html_options[:class] << classes

    ###
    
    html_options = convert_options_to_data_attributes(options, html_options)


    url = url_for(options)
    html_options["href"] ||= url

    content_tag("a", name || url, html_options, &block)
    
  end


Then just use it like this and put and html, images or svgs inside the block

<%= nav_block_link_to contacts_path, class: "rounded-md py-2 px-3 text-sm leading-5 font-medium text-white focus:outline-none focus:bg-light-blue-800 transition duration-150 ease-in-out ml-4", inactive_class: "hover:bg-light-blue-800", active_class: 'bg-black bg-opacity-25' do %>
		<svg class="w-5 h-5 inline mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path></svg>
		Contacts
	<% end %>


Notifications
You’re not receiving notifications from this thread.