Rails ajax 表单:如何在发送表单之前修复字段
Rails ajax form: how to fix up fields before the form gets sent
在Rails 4.1.8
我正在处理付款表格(Braintree 付款),我希望它通过 Ajax 工作。我不能使用标准的 Braintree 表单设置,因为它不提供 onSuccess 和 onError 方法。但是我可以使用一个特殊的 javascript 函数来查看字段,与 Braintree 服务器对话并 returns 随机数,然后在表单中发送。所以...
我创建了一个表单并设置了 remote: true。这允许 rails_ujs 接管并将表单 ajax 发送到我的服务器。但在此之前,我必须向 Braintree 发送呼叫并获得响应。他们提供的 javascript 函数执行异步调用。因此我无法连接到 Rails 'ajax:before' 回调,因为 Braintree javascript 在 'ajax:before' 传递给主 [=] 之后调用 returns 一个值31=] 将表单内容发送到服务器,因此我在服务器端得到一个空白字段。
Braintree提供的js函数确实有正常的回调,所以我可以挂钩成功回调并触发表单提交。所以我尝试连接到提交按钮上的点击事件,禁用默认设置,调用 Braintree,然后当我得到成功响应时,我调用
$('#myForm').submit()
它确实发送了数据,但它是一个普通的非 xhr POST。深入挖掘,我发现 rails_ujs 的行为不像是挂钩到 form.submit() 事件,而是挂钩到提交按钮的 click() 事件。因此,通过捕获该事件、防止默认行为、调用 Braintree 然后在表单上触发 submit() 事件,我将完全删除 Rails ajax 内容。
关键问题是如何在不单击表单内的提交按钮的情况下触发 Rails ajax 表单进行远程发送?
作为一种变通方法,我可以执行一个手动编码的 $.ajax 调用,或者在表单上放置一个隐藏的提交按钮和另一个执行 Braintree 调用的可见按钮,然后触发对隐藏提交的点击按钮。这至少会让所有 Rails 表单提交,并为我完成 csrf 令牌内容。但我想知道为什么我不能调用 form.submit()
为您的表单移除 remote: 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
}
});
}
});
这样您就可以完全控制表单流程
在Rails 4.1.8
我正在处理付款表格(Braintree 付款),我希望它通过 Ajax 工作。我不能使用标准的 Braintree 表单设置,因为它不提供 onSuccess 和 onError 方法。但是我可以使用一个特殊的 javascript 函数来查看字段,与 Braintree 服务器对话并 returns 随机数,然后在表单中发送。所以...
我创建了一个表单并设置了 remote: true。这允许 rails_ujs 接管并将表单 ajax 发送到我的服务器。但在此之前,我必须向 Braintree 发送呼叫并获得响应。他们提供的 javascript 函数执行异步调用。因此我无法连接到 Rails 'ajax:before' 回调,因为 Braintree javascript 在 'ajax:before' 传递给主 [=] 之后调用 returns 一个值31=] 将表单内容发送到服务器,因此我在服务器端得到一个空白字段。
Braintree提供的js函数确实有正常的回调,所以我可以挂钩成功回调并触发表单提交。所以我尝试连接到提交按钮上的点击事件,禁用默认设置,调用 Braintree,然后当我得到成功响应时,我调用
$('#myForm').submit()
它确实发送了数据,但它是一个普通的非 xhr POST。深入挖掘,我发现 rails_ujs 的行为不像是挂钩到 form.submit() 事件,而是挂钩到提交按钮的 click() 事件。因此,通过捕获该事件、防止默认行为、调用 Braintree 然后在表单上触发 submit() 事件,我将完全删除 Rails ajax 内容。
关键问题是如何在不单击表单内的提交按钮的情况下触发 Rails ajax 表单进行远程发送?
作为一种变通方法,我可以执行一个手动编码的 $.ajax 调用,或者在表单上放置一个隐藏的提交按钮和另一个执行 Braintree 调用的可见按钮,然后触发对隐藏提交的点击按钮。这至少会让所有 Rails 表单提交,并为我完成 csrf 令牌内容。但我想知道为什么我不能调用 form.submit()
为您的表单移除 remote: 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
}
});
}
});
这样您就可以完全控制表单流程