如何使用 Turbo Streams 提交有关输入更改的表格?

tsv*_*der 24 ruby-on-rails-5 hotwire-rails turbo

我有一个表单,我想在任何输入字段发生更改时自动提交。我正在使用 Turbo Streams,如果我使用onchange: "this.form.submit()"它,它不会被 Turbo Streams 捕获,并且 Rails 使用标准 HTML 响应。单击提交按钮时效果很好。我该如何解决这个问题?

wnm*_*wnm 61

在 hotwire 论坛上有一个讨论form.submit(),Mark Godwin 在其中找到了为什么不使用 Turbo 的原因:

\n
\n

Turbo拦截了表单提交事件,但奇怪的是,JS formElement.submit()方法并没有触发submit事件。

\n
\n

雅各布·达达里奥发现你可以使用form.requestSubmit()

\n
\n

事实证明,turbo-stream 机制监听表单提交事件,并且由于某种原因,submit() 函数不会发出表单提交事件。这意味着它\xe2\x80\x99 将返回正常的 HTML 响应。也就是说,看起来 \xe2\x80\x99 有另一个方法 requestSubmit() ,它确实发出提交事件。

\n
\n

因此,您可以稍微更改代码,requestSubmit() 如果浏览器支持则使用它,submit()如果不支持则使用: \n

\n
onchange: "this.form.requestSubmit ? this.form.requestSubmit() : this.form.submit()"\n
Run Code Online (Sandbox Code Playgroud)\n
\n


\n更新:

\n

正如BenKoshy指出的,在 Turbo 7.1.0 中,添加了一个 polyfill ,因此您可以form.requestSubmit()在不检查浏览器支持的情况下使用,因此您可以将其添加到您的输入字段中:

\n
onchange: "this.form.requestSubmit()"\n
Run Code Online (Sandbox Code Playgroud)\n

  • 我确认这有效。 (7认同)
  • 有一个polyfill可以开箱即用地处理浏览器兼容性问题,只要你安装最新版本的turbo,就可以了。 (3认同)

Aid*_*les 3

我需要为具有大量表单的应用程序实现此功能。我最终使用了刺激。下面是整个控制器:

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()
  }
}
Run Code Online (Sandbox Code Playgroud)

在这里,它以具有单个文本输入的形式使用。注意控制器连接到表单,而不是输入。

<%= 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 -->
Run Code Online (Sandbox Code Playgroud)