Skip to content

fix(ui): unnest action forms so Finalizar/Remover actually work (v1.38.6) - #70

Merged
iscarelli merged 1 commit into
mainfrom
fix/nested-form-submit
Aug 7, 2026
Merged

fix(ui): unnest action forms so Finalizar/Remover actually work (v1.38.6)#70
iscarelli merged 1 commit into
mainfrom
fix/nested-form-submit

Conversation

@iscarelli

Copy link
Copy Markdown
Owner

The bug

Clicking "Finalizar Spool" on the spool edit page flashed "Rolo atualizado" and left the spool active — it saved the edit instead of finalizing. The "Marcar spool como finalizado?" confirmation never appeared either.

A sibling instance of the same defect: the admin-only "Remover" button on the filament edit page saved the filament instead of deleting it, also without confirmation.

Root cause

Both action forms were written inside the edit form. HTML5 forbids nested forms, so the browser parser discards the inner <form> tag and reassigns its type="submit" button to the outer form. The POST therefore went to the edit route.

That also explains the missing confirmation: the submit listener in static/spool.js:24 reads data-sc-confirm off e.target, and the form carrying the attribute did not exist in the DOM.

Finalizing from the spool list (templates/spools/list.html:106) was never affected — there the form is a sibling, not nested. That working path is what confirmed the backend was fine: routes/spools.py:193-198 and database.py:818-821 needed no change.

The fix

Each action form moves out of the edit form and the button binds to it via the HTML5 form attribute, so the button stays exactly where it was in the flex row. The ms-auto right-alignment migrates from the form to the button. static/csrf.js keeps injecting the token, as it does for every POST form.

Tests

New tests/test_nested_form.py (9 tests) parses the rendered HTML and fails on any nested form. A route-level test cannot catch this class of bug, since the routes were always correct — so the suite grows a check at the layer that actually broke.

Verified the regression tests fail without the template fix (6 of the 9 go red) and pass with it. Full suite: 196 passed.

🤖 Generated with Claude Code

…8.6)

The "Finalizar Spool" button on the spool edit page submitted the edit
form instead of the deactivate route: it flashed "Rolo atualizado" and
left the spool active. Same defect hit the admin-only "Remover" button
on the filament edit page.

Root cause: both action forms were written inside the edit form. HTML5
forbids nested forms, so the browser parser drops the inner <form> tag
and the submit button is reassigned to the outer form. This also killed
the data-sc-confirm dialog, since the form carrying the attribute never
existed in the DOM. Finalizing from the spool list was never affected
(there the form is a sibling, not nested).

Fix: move each action form out of the edit form and bind the button
with the HTML5 form attribute, keeping the button in place in the flex
row (ms-auto migrates from the form to the button). csrf.js still
injects the token, as it does for every POST form.

Adds tests/test_nested_form.py, which parses the rendered HTML and
fails if any form is nested — a route-level test cannot catch this,
since the routes were always correct.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@iscarelli
iscarelli merged commit 41e3989 into main Aug 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant