2012-03-28 55 views
14

Vấn đề là tôi có một biểu mẫu từ xa, dựa trên điều kiện, id muốn chuyển đổi sang dạng không từ xa (sử dụng UJS) và sau đó gửi. lưu ý biểu mẫu có tệp tải lên.Sử dụng JS để thay đổi <form> từ xa sang không từ xa trong Rails 3, HAML

Dưới đây là chi tiết: Tôi đã bước đầu render hình thức từ xa sử dụng

= form_for @myobj, :url => {:action=>"remoteAction", :controller=>"myobjects"}, :remote => true do |f| 
... (f.fields....) 

mà tạo ra HTML:

<form id="new_myobj" class="new_myobj" method="post" accept-charset="UTF-8" data-remote="true" action="/remoteAction"> 

khi tôi bấm submit, như mong đợi, biểu mẫu được gửi 'AS JS '. trong hành động điều khiển, tôi đang thực hiện một số xác nhận của các trường bên trong biểu mẫu đã gửi. Nếu tất cả các kiểm chứng thực vượt qua, tôi thực hiện mẫu .js.haml sau:

$('form#new_myobj').removeAttr("data-remote"); 
$('form#new_myobj').attr('enctype', 'multipart/form-data'); 
$('form#new_myobj').attr('action', '/myobjects/regularAction'); 

làm thay đổi thành công mã HTML trên trang (chứng kiến ​​qua Firebug) tới:

<form id="new_myobj" class="new_myobj" method="post" accept-charset="UTF-8" enctype="multipart/form-data" action="/myobjects/regularAction"> 

kể từ khi hình thức chứa f.file_field, tôi phải gửi dưới dạng multipart để hình ảnh có thể được tải lên và tôi không thể gửi 'AS JS' ngay bây giờ, khi tôi nhấp vào gửi, hành động điều khiển 'regularAction' thực sự được gọi, nhưng vẫn 'AS JS '

nhiệm vụ ion là, những gì khác tôi cần phải thay đổi trong HTML để hình thức có thể được gửi không-xhr? có liên quan đến tiêu đề không?

Trả lời

4

Vấn đề là cách tiếp cận của bạn để vô hiệu hóa việc gửi Ajax không hoàn toàn chính xác. Bạn cần phải hủy liên kết các sự kiện JavaScript đã được thêm bởi rails.js (Rails UJS adapter) vào biểu mẫu. Bạn có thể làm điều đó bằng cách: $('form#new_myobj').unbind() để hủy liên kết tất cả sự kiện được đính kèm với biểu mẫu. Bạn cũng cần phải $('form#new_myobj').removeAttr('data-remote')$('form#new_myobj').removeAttr('data-type') để xóa các thuộc tính data-remotedata-type (nếu có).

+0

Cảm ơn đề xuất của bạn, vì vậy tôi đã thêm lệnh unbind() vào mẫu js.haml của mình, nhưng lần gửi thứ 2 vẫn đi đến hành động 'regularAction' 'AS JS ' –

+0

$' ('form # new_myobj'). Unbind() $ ('form # new_myobj'). RemoveAttr ("data-remote"); ... –

+0

là có bất kỳ thành phần nào khác tôi cần để unbind, có lẽ? –

36

jQuery hơi phức tạp với các thuộc tính dữ liệu vì cả hai số đọc thẻ dữ liệu HTML5 cũng như bộ nhớ riêng của nó được liên kết với phần tử DOM , cũng được gọi là dữ liệu. Khi ghi vào một thuộc tính giá trị đó được sao chép vào lưu trữ dữ liệu của riêng jQuery (có lẽ là khi đang gọi data("remote")).

Tuy nhiên, điều này chỉ xảy ra nếu dữ liệu của jQuery trống cho tên đó. Do đó, đặt thuộc tính sẽ chỉ hoạt động sau, sau đó giá trị "được lưu trong bộ nhớ cache" đang được sử dụng ngay cả khi thuộc tính thay đổi. Để thực sự loại bỏ giá trị , chúng tôi cần xóa thuộc tính và phương thức lưu trữ riêng của jQuerys phương thức theo thứ tự đó. Lý do là có chức năng (element.removeData(…)) cấp cao và một cấp độ thấp (jQuery. removeData(element, …)). Trước đây, họ đọc lại thuộc tính dữ liệu HTML5 và lưu trữ nó trong bộ nhớ riêng của jQuery. Sử dụng hàm mức thấp bất thường rõ ràng là hoạt động tốt.

Ngoài ra, chúng tôi thực sự cần phải loại bỏ các thuộc tính - thiết lập nó để sai là không đủ kể từ Rails chỉ kiểm tra nếu form.data('remote') là không xác định (tìm nó trong jquery_ujs.js).

TL; DR:

  • attr("data-remote") != data("remote")
  • Hai dòng này tạo ra một hình thức không xa (một lần nữa). Đặt hàng các vấn đề.
$("form").removeAttr("data-remote"); 
    $("form").removeData("remote"); 

Nó thành văn bản, nếu bạn thực sự biết những gì bạn đang tìm kiếm:

StackOverflow không cho phép tôi đăng nhiều hơn hai liên kết, nhưng bạn có thể đoán một liên kết removeData. Các hàm mức cao được liên kết từ các hàm cấp thấp.

Tránh các lỗi xác thực thẻ trong Rails 4+: Như Stan bình luận bên dưới, chỉ cần thực hiện ở trên sẽ thất bại với một lỗi InvalidAuthenticityToken. Cách giải quyết dễ dàng, xem tại đây để biết chi tiết: https://stackoverflow.com/a/19858504/1684530

+0

Tuyệt vời! Tôi sẽ cung cấp cho bạn nhiều hơn một 'lên', nếu nó có thể là có thể !!! –

+0

Rõ ràng và chính xác, cảm ơn :) – Benj

+2

Tôi yêu bạn rất nhiều ngay bây giờ –