Re: [Rails] Ajax not working inside iteration

17 views
Skip to first unread message
Message has been deleted

Walter Lee Davis

unread,
Jan 2, 2017, 1:00:30 PM1/2/17
to rubyonra...@googlegroups.com

> On Jan 2, 2017, at 9:14 AM, 'krfg' via Ruby on Rails: Talk <rubyonra...@googlegroups.com> wrote:
>
> I have a AtpRank model containing the first 100 Atp tennis players.
> My goal is to create in the view a table listing all tennis players and their attributes, along with a button for each player useful for the user to choose a list of tennis players. The home.html.erb code is below:
>
>
>
>
> <% @atp_ranks.each do |tennis_player|
> %>
> <tr id="tennist-
> <%= tennis_player.
> ranking %>">
>
> <td class="atpranking"> <%= tennis_player.ranking %> </td>
>
>
> <td class="atpname"> <%= tennis_player.name %> </td>
>
>
> <td class="atppoints"> <%= tennis_player.points %> </td>
>
>
> <% unless Time.now.month == 12
> %>
>
> <td>
>
>
> <div id="atpenlist_form">
>
>
> <% if current_user.atpenlisted?(tennis_player)
> %>
>
> <%= form_for(current_user.atp_selections.find_by(atp_rank_id: tennis_player.id),
>
> html
> : { method: :delete }, remote: true) do |f|
> %>
>
> <%= f.submit "Dump", class: "btn btn-warning btn-sm"
> %>
>
> <% end
> %>
>
> <% else
> %>
>
> <%= form_for(current_user.atp_selections.build, remote: true) do |f|
> %>
>
> <div><%= hidden_field_tag :atp_id, tennis_player.id %></div>
>
>
> <%= f.submit "Choose", class: "btn btn-primary btn-sm"
> %>
>
> <% end
> %>
>
> <% end
> %>
>
> </div>
>
>
> </td>
>
>
> <% end
> %>
>
> </tr>
> <% end %>
>
>
> As you can see, the form uses Ajax having set remote: true in the form_for helper. Requests are handled by the atp_selections controller. Below is an extract of the create action of this controller:
>
>
>
> current_user.atpenlist(tennist)
>
> respond_to
> do |format|
>
> format
> .html { redirect_to root_url }
>
> format
> .
> js
>
> end
>
> The destroy action uses the atpdiscard method instead of the atpenlist method.
> In app/views/atp_selections I created the create.js.erb and destroy.js.erb files.
> Below is the app/views/atp_selections/create.js.erb file:
>
>
>
> $("#atpenlist_form").html("<%= escape_javascript(render('users/atpdiscard')) %>");
>
> $
> ("#atp_count").html('<%= current_user.atp_ranks.count %>');
>
> Each of the app/view/users/_atpenlist.html.erb and app/view/users/_atpdiscard.html.erb partials contain the respective form (the same exact part of the code above starting with form_for).
>
>
>
> I have to say that in the original code for the home page I did not explicitly included the entire code for the forms, but I just rendered the partials. This did not work: rails warned me that it could not find the variable or method tennis_player used in the iteration, for some reason to me unknown. So I had to renounce to render the partials and decided to include the entire code.
>
>
>
> The issue is now that Ajax does not work: I have to refresh the page to see the results of submitting the form. I checked my code and could not find errors or explanation for this.
>
>
> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-ta...@googlegroups.com.
> To post to this group, send email to rubyonra...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/d57fc640-9207-45a2-9368-4362b760cea9%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

I'm sorry, but I'm not following this code at the moment. I have a different suggestion for you to try, though. Use a link with method delete and remote true rather than hand-coding the form. The remote helper will construct a form around the link at the moment that you click it, and you'll avoid all of this code. The insta-form will submit to whatever URL you create for the link, and you can add additional parameters to it if necessary without any complexity, simply by putting them in the URL helper like this:

link_to 'Dump', selection_path(tennis_player, foo: bar), remote: true, method: :delete

link_to 'Choose', new_selection_path(tennis_player), remote: true, method: :post

See if that clarifies things for you.

Also, and probably more important than how you code your form, make sure that your selections_controller has something specified in the respond_to block for format.js (this is the format that remote: true triggers), and make sure you have defined a UJS template for each of those methods. Those UJS templates can re-paint the current page, too, so your actions will have immediate effect without any need for additional code or reloading.

create.js.erb and destroy.js.erb would probably work just fine using the same code, as long as both of those methods select all selections:

$('#selections').html('<%=j render @selections %>');

Alternatively, you could probably make an index.js.erb and render action: :index inside the format.js block instead, to reduce copy-pasta.

Walter

Reply all
Reply to author
Forward
0 new messages