Skip to content

feat(Form): add HTML5 validation to programmatic submit#6002

Open
IlyaSemenov wants to merge 1 commit intonuxt:v4from
IlyaSemenov:feat/form-html5-validation
Open

feat(Form): add HTML5 validation to programmatic submit#6002
IlyaSemenov wants to merge 1 commit intonuxt:v4from
IlyaSemenov:feat/form-html5-validation

Conversation

@IlyaSemenov
Copy link
Contributor

@IlyaSemenov IlyaSemenov commented Feb 7, 2026

🔗 Linked issue

Resolves #5139.

❓ Type of change

  • 📖 Documentation (updates to the documentation or readme)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

When calling form.submit() programmatically, the form now triggers native HTML5 validation (required, type, min, max, etc.) before submission. If validation fails, submission is prevented and browser validation messages are displayed.

This is particularly useful when the submit button is outside the form element, such as in modal footers.

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

💡 Notes

This adds an inner template ref within the UForm component. I could instead use document.getElementById(), but then the tests wouldn't work because the fixture mount helper doesn't actually insert the mounted component into document.body. I could rework the helper to address that, but the template ref approach seemed cleaner as it introduced less coupling overall.

EDIT: As suggested by coderabbit, this also fixes nearby documentation formatting errors (not directly affected by the PR).

@github-actions github-actions bot added the v4 #4488 label Feb 7, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 7, 2026

📝 Walkthrough

Walkthrough

Adds HTML5 validation to programmatic form submission: Form.vue introduces a formEl ref and calls reportValidity() to abort submission when native validation fails; the same check is applied in the exposed api.submit. Tests and a fixture were added covering programmatic submit behavior for invalid/valid forms and nested-form behavior (nested forms render as div and do not trigger HTML5 validation). Documentation was updated with an HTML5 validation section and expanded API docs. No public code signatures changed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding HTML5 validation to the programmatic form submit method.
Description check ✅ Passed The description is directly related to the changeset, explaining the HTML5 validation feature, its use case with modal footers, and the implementation approach chosen.
Linked Issues check ✅ Passed The PR implementation fully addresses issue #5139 by adding HTML5 validation via reportValidity() check in the form.submit() method, preventing submission on validation failure, and supporting modal footer scenarios.
Out of Scope Changes check ✅ Passed All changes are directly related to the objective: Form component ref binding, validation check in submit, tests for HTML5 validation, fixture for testing, and documentation updates describing the new behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/content/docs/2.components/form.md (1)

229-230: ⚠️ Potential issue | 🟡 Minor

Pre-existing typo: missing | (pipe) operator in type signatures.

Lines 229 and 230 are missing the union pipe between keyof T and RegExp:

  • Line 229: getErrors(path?: keyof T RegExp) → should be keyof T | RegExp
  • Line 230: setErrors(errors: FormError[], name?: keyof T RegExp) → should be keyof T | RegExp

Not introduced by this PR, but worth fixing while you're editing this table.

🧹 Nitpick comments (2)
src/runtime/components/Form.vue (1)

105-105: Consider narrowing the ref type to reflect the actual runtime possibilities.

formEl is typed as ref<HTMLFormElement>() but it can also hold an HTMLDivElement when the form is nested. The instanceof guard at Line 403 handles this at runtime, but the type is slightly misleading.

Suggested type change
-const formEl = ref<HTMLFormElement>()
+const formEl = ref<HTMLFormElement | HTMLDivElement>()
test/components/Form.spec.ts (1)

645-667: Consider using afterEach for spy cleanup to prevent leaks on test failure.

If a test throws before reaching mockRestore(), the spy leaks to subsequent tests. A safer pattern:

Suggested pattern
   describe('HTML5 validation', () => {
+    let reportValiditySpy: ReturnType<typeof vi.spyOn> | undefined
+
+    afterEach(() => {
+      reportValiditySpy?.mockRestore()
+    })
+
     it('programmatic submit() triggers HTML5 validation and prevents submission when invalid', async () => {
       const onSubmit = vi.fn()
-      const reportValiditySpy = vi.spyOn(HTMLFormElement.prototype, 'reportValidity').mockReturnValue(false)
+      reportValiditySpy = vi.spyOn(HTMLFormElement.prototype, 'reportValidity').mockReturnValue(false)
       // ... rest of test without mockRestore at the end

@IlyaSemenov IlyaSemenov force-pushed the feat/form-html5-validation branch from d0cdb27 to e2d3435 Compare February 7, 2026 06:44
@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 7, 2026

npm i https://pkg.pr.new/@nuxt/ui@6002

commit: d0cdb27

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@test/components/Form.spec.ts`:
- Around line 647-650: The test file uses afterEach but it's not imported from
vitest causing a build error; update the vitest import (the import statement
that currently brings in functions like describe/it/etc.) to also include
afterEach so the afterEach(() => { reportValiditySpy?.mockRestore();
reportValiditySpy = undefined }) call resolves, and ensure the symbol name is
spelled exactly as afterEach to match the test hook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v4 #4488

Projects

None yet

Development

Successfully merging this pull request may close these issues.

form.submit() to perform HTML5 validation

1 participant