Search code examples
ajaxruby-on-rails-3formsujs

Rails 3 form_for :remote => true does not submit via AJAX


I am trying to submit a form via AJAX. I figured this should be a simple thing, but it insists on posting as a regular form...

update

This form exists within another form, which is not AJAXified, or related? Would that cause a problem?

The error I get

ArgumentError in LinkWidgetsController#create

There was no default layout for LinkWidgetsController in [/Users/victorstan/Sites/portrait/app/views, /Users/victorstan/.rvm/gems/ruby-1.9.2-p290@portrait/gems/devise-1.5.1/app/views]

Relevant code:

routes

  resources :profiles do
    resource :link_widgets #this handles the form requests for create
    member do
      get 'new_link_widget' #this handles the form requests for new
    end
    resources :pages
  end

controller

class LinkWidgetsController < ActionController::Base
  before_filter :authenticate_user!
  load_and_authorize_resource

  def create
    @link_widget = LinkWidget.new(params[:link_widget])

    respond_to do |format|
      if @link_widget.save
        format.js { render :js => @link_widget, :status => :created, :layout => !request.xhr? }
      else
        logger.debug @link_widget.errors.inspect
        format.js { render :js => @link_widget.errors, :status => :unprocessable_entity }
      end
    end
  end
end

partial

%hr
= form_for [@profile, @link_widget], :remote => true, :format => :js do |f|  
  .field
    = f.label :provider
    = f.select(:provider, options_for_select(f.object.providers, f.object.provider))
  .field
    = f.label :link
    = f.text_field :link, size: 37, class: 'input-width'
  .field
    = f.label :title
    = f.text_field :title, size: 37, class: 'input-width'
    %div
      %small.form-help-text If you set an optional title, it will show up beside the icon as a link
  .field
    = f.label :order
    = f.text_field :order, size: 2
  - unless f.object.new_record?
    .field
      = f.label :delete
      = f.check_box :_destroy
  = f.hidden_field :profile_id
  .actions
    = f.submit 'Save', class: 'right'
  .clear

Solution

  • If I understand what you mean by This form exists within another form, you have nested form tags (something like the following):

    <form> <!-- this is a standard form -->
        ...
        <form> <!-- this is the remote/AJAXified form -->
            ...
        </form>
        ...
    </form>
    

    The HTML specification does not allow nesting of form tags. You should move the inner form to another place in your document. If that's not possible, you could try to use two submit buttons inside a single form, and then take appropriate action based on which button was pressed (you can do that on the server).