Search code examples
ruby-on-railsformtastic

Multiple submit actions with formtastic


I'm trying to setup a formtastic form with multiple submit actions, following along with Railscast #38. What's the equivalent of this in Formtastic?

<%= submit_tag 'Create' %>
<%= submit_tag 'Preview', :name => 'preview_button' %>

This post gave me hope, but it looks like commit_button was deprecated in 2.1.0, and I can't seem to figure out the new syntax.

Here's my code for what it's worth. I'd like each submit button to go to the same controller, where I will handle them differently:

# Use prepaid credits to checkout
<%= f.action :submit, :as => :button, :label => "Order Critique (1 credit will be spent)", :button_html => { :class => "btn btn-primary", :disable_with => 'Processing...' } %>
# Use credit card to checkout
<%= f.action :submit, :as => :button, :label => "Order Critique ($10)", :button_html => { :class => "btn btn-primary", :disable_with => 'Processing...' } %>

Solution

  • TL;DR: If you use javascript to submit a form, it won't carry over the submit button's name in the commit params.

    My problem ended up being the code used in Railscasts Episode #288. This CoffeeScript function gets fired when you submit the form, after the Stripe token checks out:

    handleStripeResponse: (status, response) ->
      if status == 200
        $("#stripe_card_token").val(response.id)
        $("#my_form_id")[0].submit()
      else
        # other stuff
    

    Since javascript is doing the form submission with $("#my_form_id")[0].submit(), the name parameter won't be carried over in the commit params.

    My solution was to add a "clicked" attribute to the button that gets clicked...

    $('form_input[type=submit]').click ->
      $('input[type=submit]', $(this).parents('form')).removeAttr('clicked')
      $(this).attr('clicked', 'true')
    

    ..and then grab the id attribute of the clicked button populate a hidden field with it:

    submitter = $("input[type=submit].clicked=true").attr("id")
    

    I don't particularly like this solution. It feels like my js knows too much, and I don't like depending on js for this sort of thing. Any criticism or better solutions are certainly welcome :)