From f1bde676c6c985d653974008af592f5d31486e28 Mon Sep 17 00:00:00 2001 From: Guillem Arias Date: Mon, 11 May 2026 19:32:50 +0200 Subject: [PATCH] fix(savings_goals/new): trap Enter on step 1; add funding-accounts hint - Pressing Enter inside a step-1 input (Name, Target amount, Target date) used to fire the form-implicit-submission against the sr-only submit button, jumping straight to POST /savings_goals and skipping step 2 entirely (no initial contribution, no review). - New blockEnter action on the form re-routes Enter to next() when currentStep === 1, mirroring the Continue button. Notes textarea is exempt so newlines work. - Add an inline hint under the funding-accounts label so users know up front what the field controls; previously the only feedback was a tiny "must pick one" error after Continue. --- .../controllers/savings_goal_stepper_controller.js | 9 +++++++++ app/views/savings_goals/_form_stepper.html.erb | 7 +++++-- config/locales/views/savings_goals/en.yml | 1 + 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/javascript/controllers/savings_goal_stepper_controller.js b/app/javascript/controllers/savings_goal_stepper_controller.js index 9c5c4b5f3..a3d6bac2b 100644 --- a/app/javascript/controllers/savings_goal_stepper_controller.js +++ b/app/javascript/controllers/savings_goal_stepper_controller.js @@ -49,6 +49,15 @@ export default class extends Controller { this.refreshSubmitState(); } + blockEnter(event) { + if (this.currentStep !== 1) return; + // Allow Enter in the notes textarea so newlines work. + if (event.target.tagName === "TEXTAREA") return; + event.preventDefault(); + // Mirror Continue: validate + advance instead of swallowing silently. + this.next(); + } + footerLeft(event) { event.preventDefault(); this.back(); diff --git a/app/views/savings_goals/_form_stepper.html.erb b/app/views/savings_goals/_form_stepper.html.erb index 97b61dbf1..5779f8ada 100644 --- a/app/views/savings_goals/_form_stepper.html.erb +++ b/app/views/savings_goals/_form_stepper.html.erb @@ -18,7 +18,7 @@ - <%= styled_form_with model: savings_goal, url: savings_goals_path, class: "space-y-4" do |f| %> + <%= styled_form_with model: savings_goal, url: savings_goals_path, class: "space-y-4", data: { action: "keydown.enter->savings-goal-stepper#blockEnter" } do |f| %>

<%= t("savings_goals.form_stepper.step1.heading") %>

@@ -53,7 +53,10 @@
- <%= t("savings_goals.form_stepper.step1.fields.funding_accounts") %> +
+ <%= t("savings_goals.form_stepper.step1.fields.funding_accounts") %> +

<%= t("savings_goals.form_stepper.step1.fields.funding_accounts_hint") %>

+
<% grouped = linkable_accounts.group_by { |a| a.subtype.to_s.presence || "other" } %> <% grouped.each_with_index do |(subtype, accts), group_idx| %> diff --git a/config/locales/views/savings_goals/en.yml b/config/locales/views/savings_goals/en.yml index a2035c4c0..87a87113b 100644 --- a/config/locales/views/savings_goals/en.yml +++ b/config/locales/views/savings_goals/en.yml @@ -225,6 +225,7 @@ en: notes_summary: Add notes (optional) notes_placeholder: A reminder for future you… funding_accounts: Funding accounts + funding_accounts_hint: Balances in these accounts will count toward the goal. subtypes: checking: Checking savings: Savings