Как я могу отправить форму об изменении ввода с помощью Turbo Streams?

У меня есть форма, которую я хочу отправлять автоматически при изменении любого поля ввода. Я использую Turbo Streams, и если я использую onchange: "this.form.submit()"он не захватывается Turbo Streams, а Rails использует стандартный ответ HTML. Он отлично работает при нажатии кнопки отправки. Как я могу обойти это?

2 ответа

На форуме hotwire есть обсуждение , где Марк Годвин выяснил, почему form.submit() не работает с турбо:

Turbo перехватывает события отправки формы, но, как ни странно, метод JS formElement.submit () не запускает событие отправки.

И Джейкоб Даддарио выясняет, что вы можете использовать form.requestSubmit() вместо:

Оказывается, механизм турбо-потока отслеживает события отправки формы, и по какой-то причине функция submit () не генерирует событие отправки формы. Это означает, что он вернет обычный HTML-ответ. Тем не менее, похоже, что есть еще один метод, requestSubmit(), который выдает событие отправки.

Таким образом, вы можете немного изменить свой код и использовать requestSubmit() если браузер поддерживает это, и используйте submit() если не:

      onchange: "this.form.requestSubmit ? this.form.requestSubmit() : this.form.submit()"

Мне нужно реализовать это для приложения с большим количеством форм. Я закончил использовать 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 -->
Другие вопросы по тегам