21

What is the status of the link_to_function Javascript helper in Rails? I read, including in this stackoverflow question, that it was deprecated in Rails 3.0, then undeprecated, then deprecated again in 3.2.4. Is it something I can depend on and teach students? I just read the release notes (from a search) for Rails 3.2.8:

Reverted the deprecation of button_to_function and link_to_function helpers. Rafael Mendonça França

Where does this stand now?

Community
  • 1
  • 1
at.
  • 50,922
  • 104
  • 292
  • 461

3 Answers3

45

link_to_function is NOT deprecated in 3-2-stable branch and it won't be deprecated in 3-2-stable in future. But it IS depreacated in current master branch and will be deprecated in Rails 4.0 when it releases. So I guess it will removed from rails code in 4.1. So you can teach students to do this (from the rails 4 changelog):

We recommend the use of Unobtrusive JavaScript instead. For example:

link_to "Greeting", "#", class: "nav_link"

$(function() {
  $('.nav_link').click(function() {
    // Some complex code

    return false;
  });
});

or

link_to "Greeting", '#', onclick: "alert('Hello world!'); return false", class: "nav_link"
Vasiliy Ermolovich
  • 24,459
  • 5
  • 79
  • 77
  • 11
    How would this refactor look when link_to_function is used in a helper? – Btuman Jun 05 '13 at 15:40
  • @Btuman Did you find a solution for this? I upgraded Rails and link_to_function is deprecated and I'm not sure how to do the unobtrusive js for it. – pwz2000 Oct 07 '14 at 14:17
  • I think I did, alas, I no longer have access to the code. basically had to redo it from scratch. (The depreciation of this helper function drove me nuts) – Btuman Oct 07 '14 at 17:52
  • This reloads the page after the javascript. Adding remote: true stops the client refreshing but it still sends a request to the server.. Is there anyway of stoping the request all together? – Hovo Nov 21 '14 at 02:06
4

This is my solution to this problem:

in javascript:

// define function to be called
function awesome_func(a,b,c){
  console.log(a,b,c);
}

//clean implementation of link_to_function
$(function(){
  $('[data-on][data-call][data-args]').each(function(d){
    try{
       $(this).on( $(this).data('on'), function(){
          window[$(this).data('call')].apply(window,$(this).data('args'))})
    }catch(e){
       if(typeof(console) != 'undefined' && typeof(console.log === 'function'))
         console.log(e);
    }
  });
})

Then you can do in rails:

link_to 'Awesome Button', '#', data:{on: :click, call: 'awesome_func',args: '[1,"yeah",{b:4}]'

this seems the way they want us to code :), i liked link_to_function, though

  • Excellent solution, should be the (new) accepted answer IMO. One note the first function can be on the page, the second function needs to be invoked after jquery is loaded so on the layout, – jpw Sep 02 '15 at 20:36
  • You have to be aware of some security issues though: if you have some kind of wysiwyg (tinymce or fckeditor) you would need to always remove data-on, data-click and data-args on user provided div elements. – Elias Baixas Nov 08 '16 at 17:18
0

Building on Elias Baixas answer... I had to change it a bit to get it to work if this helps anyone... I had to add eval and preventDefault (I'm pretty terrible at JS fwiw)

link_to fa_icon('info-circle'),
        '#',
        data: {
          on: :click,
          call: 'channel_info',
          args: Array('some data').to_json
        }


function channel_info(a){
  console.log(a)
}

//clean implementation of link_to_function
$(function(){
  $('[data-on][data-call][data-args]').each(function(d){
    try{
      $(this).on( $(this).data('on'), function(event){
        console.log($(this).data('args'));
        window[$(this).data('call')].apply(window,eval($(this).data('args')));
        event.preventDefault();
      })
    } catch(e) {
     if(typeof(console) != 'undefined' && typeof(console.log === 'function'))
       console.log(e);
    }
  });
})
Ben Wiseley
  • 537
  • 6
  • 14