78

I am a beginner in rails and jQuery. I have two separate forms in one page and I want to submit them separately in ajax way (with jQuery). This is how far I got. Can anybody add or fix this code to make it work. I am using Rails 3.1 and jQuery 1.6. Thank you in advance.

application.js

$(".savebutton").click(function() { $('form').submit(function() { $(this).serialize(); }); }); 

first form:

<%=form_for :users do |f| %> <fieldset> <legend>Basic details</legend> <%= f.label :school %> <%= f.text_field :school,:size=>"45",:class=>"round",:id=>"school" %><br/> </fieldset> <p><%= button_to "save and continue",{:class=>"savebutton"} %></p> <%end%> 

second form:

<%=form_for :courses do |c| %> <fieldset> <legend>Your current classes</legend> <label>class:</label><%= c.text_field :subject,:size=>"45",:class=>"round" %><br/> </fieldset> <p><%= button_to "save and continue",{:class=>"savebutton"} %></p> <%end%> 

SchoolController

class SchoolController < ApplicationController respond_to :json def create @school = current_user.posts.build(params[:school].merge(:user => current_user)) if @school.save respond_with @school else respond_with @school.errors, :status => :unprocessable_entity end end end 

CourseController is in the same shape as SchoolController

6 Answers 6

108

You want to:

  1. Stop the normal behaviour of submit.
  2. Send it through ajax to the server.
  3. Get a reply back and change things accordingly.

The code below should do that:

$('form').submit(function() { var valuesToSubmit = $(this).serialize(); $.ajax({ type: "POST", url: $(this).attr('action'), //sumbits it to the given url of the form data: valuesToSubmit, dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard }).success(function(json){ console.log("success", json); }); return false; // prevents normal behaviour }); 
Sign up to request clarification or add additional context in comments.

8 Comments

This didn't work for me in the above form. I believe it was because I was attempting to post to a resource, which uses the same URL for the index and create methods in Rails, this requires to force the request to be a POST. If you want to submit a form request for something that has been declared a resource in routes.rb, you will need to ensure you are using a POST and not a GET. Using jQuery, simply add type: 'POST' to the $.ajax call.
I implemented this code, but it doesn't seem to actually submit. I have to wrap it in a $(CODE).submit(); call to get it to execute, then it submits 2 posts. Any ideas?
How do I do this if I have a quite large form? .serialize() will cause a request URI too long error on submit.
See first comment, you need to do a POST-request then. So add type: 'POST' to the ajax-call.
This answer really isn't the rails way.
|
59

If you use :remote => true on your forms, you can submit them with JavaScript with

$('form#myForm').trigger('submit.rails'); 

7 Comments

I got bitten by a bug in my code today so posting to help others who end up in a situation like mine. I had a hidden field and accidentally (copy & paste error), had the field marked as "required". The field did not have a value assigned (should have been statically assigned by me). Since its hidden, there is no UI artifact that rails will point you at to go fix. Rather, when the form is submitted, rails will silently fire an event that if you don't subscribe to, you won't know what the hell is going on and why the form never got submitted.
Submitting a form silently via AJAX always has this problem in development. You should be have been able to see the transaction occur in your dev tools. Also, you should only be applying AJAX once your form submits correctly.
interesting i didn't know that
This is the best answer with UJS. Let's say you have a form that is asynchronously getting a Stripe token from a remote service on form submit. In your Stripe callback function you get the Stripe response and now you need to submit your form again to Rails create action. If you do it using .ajax you are not going to be able to handle the success and error data in your 'create.js.erb' template like you should. Try to use .submit() a second time, and your remote => true and auth token are lost. .trigger rocks, your form will make it to #create as it should, rendering 'create.js.erb'
@user3670743 - thank you. are you able to elaborate on this point?
|
33

The preferred way in Rails 3 to do ajax form submission is to utilize Rails-ujs.

Basically you allow Rails-ujs to do the ajax submit for you (and you won't need to write any js code). Then you just write js code to capture the response event (or other events) and do your thing.

Here are some code:

First, use the remote option in form_for so form will submit via ajax by default:

form_for :users, remote:true do |f| 

Then when you want to do some action based on ajax response status (e.g. successful response), write the javscript logic like this:

$('#your_form').on('ajax:success', function(event, data, status, xhr) { // Do your thing, data will be the response }); 

There are several events which you can hook to.

1 Comment

Same on Rails 4, where it comes installed on the default project template. And don't forget to set the data: {type: 'text'} attribute as documented on api.jquery.com/jquery.ajax or the request may fail due to JSON parse error.
13

To submit form via AJAX you could just pass :remote => true to the form_for helper. By default rails 3.0.x uses prototype js lib, but you can change it to jquery with the jquery-rails gem (which is the default for rails 3.1). bundle install it and then rails g jquery:install to replace the prototype files with jquery.

After that you'll just need to handle the callback. Take a look at this screencast

2 Comments

already i have jquery library in my directory and i removed prototype files,jquery works but i just need to submit the form form from there
Installer isn't necessary anymore: stackoverflow.com/questions/7103437/…
2

it's very important in your request with ajax stop the beahavior default, send remote:true in your form_for

<%= form_for :session, url: sessions_path, remote: true, html: { class: "form-signin" } do |f| %> <% end %> 

in your ajax

$(".form-signin").on("submit", function(e) { $.ajax({ url: $(this).attr('action'), data: $(this).serialize(), type: "POST", dataType: "json", success: function(response) { console.log(response) }, error: function(xhr, textStatus, errorThrown) {} }); e.preventDefault(); //THIS IS VERY IMPORTANT }); 

Comments

0

Nothing here worked for me, my issue was the jQuery modal library would break my forms from being submitted via remote data if I brought up a modal window, but I found a fix.

First add the jQuery Form Plugin to your assets javascript directory: http://malsup.github.io/jquery.form.js

Now override the submit method for your form. For example you could do something like this:

= form_for @object, html: {class: "ajax_form_submit"}, authorization_token: true do |f| = f.text_input javascript: $(document).on('ready page:load', function() { $(".ajax_form_submit").submit(function () { var form = $(this) form.ajaxSubmit({ success: function (responseText, statusText, xhr) { console.log('success: ajax_form_submit') }, error: function (jqXHR, statusText, errorThrown) { console.log('error: ajax_form_submit'); console.log(jqXHR, statusText, errorThrown); } }) }) }) 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.