Gửi biểu mẫu trong rails 3 theo cách ajax (với jQuery)


79

Tôi là người mới bắt đầu về rails và jQuery. Tôi có hai biểu mẫu riêng biệt trong một trang và tôi muốn gửi chúng riêng biệt theo cách ajax (với jQuery). Đây là cách tôi đã đi xa. Ai có thể thêm hoặc sửa mã này để làm cho nó hoạt động. Tôi đang sử dụng Rails 3.1 và jQuery 1.6. Cảm ơn bạn trước.

application.js

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

hình thức đầu tiên:

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

Dạng thứ hai:

<%=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 có cùng hình dạng với SchoolController

Câu trả lời:


108

Bạn muốn:

  1. Ngừng hành vi thông thường của gửi.
  2. Gửi nó thông qua ajax đến máy chủ.
  3. Nhận trả lời lại và thay đổi mọi thứ cho phù hợp.

Đoạn mã dưới đây sẽ làm điều đó:

$('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
Điều này không làm việc cho tôi trong biểu mẫu trên. Tôi tin rằng đó là vì tôi đã cố gắng đăng lên một tài nguyên, tài nguyên này sử dụng cùng một URL cho chỉ mục và tạo các phương thức trong Rails, điều này yêu cầu buộc yêu cầu phải là POST. Nếu bạn muốn gửi một yêu cầu biểu mẫu cho một cái gì đó đã được khai báo là tài nguyên routes.rb, bạn sẽ cần đảm bảo rằng bạn đang sử dụng POST chứ không phải GET. Sử dụng jQuery, chỉ cần thêm type: 'POST'vào $.ajaxcuộc gọi.
Eli Hooten,

Tôi đã triển khai mã này, nhưng có vẻ như nó không thực sự gửi. Tôi phải gói nó trong một $(CODE).submit();cuộc gọi để nó thực thi, sau đó nó gửi 2 bài viết. Có ý kiến ​​gì không?
thinkpunch

Làm cách nào để làm điều này nếu tôi có một biểu mẫu khá lớn? .serialize () sẽ gây ra lỗi URI yêu cầu quá dài khi gửi.
zykadelic

Xem bình luận đầu tiên, sau đó bạn cần thực hiện yêu cầu ĐĂNG. Vì vậy, hãy thêm type: 'POST'vào cuộc gọi ajax.
Johan

1
Câu trả lời này thực sự không phải là đường ray.
Nhẹ nhàng Fuzz

58

Nếu bạn sử dụng :remote => truetrên các biểu mẫu của mình, bạn có thể gửi chúng bằng JavaScript với

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

4
Tôi đã bị một lỗi trong mã của mình hôm nay, vì vậy hãy đăng bài để giúp những người khác gặp phải trường hợp như tôi. Tôi đã có một trường ẩn và vô tình (lỗi sao chép và dán), đã đánh dấu trường là "bắt buộc". Trường không có giá trị được chỉ định (lẽ ra tôi phải được gán tĩnh). Vì nó bị ẩn, không có cấu phần giao diện người dùng nào mà đường ray sẽ chỉ cho bạn để sửa chữa. Thay vào đó, khi biểu mẫu được gửi, rails sẽ âm thầm kích hoạt một sự kiện mà nếu bạn không đăng ký, bạn sẽ không biết chuyện quái gì đang xảy ra và tại sao biểu mẫu không bao giờ được gửi.
sat

1
Gửi biểu mẫu một cách âm thầm qua AJAX luôn có vấn đề này trong quá trình phát triển. Bạn sẽ có thể thấy giao dịch xảy ra trong các công cụ dành cho nhà phát triển của mình. Ngoài ra, bạn chỉ nên áp dụng AJAX khi biểu mẫu của bạn được gửi chính xác.
Nhẹ nhàng Fuzz

thú vị tôi đã không biết rằng
Alain Goldman

Đây là câu trả lời tốt nhất với UJS. Giả sử bạn có một biểu mẫu nhận mã thông báo Stripe không đồng bộ từ một dịch vụ từ xa khi gửi biểu mẫu. Trong hàm gọi lại Stripe, bạn nhận được phản hồi Stripe và bây giờ bạn cần gửi lại biểu mẫu của mình để Rails tạo hành động. Nếu bạn làm điều đó bằng cách sử dụng, .ajaxbạn sẽ không thể xử lý dữ liệu thành công và lỗi trong mẫu 'create.js.erb' của mình như bạn nên làm. Hãy thử sử dụng .submit()lần thứ hai remote => truevà mã thông báo xác thực và của bạn bị mất. .triggerđá, hình thức của bạn sẽ làm cho nó để #create như mong muốn, vẽ 'create.js.erb'
user3670743

@ user3670743 - cảm ơn bạn. bạn có thể nói rõ hơn về điểm này không?
BKSpurgeon

33

Cách ưa thích trong Rails 3 để gửi biểu mẫu ajax là sử dụng Rails-ujs.

Về cơ bản, bạn cho phép Rails-ujs thực hiện gửi ajax cho bạn (và bạn sẽ không cần viết bất kỳ mã js nào). Sau đó, bạn chỉ cần viết mã js để nắm bắt sự kiện phản hồi (hoặc các sự kiện khác) và thực hiện công việc của bạn.

Đây là một số mã:

Đầu tiên, sử dụng tùy chọn từ xa trong form_for để biểu mẫu sẽ gửi qua ajax theo mặc định:

form_for :users, remote:true do |f|

Sau đó, khi bạn muốn thực hiện một số hành động dựa trên trạng thái phản hồi ajax (ví dụ: phản hồi thành công), hãy viết logic javscript như sau:

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

một số sự kiện mà bạn có thể tham gia.


1
Tương tự trên Rails 4, nơi nó được cài đặt trên mẫu dự án mặc định. Và đừng quên đặt data: {type: 'text'}thuộc tính dưới dạng tài liệu trên api.jquery.com/jquery.ajax nếu không yêu cầu có thể không thành công do lỗi phân tích cú pháp JSON.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

13

Để gửi biểu mẫu qua AJAX, bạn chỉ cần chuyển :remote => truecho người form_fortrợ giúp. Theo mặc định, rails 3.0.x sử dụng js lib nguyên mẫu, nhưng bạn có thể thay đổi nó thành jquery với jquery-railsgem (là mặc định cho rails 3.1). bundle installnó và sau đó rails g jquery:installđể thay thế các tệp nguyên mẫu bằng jquery.

Sau đó, bạn sẽ chỉ cần xử lý lệnh gọi lại. Hãy xem video màn hình này


đã tôi có thư viện jquery trong thư mục của tôi và tôi loại bỏ các file nguyên mẫu, các công trình jquery nhưng tôi chỉ cần gửi biểu mẫu dạng từ đó
katie

Trình cài đặt không cần thiết nữa: stackoverflow.com/questions/7103437/...
Alex Moore-Niemi

2

điều này rất quan trọng trong yêu cầu của bạn với ajax, hãy dừng mặc định beahavior, gửi điều khiển từ xa: true trong form_for của bạn

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

<% end %>

trong ajax của bạn

$(".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

Không có gì ở đây hiệu quả với tôi, vấn đề của tôi là thư viện phương thức jQuery sẽ ngăn các biểu mẫu của tôi được gửi qua dữ liệu từ xa nếu tôi đưa ra một cửa sổ phương thức, nhưng tôi đã tìm thấy cách khắc phục.

Đầu tiên, hãy thêm Trình cắm biểu mẫu jQuery vào thư mục javascript nội dung của bạn: http://malsup.github.io/jquery.form.js

Bây giờ ghi đè phương thức gửi cho biểu mẫu của bạn. Ví dụ, bạn có thể làm điều gì đó như sau:

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

  })
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.