以Ajax方式在Rails 3中提交表单(使用jQuery)


79

我是Rails和jQuery的初学者。我在一页中有两个单独的表单,我想以ajax方式(使用jQuery)分别提交。这就是我走了多远。任何人都可以添加或修复此代码以使其正常工作。我正在使用Rails 3.1和jQuery 1.6。先感谢您。

application.js

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

第一种形式:

<%=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%>

第二种形式:

<%=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%>

学校负责人

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与SchoolController的形状相同

Answers:


108

你想要:

  1. 停止提交的正常行为。
  2. 通过ajax将其发送到服务器。
  3. 收到回复并相应地进行更改。

下面的代码应该这样做:

$('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
});

14
在上面的表格中,这对我不起作用。我相信这是因为我试图发布到资源,该资源使用相同的URL作为索引并在Rails中创建方法,这要求将请求强制为POST。如果您要提交表单请求,以请求已在中声明为资源的内容routes.rb,则需要确保您使用的是POST而不是GET。使用jQuery,只需将其添加type: 'POST'$.ajax调用中即可。
伊莱·霍滕

我实现了此代码,但似乎并未实际提交。我必须将其包装在$(CODE).submit();调用中才能执行,然后提交2个帖子。有任何想法吗?
thinkpunch 2013年

如果表格很大,该怎么办?.serialize()将在提交时导致请求URI太长错误。
zykadelic

请参阅第一个评论,然后您需要执行POST请求。因此,添加type: 'POST'到ajax调用中。
2013年

1
这个答案确实不是万能的。
轻度模糊

58

如果您:remote => true在表单上使用,则可以使用JavaScript提交

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

4
我今天被代码中的错误所咬,因此发布以帮助最终遇到像我这样的情况的其他人。我有一个隐藏字段,并且偶然(复制和粘贴错误),该字段标记为“必填”。该字段没有分配值(应该由我静态分配)。由于它是隐藏的,因此没有Rails会指出要修复的UI工件。而是在提交表单时,Rails会静默触发一个事件,如果您不订阅该事件,您将不知道发生了什么以及为什么表单从未提交。
2013年

1
通过AJAX静默提交表单在开发中始终会遇到此问题。您应该能够在您的开发工具中看到交易发生。另外,仅当表单正确提交后,才应使用AJAX。
轻微的绒毛

有趣的是我不知道
阿兰·高

这是使用UJS的最佳答案。假设您有一个表单,该表单从表单提交的远程服务异步获取Stripe令牌。在Stripe回调函数中,您将获得Stripe响应,现在您需要再次将表单提交给Rails create动作。如果您使用它进行操作,.ajax您将无法像应该那样处理'create.js.erb'模板中的成功和错误数据。尝试.submit()第二次使用,并且您remote => true和auth令牌丢失。 .trigger岩石,您的表单将使其按需创建#create,渲染“ create.js.erb”
user3670743 2015年

@ user3670743-谢谢。您能否详细说明这一点?
BKSpurgeon'8

33

在Rails 3中进行Ajax表单提交的首选方法是利用Rails-ujs。

基本上,您允许Rails-ujs为您完成ajax提交(并且您无需编写任何js代码)。然后,您只需编写js代码来捕获响应事件(或其他事件)并执行您的操作即可。

这是一些代码:

首先,在form_for中使用remote选项,因此默认情况下,表单将通过ajax提交:

form_for :users, remote:true do |f|

然后,当您要基于ajax响应状态(例如,成功响应)执行某些操作时,请编写如下的javscript逻辑:

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

几个事件,你可以钩住。


1
与Rails 4相同,它安装在默认项目模板上。并且不要忘记data: {type: 'text'}api.jquery.com/jquery.ajax上的说明设置属性,否则请求可能会由于JSON解析错误而失败。
Ciro Santilli郝海东冠状病六四事件法轮功

13

要通过AJAX提交表单,您可以将其传递:remote => trueform_for助手。默认情况下,rails 3.0.x使用原型js库,但您可以将其更改为带有jquery-railsgem的jquery (rails 3.1的默认设置)。bundle install然后rails g jquery:install使用jquery替换原型文件。

之后,您只需要处理回调即可。看看这个截屏


我已经在目录中拥有jquery库并且删除了原型文件,jquery可以工作,但我只需要从此处提交表单表单
katie


2

在您使用ajax的请求中停止行为默认值非常重要,在form_for中发送remote:true

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

<% end %>

在你的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
});

0

这里对我没有任何帮助,我的问题是,如果我调出一个模态窗口,则jQuery模态库会使我的表单无法通过远程数据提交,但我找到了解决方法。

首先将jQuery Form插件添加到资产javascript目录中:http : //malsup.github.io/jquery.form.js

现在,为您的表单覆盖Submit方法。例如,您可以执行以下操作:

= 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);
        }
      })
    })

  })
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.