pawel7318
pawel7318

Reputation: 3593

Perform different actions on selected page elements using different buttons within one form

Some time ago I asked how to select multiple page elements and perform an action on them.

I implemented it and it works great. Now I face another problem: how to make multiple actions for those elements?

My view looks now that way:

<%= form_for :album_slides_multi, method: :delete, id: 'multi-select' do |f| %>
<%= f.submit "Delete selected" %>
...
<% @slides.each do |slide| %>
<tr>
      <td><%= check_box_tag "ids[]", slide.id, false, class: "multi-delete" %></td>

So I have checkboxes and the submit button named 'Delete selected'. I wish to have another button next to it - 'Move to another album'.

My controller will use :update method rather than :delete so I assume form_for ... method: :delete is not what I can use here.

Upvotes: 1

Views: 1021

Answers (3)

DTOMA88
DTOMA88

Reputation: 26

Actually the easiest way to change the form action depending on the button clicked (or pressed with enter) would be something like this :

<form id="form" action="form_1" method="post">
<button data-action="form_2">button1</button>
<button data-action="form_3">button2</button>
<button data-action="form_4">button3</button>
</form>


<script>
$(document).ready(function(e) { 
$('button').click(function(e) {
    $('#form').attr('action',$(this).attr('data-action'));
});
});
</script>

Upvotes: 1

MrCode
MrCode

Reputation: 64536

If you have two forms and you want the checkbox actions in the first to be mirrored in the second, you can do this:

Fiddle

$(document).ready(function(){
    $('#foo_form input:checkbox').change(function(){
       $('#bar_' + this.id.replace('foo_', '')).prop('checked', this.checked); 
    });
});

Upvotes: 1

Ecnalyr
Ecnalyr

Reputation: 5802

You currently have a form button that is posting to the destroy action. You are submitting the form data (params containing, among other things, the ids of the models that are checked) to the destroy action, which does whatever you want with the data collected and submitted through the form. What you are asking will require another button (or some way of submitting the form) that points to another action (in your case, it looks like you want to use update), but you cannot do this directly because the form decides what action to use, not the button. So what should you do?

What you really want:

The answer is to have the form post to an action of your choice (probably a custom one you create because in your case it won't make sense to call it destroy or update).

How to do it:

To keep things simple, simply change your form to use the update action rather than the destroy action (because it makes more sense)

<%= form_for :album_slides_multi, method: :update, id: 'multi-select' do |f| %>

Leave your submit/delete button alone:

<%= f.submit "Delete selected" %>

Add a new tag for your 'move to another album' feature's button:

<%= f.submit "Move selected" %>

The above tags give you html that looks like:

<input type="submit" value="Delete selected" name="commit" />
<input type="submit" value="Move selected" name="commit" />

Then, in your controller, make your update action read something like this:

def update
  if params[:commit] == "Delete selected"
    # your current delete logic
  elsif params[:commit] == "Move selected"
    # your desired move logic
end

More info:

When you click your Move selected button your update action will fire and you will make it to the section where params[:commit] == "Move selected" because the value of the button was "Move selected" and that value was submitted along with the rest of the params under the name "commit".

If it makes more sense, feel free to create a new action named something more appropriate than update. I won't detail how to do that here as there are plenty of resources explaining how to do that, but using the update action above to accomplish what you want should teach you what you are trying to learn.

This is called a multibutton form and is covered in Rails Cast #38, but that episode is from 2007 and the exact syntax may be dated in places.

Upvotes: 1

Related Questions