views:

275

answers:

1

I have a boolean field called "saved" in my database. I want to toggle this field by clicking on a text link that changes from "Save" to "Unsave" depending on the situation, and updates my "Customer" table with 0 or 1. I imagine Javascript may be a way to go for this but I am not experienced enough (yet!) in Javascript to know how to code it.

I've rolled back the question to keep it shorter. Here is my exact code.

#employers controller
def save_toggle
  @matching = Matching.find(params[:id])
  if @matching.employer_stars == false
    @matching.employer_rejects = false # If saving a match, remove any existing rejection.
  end
  @matching.employer_stars = [email protected]_stars
  @matching.save
  render :partial => "save_unsave_buttons", :layout => false
end

#view home.html.erb
<%= render :partial => "save_unsave_buttons", :locals => {:matching => matching} %>

#partial _save_unsave_buttons.html.erb
<div id="save_buttons" class="buttonText"> #latter is just for CSS layout
  <% if @matching.employer_stars %>
    <%= link_to_remote "Unsave",
      :url => {:action => "save_toggle", :id => matching.id},
      :update => {:success => "save_buttons", :failure => "Error"} %>
  <% else %>
    <%= link_to_remote "Save",
      :url => {:action => "save_toggle", :id => matching.id},
      :update => {:success => "save_buttons", :failure => "Error"} %>
  <% end %>
</div>

The database is working but the toggle text isn't switching. To @nathanvda: I'm really sorry for being such a pain - I want to confirm your answer but I know if I do I'll just leave this for a while then come back to it and get frustrated again! Thanks man.

+1  A: 

You have to define a controller-method, which sets your saved attribute. In your view you can then link to this method using link_to_remote.

That should get you started.

--Update: after updated question:

You should create a partial that renders your save/unsave button like this, call it "_save_unsave_buttons.html.erb" :

<div id="save_buttons">
  <% if matching.employer_stars %>
    <%= link_to_remote "Unsave",
       :url => {:action => "save_toggle", :id => matching.id},
       :update => {:success => "save_buttons", :failure => "Error"} %>
  <% else %>
    <%= link_to_remote "Save",
       :url => {:action => "save_toggle", :id => matching.id},
       :update => {:success => "save_buttons", :failure => "Error"} %>
  <% end %>
</div>

This partial will render you correct save-buttons, and upon update the containing div is updated/replaced by the result of your controller action.

From inside your main view, write

<%= render :partial => "save_unsave_buttons", :locals => {:matching => match } %>

where you want the buttons to be visible.

And inside your controller:

def save_toggle
  @matching = Matching.find(params[:id])
  @matching.employer_stars = [email protected]_stars
  @matching.save
  render :partial => "save_unsave_buttons", :locals => {:matching => @matching}, :layout => false
end

Good luck!

--Update again: so i presume you render a set of @matchings, i would change the naming between the collection and the item a bit, to prevent more confusion and accidental mistypings.

But actually this is pretty easy:

@matchings.each do |match|
  .. build your view here ..
  <%= render :partial => "save_unsave_buttons", :locals => {:matching => match}
end

and in your partial you can then use the correct matching everywhere.

nathanvda
Hi @nathanvda, thanks for the comments. I've updated my question above.
sscirrus
Hi @sscirrus: i have update my answer accordingly. I hope it is clearer now?
nathanvda
Hi @nathanvda: I'm almost there. Just a final error to get past - I needed to add :locals in calling the partial so it would recognize 'matching'. But, the toggles aren't working. See my update for more detail. I've given you a 1+ so far, and thank you.
sscirrus
Do you have a surrounding div, with an id, and is that id inside your `:update => "div-name-here". Otherwise it will not know where to send the rendered result.
nathanvda
@nathanvda: Everything seems to be in place but it just isn't changing that damn toggle! I've simplified everything and condensed it above.
sscirrus
@sscirrus, in your partial you test against `@matching.employer_stars`, but from the view you pass to a local named `matching` without the @! From your controller-method you should also pass the locals the keep it alike.
nathanvda
@nathanvda - the last line you write for the controller is now updating the form as it should... but for every single link the controller is toggling only the first element! If a user clicks the 3rd item in the view's loop (@matchings.each do |match|) the controller is rendering the save_buttons partial (with correct result) but it's rendering to the first loop and not the correct loop. I imagine, because the same partial is rendered many times, the controller isn't distinguishing between them all so it just renders the first one it finds.
sscirrus
Yes indeed, because it is in a loop you will have to give your div a unique name, and make sure that div is updated.
nathanvda
Thank you very much @nathanvda. I'll figure out how to create unique divs within a loop. You have been incredibly helpful!
sscirrus