我有一个表单,我想在任何输入字段更改时自动提交。我正在使用 Turbo Streams,如果我使用onchange: "this.form.submit()"
它,Turbo Streams 不会捕获它,并且 Rails 使用标准的 HTML 响应。单击提交按钮时它工作正常。我该如何解决这个问题?
问问题
2081 次
2 回答
8
hotwire 论坛上有一个讨论,马克·戈德温(Mark Godwin)找出了为什么form.submit()
不使用 turbo:
Turbo 拦截了表单提交事件,但是奇怪的是,JS 的 formElement.submit() 方法并没有触发提交事件。
Jacob Daddario发现您可以form.requestSubmit()
改用:
事实证明,turbo-stream 机制会监听表单提交事件,并且由于某种原因 submit() 函数不会发出表单提交事件。这意味着它将带回正常的 HTML 响应。也就是说,看起来还有另一种方法 requestSubmit() 确实发出了提交事件。
所以你可以稍微改变你的代码,requestSubmit()
如果浏览器支持就使用,
submit()
如果不支持就使用:
onchange: "this.form.requestSubmit ? this.form.requestSubmit() : this.form.submit()"
更新:
正如BenKoshy指出的那样,在 Turbo 7.1.0 中,添加了一个 polyfill,因此您可以form.requestSubmit()
在不检查浏览器支持的情况下使用,因此您可以将其添加到您的输入字段中:
onchange: "this.form.requestSubmit()"
于 2021-10-12T08:59:18.197 回答
2
我需要为一个有很多表单的应用程序实现这个。我最终使用了 Stimulus。下面是整个控制器:
import { Controller } from "stimulus"
const _ = require("lodash")
export default class extends Controller {
connect() {
let that = this;
that.element.addEventListener('change', _.debounce(that.handleChange, 500))
}
handleChange(event) {
event.preventDefault()
// event.target.name // => "user[answer]"
// event.target.value // => <user input string>
event.target.form.requestSubmit()
}
}
在这里,它以具有单个文本输入的形式使用。注意控制器附加到表单,而不是输入。
<%= turbo_frame_tag dom_id(form_model) do %>
<%= form_with model: form_model,
format: :turbo_stream,
html: { data: { controller: "buttonless-form" } } do |f| %>
<%= f.hidden_field :question_id, value: question.id %>
<%= f.text_field :answer_value, class: "input shadow wide", placeholder: "Enter your answer here" %>
<% end %>
<div id=<%= "question_#{question.id}_output" %>>
<p> <!-- feedback to the user shows up here via Turbo -->
</div>
<% end %> <!-- end turbo frame -->
于 2021-08-05T18:16:48.967 回答