Handle form errors with a stimulus class
We need to keep the focus in place when submitting the form. We are using a data-turbo-permanent for that. We were rendering the error form with a turbo stream. The problem was that turbo streams ignore permanent elements as per this https://github.com/hotwired/turbo/pull/688, so the system wasn't updating the input field as expected. Handling this as the stimulus level will also help with managing additional error states (such as the one we need for confirmations).
This commit is contained in:
@@ -16,7 +16,7 @@ class CommandsController < ApplicationController
|
||||
redirect_back_or_to root_path
|
||||
end
|
||||
else
|
||||
render turbo_stream: turbo_stream.replace("commands_form", partial: "commands/form", locals: { error: true })
|
||||
head :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -2,10 +2,25 @@ import { Controller } from "@hotwired/stimulus"
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = [ "input" ]
|
||||
static classes = [ "error" ]
|
||||
|
||||
// Actions
|
||||
|
||||
focus() {
|
||||
this.inputTarget.focus()
|
||||
}
|
||||
|
||||
handleSubmit(event) {
|
||||
if (event.detail.success) {
|
||||
event.target.reset()
|
||||
} else {
|
||||
this.#handleErrorResponse(event.detail.fetchResponse.response.status)
|
||||
}
|
||||
}
|
||||
|
||||
#handleErrorResponse(code) {
|
||||
if (code == 422) {
|
||||
this.element.classList.add(this.errorClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,6 @@ export default class extends Controller {
|
||||
event.target.select()
|
||||
}
|
||||
|
||||
reset(event) {
|
||||
this.element.reset()
|
||||
}
|
||||
|
||||
showPicker(event) {
|
||||
if ("showPicker" in HTMLInputElement.prototype) {
|
||||
event.target.showPicker()
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
<% has_error = local_assigns.fetch(:error, false) %>
|
||||
|
||||
<%= form_tag commands_path,
|
||||
id: "commands_form",
|
||||
class: [ "flex align-center gap-half", { "has-error" => has_error } ],
|
||||
data: { controller: "form", action: "turbo:submit-end->form#reset turbo:submit-end->commands#focus keydown.meta+k@document->commands#focus" } do %>
|
||||
class: [ "flex align-center gap-half" ],
|
||||
data: {
|
||||
controller: "form commands",
|
||||
commands_error_class: "has-error",
|
||||
action: "turbo:submit-end->commands#focus keydown.meta+k@document->commands#focus turbo:submit-end->commands#handleSubmit"
|
||||
} do %>
|
||||
<label class="terminal__label txt-nowrap" for="fizzy_do">Fizzy do ></label>
|
||||
|
||||
<%= text_field_tag "command", has_error ? params[:command] : nil,
|
||||
<%= text_field_tag "command", nil,
|
||||
autocomplete: "off",
|
||||
autocorrect: "off",
|
||||
autocapitalize: "off",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<%= tag.div class: "terminal full-width flex flex-column gap justify-end", data: {
|
||||
controller: "toggle-class commands",
|
||||
controller: "toggle-class",
|
||||
toggle_class_toggle_class: "terminal--open" } do %>
|
||||
<%= turbo_frame_tag :recent_commands, src: commands_path, refresh: "morph" %>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user