Rails ajax表单:如何在表单发送之前修复字段

时间:2015-02-07 18:53:08

标签: ruby-on-rails ajax braintree braintree-rails

在Rails 4.1.8中

我正在处理付款表单(Braintree付款),我希望它能通过Ajax工作。我不能使用标准的Braintree表单设置,因为它没有提供onSuccess和onError方法。但我可以使用一个特殊的javascript函数来查看字段,与Braintree服务器对话并返回一个随机数,然后在表单中发送。所以......

我创建了一个表单并设置了remote:true。这允许rails_ujs接管并将表单ajax到我的服务器。但在此之前,我必须打电话给Braintree并得到答复。他们提供的javascript函数执行异步调用。因此,我无法加入Rails' ajax:之前'回调因为Braintree javascript调用在' ajax之前返回一个值:之前'已传递给主rails_ujs,它将表单内容发送到服务器,因此我在服务器端得到一个空白字段。

Braintree提供的js函数确实有正常的回调,所以我可以挂钩成功回调并触发表单提交。所以我试着勾选提交按钮上的click事件,禁用默认值,调用Braintree,然后当我得到一个成功的响应时,我打电话

$('#myForm').submit()

实际发送数据的是哪个,但它是正常的非xhr POST。深入挖掘我发现rails_ujs的行为不像是挂钩到form.submit()事件,而是挂钩提交按钮click()事件。因此,通过捕获该事件,阻止默认行为,调用Braintree然后触发表单上的submit()事件,我完全删除了Rails ajax的东西。

关键问题是如何在不单击表单内的提交按钮的情况下触发Rails ajax表单进行远程发送?

作为一种解决方法,我可以执行手动编码的$ .ajax调用,或者在表单上放置一个隐藏的提交按钮,然后执行Braintree调用的另一个可见按钮,然后触发隐藏的提交按钮。这将至少让所有的Rails表单提交给我的csrf令牌。但是我想知道为什么我不能调用form.submit()

1 个答案:

答案 0 :(得分:3)

删除远程:您的表单为true,并使用原生javascript交换提交表单。



braintree.setup(
  braintree_token,
  'dropin', {
  container: 'dropin',
  paymentMethodNonceReceived: function (event, nonce) {
    $('.braintree-checkout').append("<input type='hidden' name='payment_method_nonce' value='"+ nonce +"'></input>");
    $.ajax({
      url: braintree_charge_path,
      type: 'post',
      data: $('.braintree-checkout').serialize(),
      context: $('.braintree-checkout'),
      beforeSend: function(evt, xhr, settings){
        // Stuff to do before braintree submits, e.g. loading screen
      },
      complete: function(evt, xhr, status){
        // Stuff that has to be done regardless of success or error 
      },
      error: function(evt, xhr, status, error){
        // Your error messages
      }
    });
  }
});
&#13;
&#13;
&#13;

通过这种方式,您可以完全控制表单流程