Rails menu link style depending on current page - ruby-on-rails

I have a simple navigation menu with plain html links that target different pages. All of these pages share this menu, which is separated out in a partial.
I would like to have the current page's link be highlighted in bold. A generic version of my (non-working) implementation looks like this:
# 'pagetwo' view
<%= render :partial => "shared/nav" %>
# partial
<%= link_to "Home", home_url, :id => "home" %>
<%= link_to "Page 1", pageone_url, :id => "pageone" %>
<%= link_to "Page 2", pagetwo_url, :id => "pagetwo" %>
Do I solve this with JavaScript?
The link_to_unless_current suggestion appears to be working. Does anyone know how to assign different CSS class to each outcome using this method?

Unless you need to change the boldness of the links between page requests (i.e. in response to client side events), you might look into using the block form of link_to_unless_current or, for a more general solution, look into current_page?
Another option might be adding classes to the body (or similar container element) based on your current page and then writing CSS rules to target links in specific contexts. For example:
body.home a#home_link { font-weight: bold }
body.about a#about_link { font-weight: bold }

Here is the solution I found, which is the most compact I have yet seen. It builds on the answer given by #thatothermitch (thank you and +1!).
I used link_to_unless_current for all the links, i.e.
# partial
<div id="manage_list"> # already surrounds the entire partial
<%= link_to_unless_current "Home", home_url, :id => "home" %>
<%= link_to_unless_current "Page 1", pageone_url, :id => "pageone" %>
<%= link_to_unless_current "Page 2", pagetwo_url, :id => "pagetwo" %>
</div>
I then added CSS styles that pick up on whether the <a> tag exists:
#manage_list p{ font-weight:bold; }
#manage_list p a{ font-weight:normal; }
This way, there is no need to pass any variables, write any javascript, or add any helper.
I hope this is helpful for any others who are experiencing the same problem. :)

You can do this a simple helper
In application helper put this
def set_selected(url_hash)
current_page?(url_hash) ? "current" : ""
end
Your links will call the helper to set the class name
<%= link_to "Home", home_url, :id => "home", :class => set_selected({:controller => 'homes', :action => 'index'}) %>
<%= link_to "Page 1", pageone_url, :id => "pageone", :class => set_selected({:controller => 'page_ones', :action => 'index'}) %>
CSS definition for the current class goes in the application.css or any other css file in your application
.current{
font-weight:bold;
}

Related

Rails link_to interpreting :class and :style as params for the :action?

Here is the offending line:
<p><%= link_to 'Job Type template', :action => :jt_template, :style => "color:white", :class => "btn btn-primary" %></p>
And when we load the page and inspect the element:
Job Type template
Why are my class and style tags being interpreted as params for the action?
Other than this weirdness - it's working as expected.
Just FWIW - the jt_template action sends the CSV file as a download. I was linking directly to the file stored in my public dir, but I found that when you clicked the button in Safari it would just open the CSV in the browser, and I'm forcefully required to make the file download instead (even though a user could get from the opened page)
EDIT:
Ever do that thing where you post to SO, then think of some new wording you haven't Googled, then find your answer on the first result?
Add css class to rails link_to helper
Someone go ahead and post the answer "you should put your :action inside { } and it will work" and I'll accept that.
Do this:
<p><%= link_to 'Job Type template', {:action => :jt_template}, :style => "color:white", :class => "btn btn-primary" %></p>
:action and :controller must be placed between { } in order to avoid the incorrect interpolation of stuff that comes after it (I only tried with :class and :style, but I assume it would affect anything that follows)

Ruby on Rails 3: AJAX call not refreshing div with link_to

