Forum: Ruby on Rails Bug: Multiple Submit Buttons w/ form_remote_tag

Posted by derek.haynes (Guest)
on 2005-12-03 22:43
(Received via mailing list)
I've run across a problem when attempting to submit a form with the
form_remote_tag when the form contains multiple submit buttons.

My form contains 2 submit buttons, a "Preview" button and a "Post
Message" button:
<%= submit_tag 'Preview' %>
<%= submit_tag 'Post Message' %>

When the form is submitted, the value of @params['commit'] is the
value of the first submit tag ('Preview' in this case) no matter what
button is used to submit the form.

This is not present when changing the form to a standard non-ajax form.

Any one else run across this problem or have a suggested fix?


--
Derek Haynes
HighGroove Studios - http://www.highgroove.com
Atlanta, GA
Keeping it Simple.
404.593.4879
Posted by Jan Prill (Guest)
on 2005-12-14 19:33
Hi, Derek,

I just ran across this misbehaviour and found your post. Have you found 
any solution?

I've filed a bug report with Ticket #3231

Regards
Jan Prill

derek.haynes wrote:
> I've run across a problem when attempting to submit a form with the
> form_remote_tag when the form contains multiple submit buttons.
> 
> My form contains 2 submit buttons, a "Preview" button and a "Post
> Message" button:
> <%= submit_tag 'Preview' %>
> <%= submit_tag 'Post Message' %>
> 
> When the form is submitted, the value of @params['commit'] is the
> value of the first submit tag ('Preview' in this case) no matter what
> button is used to submit the form.
> 
> This is not present when changing the form to a standard non-ajax form.
> 
> Any one else run across this problem or have a suggested fix?
> 
> 
> --
> Derek Haynes
> HighGroove Studios - http://www.highgroove.com
> Atlanta, GA
> Keeping it Simple.
> 404.593.4879
Posted by Tim Pease (Guest)
on 2005-12-19 20:22
I ran into the same problem.  The prototype library is being used for 
the client-side AJAX serialization -- specifically the Form.serialize() 
method.

http://roberthanson.blogspot.com/2005/11/prototypejs-form.html

It appears that the serialize method does not know which button was 
clicked.  Therefore, it does not know which button to put into the 
serialization.  That is just my guess since by no means am I a 
javascript expert.

