Search code examples
javascriptruby-on-railsassetslink-to-function

How to replace link_to_function for rails 4.1


I am in the middle of creating my first real Rails app, and I'm learning on the go. I have a situation where I need to create nested attributes on one form, and so have been looking at the railscast episodes relevant to that (196 and 197). In the second episode, he uses a link_to_function method, which is apparently no longer available in rails 4.1.

I am wondering how to replace it. I have been trying to link_to, and have tried many of the suggested solutions for others who have posted a similar question, but to no avail.

Here is what my view partial looks like at the moment (though, I've tried many things...)

<p class="offset1 fields">
   <%= f.hidden_field :_destroy %>
   <%= link_to "remove", '#', onclick: 'remove_fields("this")' %>
</p>

And here is my .js.coffee file containing the remove_fields() function:

remove_fields = (link) -> 
    $(link).previous("input[type=hidden]").value = 1
    $(link).up(".fields").hide

This function is supposed to remove a field from the form, but instead just appends the '#' to the url without calling the function.

What is the best way to link to a javascript (coffeescript) function in the assets from a view?


Solution

  • A good way to deal with this is:

    a) Set your href attribute to "javascript:void(0);" b) Set a DOM id or CSS class attribute to your link

    <%= link_to "remove", "javascript:void(0);", id="remove_link" %>
    

    c) Add the js click listener to your element (please check if this is the proper coffeescript syntax)

    $ ->
      $('#remove_link').click = ()-> 
        $(link).previous("input[type=hidden]").value = 1
        $(link).up(".fields").hide
    

    d) Always avoid using onclick: on html elements.

    UPDATE:

    e) Here is an alternative of what might work for your code (after your comment):

    $ ->
      $('#remove_link').click = ()-> 
        $('.offset1.fields input').attr('value', 1);
        $('.offset1.fields').hide();