1

I'm very bad with Ajax and jquery and javascript in general and especially bad in Rails so forgive the obtuseness of this question.

I have a link in my Rails 4 app that I want it to execute a simple hide/show jquery code to hide or show a column based on a cookie value.

I'd like to do this without calling separate js or coffee scripts, but right when the link is clicked without reloading the page.

I've got all the Rails code working to write the cookie value and show or hide the column but by reloading the page, so now I'm trying to do with a bit less obtrusively via Ajax.

In the good ol' days before Rails I would do something like:

onclick='javascript: hideShow(this)'

Or something similar, can't quite remember the proper syntax.

How can I do this in the Rails world? I read somewhere that you can use a link_to with a block but that throws an error.

My link looks like this:

  = link_to "<span class='btn btn-sm btn-primary'>#{dogtag_icon}</span>".html_safe, users_flip_show_dogtag_path, title: icon_title, remote: true

I'm using SLIM templates so I tried creating a block like this:

= link_to "<span class='btn btn-sm btn-primary'>#{dogtag_icon}</span>".html_safe, users_flip_show_dogtag_path, title: icon_title, remote: true do
    - dogtag_show_value = cookies[:show_library_dogtags].to_i
    javascript:
      if (#{dogtag_show_value} == 1) {
        $('.dogTag').show();
      } else {
        $('.dogTag').hide();
      }

Rails did not like that one bit.

I should also explain that the users_flip_show_dogtag_path is important because it's the controller method where the cookie gets set to 0 or 1, I'd like to keep it so as to avoid writing that code in the view template.

If I ammend the link to something like this:

= link_to "<span class='btn btn-sm btn-primary'>#{dogtag_icon}</span>".html_safe do

It doesn't even appear in the view.

It would seem like such a simple thing to do yet I can't figure it out. Google searches have not proved useful.

Any help would be appreciated, thanks.

Edit:

Sorry for the double edit, wrong question

I'm using mccannf's answer and it seems to be working. Now I just need a way to set the visibility of the column on load based on the cookie value. I'm doing this in the viewer top but it doesn't work:

 javascript:
  if (#{@dogtag_show_value} == '1')  {
    $('.dogTag').show();
  } else {
    $('.dogTag').hide();
  }

Thanks again.

Note: I solved the above by simply putting the code at the bottom of the page after the DOM element had been created. By having it at the top it was trying to execute before the DOM element existed. I know, stupid mistake!

kakubei
  • 5,321
  • 4
  • 44
  • 66

1 Answers1

1

The way it works is when you click the link (with remote: true) in View A, it does a remote call to Method_B in the controller which responds with a format.js , and it then executes any JavaScript in the method_B.js.erb file in the view of the controller.

So your link might look like:

= link_to users_flip_show_dogtag_path, title: icon_title, id: "dogtag_link", remote: true do
    %span.btn.btn-sm.btn-primary #{dogtag_icon}

And say your method is called show_dogtag in your controller:

def show_dogtag
    # Logic here e.g. @show_dogtag_value = blah

    respond_to do |format|
      # format.js is the important one here
      format.js
      format.html
    end
end

And then you would add something like the following to show_dogtag.js.erb under the view for the controller (assuming dogtag_show_value has been updated in your method):

if (<%=j @dogtag_show_value %> == 1) {
   $('.dogTag').show();
} else {
   $('.dogTag').hide();
}
mccannf
  • 16,619
  • 3
  • 51
  • 63
  • Thanks, I was trying to avoid the extra show_dogtag.js.erb file but even trying this method I get an error: `NoMethodError - undefined method `gsub' for 1:Fixnum: actionpack (4.0.4) lib/action_view/helpers/javascript_helper.rb:27:in `escape_javascript'` for this line: `if ("<%=j @dogtag_show_value %>" == 1) {`. Apparently it's trying to run `gsub` on the value and it's an integer, but where is this `gsub` run? – kakubei Oct 15 '14 at 13:26
  • I was able to get around the error by creating the cookie as a string instead of an integer, which I'm not very happy about but at least it doesn't throw an error. – kakubei Oct 15 '14 at 13:32
  • Well, the `js.erb` file is the unobtrusive way! For the first load, I would look at the answer to this question: http://stackoverflow.com/questions/3437585/best-way-to-add-page-specific-javascript-in-a-rails-3-app – mccannf Oct 15 '14 at 14:13