Here is a workaround, though.  Prepare yourself for an ugly hack :(

<%= hidden_field_tag('commit', 'Preview') %>
<%= submit_tag('Preview', :name => '_commit') %>
<%= submit_tag('Post Message', :name => '_commit',
               :onclick => "Form.getInputs(this.form, null, 
'commit')[0].value = 'Post Message'") %>

The trick here is to create a hidden input field named 'commit' that 
will be serialized by the prototype javascript code.  The default value 
is 'Preview'.  The javascript attached to the 'Post Message' button will 
change the value of the hidden field to be 'Post Message'.

Hope this helps.

Blessings,
Tim Pease

derek.haynes wrote:
> I've run across a problem when attempting to submit a form with the
> form_remote_tag when the form contains multiple submit buttons.
> 
> My form contains 2 submit buttons, a "Preview" button and a "Post
> Message" button:
> <%= submit_tag 'Preview' %>
> <%= submit_tag 'Post Message' %>
> 
> When the form is submitted, the value of @params['commit'] is the
> value of the first submit tag ('Preview' in this case) no matter what
> button is used to submit the form.
> 
> This is not present when changing the form to a standard non-ajax form.
> 
> Any one else run across this problem or have a suggested fix?
> 
> 
> --
> Derek Haynes
> HighGroove Studios - http://www.highgroove.com
> Atlanta, GA
> Keeping it Simple.
> 404.593.4879
Posted by Eddie Roadcap (Guest)
on 2006-09-22 00:21
The following code placed in application_helper.rb or loaded via /lib
works around this problem while allowing normal submit_tag() useage.
This is not well tested, but seems to do the trick for me.

class ActionView::Base
  alias_method :rails_submit_tag, :submit_tag
  def submit_tag(value = "Save changes", options = {})
    options[:id] = (options[:id] || options[:name] || :commit)
    options.update(:onclick => "$('#{options[:id]}').value =
'#{value}'")
    rails_submit_tag(value, options)
  end
end

So this rails code:
   <%= submit_tag 'Transfer', :name => :submit %>
   <%= submit_tag 'Check IN' %>
produces this HTML:
   <input id="submit" name="submit" onclick="$('submit').value =
'Transfer'" value="Transfer" type="submit">
   <input id="commit" name="commit" onclick="$('commit').value = 'Check
IN'" value="Check IN" type="submit">



derek.haynes wrote:
> I've run across a problem when attempting to submit a form with the
> form_remote_tag when the form contains multiple submit buttons.
> 
> My form contains 2 submit buttons, a "Preview" button and a "Post
> Message" button:
> <%= submit_tag 'Preview' %>
> <%= submit_tag 'Post Message' %>
> 
> When the form is submitted, the value of @params['commit'] is the
> value of the first submit tag ('Preview' in this case) no matter what
> button is used to submit the form.
> 
> This is not present when changing the form to a standard non-ajax form.
> 
> Any one else run across this problem or have a suggested fix?
> 
> 
> --
> Derek Haynes
> HighGroove Studios - http://www.highgroove.com
> Atlanta, GA
> Keeping it Simple.
> 404.593.4879
Posted by Mike Garey (random52k)
on 2006-09-22 00:39
(Received via mailing list)
what's the status on this bug? Is it something that's ever going to be
fixed?  I try to stay away from Ajax forms with multiple buttons
because of this.

Mike
Posted by _Kevin (Guest)
on 2006-09-22 02:57
(Received via mailing list)
Mike Garey wrote:
> > This is not well tested, but seems to do the trick for me.
> >
> >
> > > value of the first submit tag ('Preview' in this case) no matter what
> > > Atlanta, GA
> > > Keeping it Simple.
> > > 404.593.4879
> >
> > --
> > Posted via http://www.ruby-forum.com/.
> >
> > >
> >

With normal forms, if you give the submit button a different name
attribute, the submitted parameters will contain an entry for it.

<%= submit_tag 'Preview', :name=>'preview' %>

params['preview'] is then defined on submission, and you can use that
to figure out which button was pressed.  No idea if this works for AJAX
forms, but it seems like it should.

_Kevin
Posted by Daniel Morris (danieljmorris)
on 2006-09-29 13:09
I've tried a simple method of creating a hidden 'submit_id' field.

Every submit button updates it with ':onclick'.

The code I use:

class ActionView::Base
  def submit_tag(value = "Save changes", options = {})
	options.update(:onclick => "$('submit_id').value = '#{value}'")
	super(value,options)
  end
end

which is placed in application_helper.rb.

And on your form place a hidden field like so (for example):

<%= %Q!<input id="submit_id" name="submit_id" type="hidden" 
value="12345">! %>

The :submit_id param will contain the right value. At least this is what 
worked for me !!

Cheers
Posted by Daniel Morris (danieljmorris)
on 2006-09-29 13:41
This is a more compact solution- it only needs to be inserted into your 
application_helper.rb

class ActionView::Base
	attr_accessor :got_submit
  def submit_tag(value = "Save changes", options = {})
	options.update(:onclick => "$('submit_id').value = '#{value}'")
	if options[:name] && options[:name]==:commit
		options[:name]="commit_sub"
	elsif options[:name].nil?
		options[:name]="commit_sub"
	end
	res=super(value,options)
	if @got_submit.nil?
		@got_submit=true
		res = res << %Q!<input id="submit_id" name="commit" type="hidden" 
value="12345">!
	end
	res
  end
end


Question:

Is there a better way of inserting the hidden field into a form?

My premise in doing it the way I have done is that you only want a 
hidden 'submit_id' field when you actually have submit buttons.

Cheers
Posted by David Lake (rifraf)
on 2006-11-02 15:23
Hi,

If you have only got 2 buttons then you can take advantage of the fact 
that disabling a button means that it won't get posted. In the code 
below, when the user presses 'Save', the save_button gets disabled and 
the controller sees the presence of preview_button. If 'Preview' gets 
pressed then the first button ('save_button') gets seen as described in 
the earlier posts. It's ugly and the controller logic looks upside down, 
but it seems to work for me...

 <%= submit_tag "Save", :name => 'save_button', :disable_with => "..." 
%>
 <%= submit_tag "Preview", :name => 'preview_button' %>

Controller:

  def save
    # Save button gets disabled when pressed, so no save button means 
preview...
    if !@params['save_button'].nil? then
      do_preview
    else
      do_save
    end
  end

derek.haynes wrote:
> I've run across a problem when attempting to submit a form with the
> form_remote_tag when the form contains multiple submit buttons.
> 
> My form contains 2 submit buttons, a "Preview" button and a "Post
> Message" button:
> <%= submit_tag 'Preview' %>
> <%= submit_tag 'Post Message' %>
> 
> When the form is submitted, the value of @params['commit'] is the
> value of the first submit tag ('Preview' in this case) no matter what
> button is used to submit the form.
> 
> This is not present when changing the form to a standard non-ajax form.
> 
> Any one else run across this problem or have a suggested fix?
> 
> 
> --
> Derek Haynes
> HighGroove Studios - http://www.highgroove.com
> Atlanta, GA
> Keeping it Simple.
> 404.593.4879
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.