Как я могу отправить форму об изменении ввода с помощью 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 -->