简体   繁体   中英

Creating RoR Links within Ajax call in .js.erb file

I have the following ajax call that activates on button click:

    $.ajax({

            url: button_action,

            data: {},

            type: "POST",

            dataType: "json",

            success: function( data ) {

                var att = data.attendees

                var attendee_list = "";

                for (i = 0; i < data.attendees.length; i++) {
                    if ( i != att.length-1) {
                        attendee_list += att[i].first_name + " " + att[i].last_name + ", ";
                    }       else {
                        attendee_list += att[i].first_name + " " + att[i].last_name 
                    }
                }

                att_array.innerHTML = attendee_list;
            }, . . . 

        });

Now, we see that I'm getting a list of event attendees back from the server in data.attendees . I'm able to get the first and last name of each attendees, and I can just as easily get the id of the attendees with id = att[i].id . Instead of just displaying the name of each attendee, I would like to create a link to that attendees show page using their id . Ideally, I would create a variable full_name = att[i].first_name + " " att[i].last_name and then create a link like

<%#= link_to full_name, user_path(user.id) %>

I am aware that this involves taking json or javascript variables and using them in Ruby code, and then outputting Ruby code. Is this possible, and if so, how can I do it?

The way your are doing it, with a simple AJAX request, is impossible (by design). The problem is that the Ruby code renders first (since it is server-side) and the JavaScript renders after it. So you can't really 'inject' json in a Ruby method because the helper link_to will execute before the JavaScript is even requested from the server.

What you would like to have it is using unobtrusive JavaScript (UJs). It is done by putting :remote => true on your link. After doing so, the request will go to the server-side method put in your link ( attendees ). Server side, you need to have a respond_to block:

def attendees
  @attendees = Attendee.all #I'm making this up for the example
  respond_to do |format|               
    format.js
  end        
end 

Then, you need a .js.erb file named after the action, ie attendees.js.erb . It will be called when the server-side gets executed. You will receive an array of items. You need a partial that is going to iterate through them. Here is how you are going to do it. In attendees.js.erb

('.attendee-list-container').html("<%= j render(:partial => 'attendees_list', :locals => { :attendees => @attendees }) %>");

And finally, in your _attendees_list.html.erb , you can iterate and create links.

#in HAML:
-attendees.each do |attendee|
  =link_to "#{attendee.first_name + ' ' + attendee_last_name}" , attendee

That's it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM