2

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

4

2 回答 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 回答