0
votes

On a search results page I have "Add to favorites" and "Remove from favorites" button partials that use respond_to and format.js so the page does not refresh, but the page toggles between displaying the "Add to favorites" and "Remove from favorites" button partials. That works fine.

But on the user's "My Favorites" page and on their profile page, if the user clicks "Remove from favorites" button, I do want to refresh the page, so that removed favorite no longer displays.

I can control when to refresh page (respond_to format.html) and when to toggle the buttons (respond_to format.js), by passing local variable to partial used for remote: true (remote: @refresh_page), but in the favorites controller, the format.html is set to redirect_to users_path.

So how can I send a variable from the partial to the controller destroy action method telling it where to redirect to?

Here is the partial:

<%= form_for(current_user.favorites.find_by_followed_event_id(user_event),
  html: { id: "event_number_#{user_event.id}", method: :delete }, remote: @refresh_page) do |f| %>
  <%= f.submit "Remove from favorites %>
<% end %>
3
why would you use a form to add/remove to/from favorites? a link_to an action would be enough I think, in that link you'll use remote: true for ajax, and send whatever params you need but when you do it with ajax you won't need a redirect, just add proper js in the action_name.js.erb file to replace one partial with another.rmagnum2002
As I said in my question, on the search results page I want to not refresh, but to toggle between the add and remove buttons, and that is working fine. But on the My Favorites page, I do want to refresh, so the favorite will completely disappear. I guess I could just not refresh, and just update the favorites for the user, but that would mean a different format.js than the one used to toggle the buttons. So I need different behavior depending on where the partials are used. I'm trying to be DRY.Greg Lafrance
So you need the refresh only to remove the favorited object from the list, and you can make a favorite disappear with my exemple too, in your action.js.erb file you'll have to use javascript to remove the div where the favorite is, this way when you'll click to remove from favorites, js will remove the element from page.rmagnum2002
I could have the action.js.erb file remove the element, but depending on where the partial is being used, instead of removing the element, I need to toggle between add and remove buttons, as described in the question. Perhaps I need to code more intelligence in the action.js.erb.Greg Lafrance
"Perhaps I need to code more intelligence in the action.js.erb" - yes, you do.. You could send a special param in link_to and in action.js.erb you can check if that param is present, than just remove the favorited element, else toggle butons.rmagnum2002

3 Answers

0
votes

I understand, that you want to call favourite#destroy but want a switch in your controller to specify the redirect_to target.

One way is to submit additional information either as url parameter or as hidden field.

<%= form_for(current_user.favorites.find_by_followed_event_id(user_event),
  html: { id: "event_number_#{user_event.id}", method: :delete }, remote: @refresh_page) do |f| %>
  <%= hidden_field_tag :return_to, 'your_target' %>
  <%= f.submit "Remove from favorites %>
<% end %>

and in your controller

...
if params[:return_to]=='your_target'
  redirect_to 'where_ever'
else
  redirect_to users_path
end
1
votes

What about the hidden field in your form ? Like so:

<%= hidden_field_tag :redirect_path, root_path %>

Then in your controller:

params[:redirect_path]
0
votes

! Note, just an exemple, not a copy/paste ready code:

search page

here you'll need to check if object is in favorites list already

  <div class="fav_toggle">
    <%= link_to "Add to favorites", toggle_favorites_path(object, action: 'toggle'), remote: true %>
  </div>

my favorites page

  <div class="fav_toggle">
    <%= link_to "Remove from favorites", toggle_favorites_path(object, action: 'remove'), remote: true %>
  </div>

let's say toggle_favorites_path in routes.rb points to some_controller#fav_toggle

def fav_toggle
  some logic here to check if fav exists or not and act as needed
  add/remove favorite
end

fav_toggle.js.erb

<% if params[:action] == toggle %>
  $('.fav_toggle').html('<%= link_to "Remove from favorites", add_to_favorites_path(object, action: 'toggle'), remote: true %>');
<% else %>
  $('.fav_toggle').fadeOut().remove();
<% end %>

you'll need to work on this code to get it working, in the end you'll get what you expect.