I am new to Ruby on Rails and i am working through a few example applications in the O'Reilly Head First Rails book. In one of the examples there is a page made up of three partials. The middle partial is a list of items. There is a link right below this section that, when clicked, should refresh the div containing that partial. The book is running examples based off of Rails 2.3 i believe and i am using Rails 3.1. This is the example that the book is giving me:
routes.rb:
map.connect '/flights/:flight_id/seats', :action=>'flight_seats', :controller=>'seats'
seats_controller.rb:
def flight_seats
#flight = Flight.find(params[:flight_id])
render :partial => "flights/seat_list", :locals => {:seats => #flight.seats}
end
show.html.erb:
<div id="seats">
<%= render :partial=>"seat_list". :locals=>{:seats=>#flight.seats} %>
</div>
<$= link_to_remote("Refresh Seats", :url=>"/flights/#{#flight.id}/seats", method=>"get", :update=>"seats") %>
This example is also using prototype.js since that's what Rails 2.3 came with built in. Rails 3 has jQuery as the default JavaScript library. (not sure if that makes a big difference)
Here is what i have so far. This is getting the contents of the partial correctly, it's just not updating the "seats" div after the AJAX call gets the partial. My code:
routes.rb:
match 'flights/:flight_id/seats' => 'seats#flights_seats'
seats_controller.rb:
def flights_seats
#flight = Flight.find(params[:flight_id])
render :partial => "flights/seat_list", :locals => { :seats => #flight.seats }
end
show.html.erb:
<div id="seats">
<%= render :partial => 'seat_list', :locals => { :seats => #flight.seats } %>
</div>
<%= link_to "Refresh Seats", "/flights/#{#flight.id}/seats", :remote => true %>
Any idea why my <div id="seats"> won't refresh with the updated partial? I'm betting there is but i'll ask anyway, is something wrong with my code?
The :remote => true option is a bit weird if you aren't returning JSON data. You can wrap your HTML in a JSON object, though, which is what I typically do. Or if you want something closer to your existing code something like this should work for you:
<%= link_to "Refresh Seats", "/flights/#{#flight.id}/seats", :class => "refresh-seats" %>
In your javascript somewhere:
$(document).delegate(".refresh-seats", "click", function(e){
e.preventDefault();
$("#seats").load(this.href);
});

Disable link_to tag in Rails3+

I used the following code:
<%= link_to image_tag("edit.png", :alt => "Edit"), edit_user_path(user) %>
I want to disable this link and image, so I added :disabled=>true to the code, but it's not disabling. Why not, and how do I disable them?
I'm not sure what #lamrin wanted with this question, but I suppose that it is something like this:
<%= link_to_if condition?, image_tag("edit.png", :alt => "Edit"), edit_user_path(user) %>
With this code above, the image would have a link if the condition? is true
In my case this code below worked (a more complicated example):
link_to_unless disabled, (content_tag :div, "", :class => "vote " + vote_class, :title => title), resource_user_path({ :id => resuser.id, :resource_user => {:id => resuser.id, :resource_id => resource_id, :user_id => current_user_id, :vote => vote_value}}), :remote => true, :method => http_method
This link may also help with this approach:
http://railskey.wordpress.com/2012/07/19/rails-link_to-link_to_if-and-link_to_unless/
Unlike buttons, hyperlinks cannot be "disabled". You can do the following though, assuming you have jQuery included on your pages:
<%=link_to image_tag("edit.png", :alt=>"Edit"), edit_user_path(user), :id => "mylink" %>
Add the following Javascript to your page:
$('#mylink').click(function(e){
e.preventDefault();
});
In answer to your question, there is no :disabled option for the link_to helper in Rails, and it is not a valid attribute for a elements either. I believe the reason people tend to get confused with this in Rails is that ":disabled => true" does work IF you are using Bootstrap. So to fix this issue you can either follow Gupta's approach, or just add Bootstrap (which will give you some default CSS as well, so people don't get frustrated trying to click the link)!
Re: link_to method in rails: http://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to)
Re: the "disabled" attribute on a elements: Is 'disabled' a valid attribute for an anchor tag
Re: Bootstrap "disabled" class or attribute with bootstrap: http://getbootstrap.com/css/#anchor-element-1
1)One solution is to render just image_tag when you do not want link and use link_to when u want link to be click enabled. you can use instance variables to control what to render.
2) or use Javascript as suggested.
Use 2 if you want to dynamically do it.
You may use conditional link_to:
<%=
link_to_if(#current_user.nil?, "Login", { :controller => "sessions", :action => "new" }) do
link_to(#current_user.login, { :controller => "accounts", :action => "show", :id => #current_user })
end
%>

How to add a custom attribute to the HTML output of rails link_to

With rails version 2.3.8 I'm trying to get HTML output like:
Product list
So an A tag with a custom attribute "data-role". (The reason I want the "data-role" attribute is that I'm working with JQuery Mobile which picks up on this attribute and does its magic) So I was trying to do this
<%= link_to "product list", :controller => "product", :action => "list", "data-role" => "button" %>
Judging by this tutorial perhaps this would work in rails 3, but in rails 2.3.8 it interprets it by generating a data-role=button parameter on the link URL.
One way I can get the desired HTML output is to use url_for instead:
Product list
A bit long and ugly. Is there a way to make link_to output custom attributes in the A tag (?)
Try
<%= link_to "product list", { :controller => "product", :action => "list" }, "data-role" => "button" %>
I use fancybox in link_to on rails.
<%= link_to image_path('website/website_new/apps/filter_2.png'),"data-fancybox" => "images" do %>
<%= image_tag "website/website_new/apps/filter_2.png", class:"image-medium inline-block cast-shadow" %>
<% end %>
Output:
<a data-fancybox="images" href="/assets/website/website_new/apps/filter_1-d6e69e3728465146276c548645b649be.png"><img class="image-medium inline-block cast-shadow" src="/assets/website/website_new/apps/filter_1-d6e69e3728465146276c548645b649be.png" alt="Filter 1"></a>

adding a class to a link_to is breaking the link

I'm using link_to in RoR 3
When I use it like this, it works fine:
<%= link_to "Add to your favorites list",:controller =>
'favourite_companies', :action =>'create',
:company_id=>"#{#company.id}",
:company_name=>"#{#company.company_name}" %>
But I would like to pass in a class as well
however, this is not working for me. The class works, but it breaks the link. Any ideas?
<%= link_to "Add to your favorites list",{:controller =>
'favourite_companies', :action =>'create'},
:company_id=>"#{#company.id}",
:company_name=>"#{#company.company_name}",
:class=>"ui-button-text button_text"} %>
<%= link_to "Add to your favorites list",{:controller =>
'favourite_companies', :action =>'create'},
:company_id=>"#{#company.id}",
:company_name=>"#{#company.company_name}",
:class=>"ui-button-text button_text"} %>
try this
<%= link_to "Add to your favorites list", :controller =>
'favourite_companies', :action =>'create',
:company_id=>"#{#company.id}",
:company_name=>"#{#company.company_name}",
{ :class=>"ui-button-text button_text" } %>
Since the :class should be in :html_options (refering to API)
link_to(body, url, html_options = {})
The proper way of doing what you have is as follows:
link_to "Foo", { URL_FOR PARAMS HERE }, :class => "bar"
As far as setting the controller and action manually like this, well, it's crap. Rails builds url helpers for you; use them and save yourself some time, energy, and add clarity, all at once:
link_to "Foo", favourite_companies_path(#company), :method => :post
What you're doing with the string interpolation is a bad idea too…it's just wasteful and cluttered for no reason at all. The following is the same, just better:
link_to "Foo", :company_id => #company.id, :company_name => #company.name
As far as why your link wasn't working, if wrapping it in a div helped it sounds like you have a problem with your HTML structure, not the link_to syntax.
I'm using a link_to do-end block so the above previous solutions didn't work for me.
If you want to embed other tags in your a tag, then you can use the link_to do-end block.
<%= link_to favourite_companies_path(:company_id => #company.id, :another_url_param_here => "bar"), { :class => "ui-button-text button_text", :title=> "We can have more html attributes as well" } do %>
<i class="fa fa-star"></i>
<%= #company.company_name %>
<% end %>
In this case it's
<%= link_to path(url_params), html_options = {} do %>
<% end %>
Be careful because in Rails 5 the above methods will still result in a wrong URL generation. The controller and action need to be put in a literal hash in order for it to work in Rails 5. What you will have should be something like this
<%= link_to "Add to your favorites list",
{ controller: "favourite_companies", action:"create"},
company_id: #company.id,
company_name: #company.company_name,
class: "ui-button-text button_text" %>

Resources