使用Rails UJS,如何从函数中提交远程表单

19

我正在使用Rails UJS。我已经设置了一个表单,可以进行远程提交,如下:

<form accept-charset="UTF-8" action="/subscriptions" class="new_subscription form-horizontal" id="new_subscription" data-remote="true" data-type="json" method="POST">

我正在尝试找到一种从JavaScript函数中提交此表格的方法。 我尝试过:

var form$ = $("#new_subscription");
form$.get(0).submit();

但是这样做的问题是它会在没有远程数据的情况下提交表单,它会向服务器发送一个请求并刷新页面。有什么想法是怎么回事吗?有没有不同的方法可以提交一个远程表单?

谢谢

3个回答

44

对于那些使用jquery-ujs(Rails 5.0默认和以下版本),如Mikhail已经回答的那样,触发自定义jquery事件会起作用,例如:

$("#new_subscription").trigger("submit.rails");

对于那些在2017年遇到这个问题并使用Rails 5.1的人,答案将有所不同。Rails 5.1已经将jquery作为依赖项删除,因此用一个完全重写的rails-ujs来代替了jquery-ujs。请参见:http://weblog.rubyonrails.org/2017/4/27/Rails-5-1-final/

因此,您需要在rails-ujs中触发适当的CustomEvent对象:

目前,在文档(即RailsGuides)中还没有发布/推荐的方法来实现它,但是通过查看Rails源代码,有多种可选方案:

  1. Use Rails.fire function:

    nativeFormEl = $("#new_subscription")[0] // you need the native DOM element
    Rails.fire(nativeFormEl, 'submit')
    
  2. You could also programmatically call the Rails.handleRemote handler (the one that actually submits forms with data-remote=true via XHR:

    nativeFormEl = $("#new_subscription")[0] // you need the native DOM element
    Rails.handleRemote.call(nativeFormEl, event); // unfortunately, you cannot reference the previously created submit CustomEvent object by rails-ujs.js
    //  ... or ...
    Rails.handleRemote.call(nativeFormEl) // submits via XHR successfully, but throws an error after success callback at Rails.stopPropagation
    

我更喜欢选项1,因为它只是一个包装器,使用了更近期的Web API方法,即创建CustomEvent并通过dispatchEvent将其分派到EventTarget


1
选项1是Rails 5的真正答案!谢谢!运行得非常好。 - Brazhnyk Yuriy
1
可以确认选项1非常好用,但是在使用webpacker时访问Rails对象,你需要先执行import Rails from '@rails/ujs'; Rails.start()。请参考https://dev59.com/TlMI5IYBdhLWcg3wfbbN - Paul Odeon
想要补充说明的是,我目前在我的代码中使用以下内容:Rails.fire(nativeFormEl, 'ajax:success') -- 虽然这确实会触发 ajax:success 事件,但它传递了 Rails UJS 使用的 错误/旧 类型的 CustomEvent。新的 CustomEvent 类型在键 event.details 下有一个 3 项数组,而旧格式则没有。这很令人困惑,我不得不编写一个愚蠢的 if-then 语句来解决我的 Ajax 事件监听器中的代码处理问题。 - FireDragon

15

尝试触发submit.rails事件:

$("#new_subscription").trigger("submit.rails");

12
虽然这可能是几年前的正确答案,但现在已经不再正确了。自从Rails 5.1用rails-ujs替换了jquery-ujs后,jQuery依赖已被移除,自定义事件也发生了变化。我偶然看到了你的回答,只是为了确认这不再是答案。一旦我验证了最新答案,就会发布新的内容。 - padi

-1

尝试自己做一个Ajax请求:

$('#new_suscription').submit(function(){
  /*do whatever you want here*/
  $.post('/subscriptions',$(this).serialize(),function(){},'script');
}

这样,您可以使用表单数据进行POST请求,并将响应作为脚本执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接