Event.preventDefault()不起作用,表单提交了两次

时间:2019-06-30 19:34:02

标签: javascript html ruby-on-rails forms

我有两个页面,两种形式基本相同,但带有stripe元素,但是其中一个具有多余的字段,而另一个则没有。

带有多余字段event.preventDefault()的表单似乎并没有停止提交表单,因此该表单被提交了两次,但是没有多余字段的表单却没有提交。

为什么一种形式isTrusted === true而另一种形式isTrusted === false?是什么控制的?

这可能是preventDefault()无法正常工作的原因吗?

经过更多测试,我发现:

<%= form_tag add_card_path(@product.id), id: "payment-form" do

不会提交两次,但是

<%= form_with add_card_path(@product.id), id: "payment-form" do 

提交两次,因此preventDefault()不起作用。

为什么会这样?

<%= form_tag add_card_path(@product.id), id: "payment-form" do %>
  <div class="form-row">
    <div id="card-errors" role="alert" class="col"></div>
  </div>
  <div class="form-row">
    <div id="card-element" class="col"></div>
  </div>
  <div class="form-row mt-3">
    <button class="btn_spinner col btn md-width-auto btn-primary">Add Card</button>
  </div>
<% end %>

Javascript:

// Handle form submission.
var form = document.getElementById(thatInstance.formId);
form.addEventListener('submit', function (event) {
  event.preventDefault();
  debugger;
  thatInstance.createStripeToken();
});

从调试器检查事件对象:

工作页面:

事件对象:

bubbles: true
cancelBubble: false
cancelable: true
composed: false
currentTarget: <form id="payment-form">
defaultPrevented: true
eventPhase: 2
isTrusted: false
returnValue: false
srcElement: <form id="payment-form">
target: <form id="payment-form">
timeStamp: 20826
type: "submit"

非工作页:

事件对象:

bubbles: true
cancelBubble: false
cancelable: true
composed: false
currentTarget: <form id="payment-form">
defaultPrevented: true
eventPhase: 2
isTrusted: true
returnValue: false
srcElement: <form id="payment-form">
target: <form id="payment-form">
timeStamp: 23652
type: "submit"

解决方案:

需要data-remote === false,不确定为什么。

Form_with有data-remote === true,而form_tag有data-remote === false

2 个答案:

答案 0 :(得分:0)

来自MDNEvent.isTrusted

  

Event界面的 isTrusted 只读属性是一个Boolean,它是由用户生成事件时的true操作,以及false何时通过脚本创建或修改事件或通过EventTarget.dispatchEvent()调度事件。

来自MDNEvent.preventDefault()

  

致电 preventDefault() 进行不可取消的事件,例如通过EventTarget.dispatchEvent()分派的事件,但未指定cancelable: true无效。

答案 1 :(得分:0)

在Rails中,form_with()和form_tag()的操作方式不同。

根据本文:

https://m.patrikonrails.com/rails-5-1s-form-with-vs-old-form-helpers-3a5f72a8c78a

“默认情况下,由form_with生成的所有表单都将由XHR(Ajax)请求提交。不需要指定remote:true,因为必须使用form_tag和form_for。”

因此,通过将remote设置为false(本地:true)或使用form_tag解决了此问题,因为.preventDefault停止了本地提交,而不是ajax提交。