diff --git a/app/webpacker/controllers/toggle_control_controller.js b/app/webpacker/controllers/toggle_control_controller.js index 6beea90ec2..a6e48cd236 100644 --- a/app/webpacker/controllers/toggle_control_controller.js +++ b/app/webpacker/controllers/toggle_control_controller.js @@ -1,5 +1,7 @@ import { Controller } from "stimulus"; +const BUTTON_TYPES = ['submit', 'button']; + // Toggle state of a control based on a condition. // // 1. When an action occurs on an element, @@ -57,10 +59,8 @@ export default class extends Controller { target.disabled = disable; }); - // Focus first when enabled - if (!disable) { - this.controlTargets[0].focus(); - } + // Focus first when enabled and it's not a button + if (!disable) this.#focusFieldControl(); } #toggleDisplay(show) { @@ -69,9 +69,7 @@ export default class extends Controller { }); // Focus first when displayed - if (show) { - this.controlTargets[0].focus(); - } + if (show) this.#focusFieldControl(); } // Return input's value, but only if it would be submitted by a form @@ -81,4 +79,10 @@ export default class extends Controller { return input.value; } } + + #focusFieldControl() { + const control = this.controlTargets[0]; + const isButton = BUTTON_TYPES.includes(control.type); + if(!isButton) control.focus(); + } } diff --git a/spec/javascripts/stimulus/toggle_control_controller_test.js b/spec/javascripts/stimulus/toggle_control_controller_test.js index dca6e3df0e..12746389e7 100644 --- a/spec/javascripts/stimulus/toggle_control_controller_test.js +++ b/spec/javascripts/stimulus/toggle_control_controller_test.js @@ -71,11 +71,12 @@ describe("ToggleControlController", () => { `; }); - it("Enables when input is filled", () => { + it("Enables when input is filled and focuses the control", () => { input.value = "a" input.dispatchEvent(new Event("input")); expect(control.disabled).toBe(false); + expect(document.activeElement).toBe(control); }); it("Disables when input is emptied", () => { @@ -88,6 +89,37 @@ describe("ToggleControlController", () => { expect(control.disabled).toBe(true); }); }); + describe("with button as control target", () => { + beforeEach(() => { + document.body.innerHTML = `