fix(rules): add required_if rule for conditional field validation#5138
fix(rules): add required_if rule for conditional field validation#5138
Conversation
) The required_if rule was listed in the README and i18n locale files but was missing from the rules package since a prior refactor removed it. This re-implements the rule using the current simple validator pattern, enabling cross-field conditional required validation that works correctly on every submission. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 92efca1 The changes in this PR will be included in the next version bump. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Deploy Preview for vee-validate-docs canceled.
|
✅ Deploy Preview for vee-validate-v5 ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
Re-introduces the required_if validation rule in @vee-validate/rules to support conditional “required when another field matches” validation patterns, restoring functionality that was previously removed but still documented.
Changes:
- Adds a new
required_ifrule implementation with support for array and object params. - Exports
required_iffrom the rules entrypoint (all+ named export). - Adds unit tests and a changeset entry for the patch release.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
packages/rules/src/required_if.ts |
Implements the required_if validator logic. |
packages/rules/src/index.ts |
Adds required_if to exported rules and the all map. |
packages/rules/tests/required_if.spec.ts |
Introduces unit tests for required_if. |
.changeset/fix-4868-required-if-resubmit.md |
Adds release note for publishing the change. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return true; | ||
| } | ||
|
|
||
| return !isEmpty(value); |
There was a problem hiding this comment.
When the condition is met, this returns !isEmpty(value), which doesn't match the semantics of the existing required rule (e.g. ' ' and false will incorrectly be considered valid). To keep behavior consistent across rules, delegate to the required validator (or mirror its trim/boolean handling) when isRequired is true.
| } else { | ||
| isRequired = !isNullOrUndefined(target) && !isEmptyArray(target) && !!String(target).trim().length; |
There was a problem hiding this comment.
The "truthy target" branch doesn't treat false as falsy, so a boolean target of false will still make the field required (because String(false).trim().length is non-zero). Consider using the same presence check as the required rule for the target (e.g. required(target)), so false/empty values don't trigger the condition unexpectedly.
| } else { | |
| isRequired = !isNullOrUndefined(target) && !isEmptyArray(target) && !!String(target).trim().length; | |
| } else if (typeof target === 'boolean') { | |
| // For boolean targets, only `true` should make the field required. | |
| isRequired = target; | |
| } else { | |
| isRequired = | |
| !isNullOrUndefined(target) && | |
| !isEmptyArray(target) && | |
| !!String(target).trim().length; |
| test('validates required_if with array params', () => { | ||
| // target has a matching value, field is empty -> invalid | ||
| expect(validate('', ['Online Banking', 'Online Banking'])).toBe(false); | ||
| expect(validate(null, ['Online Banking', 'Online Banking'])).toBe(false); | ||
| expect(validate(undefined, ['Online Banking', 'Online Banking'])).toBe(false); | ||
| expect(validate([], ['Online Banking', 'Online Banking'])).toBe(false); | ||
|
|
||
| // target has a matching value, field is filled -> valid | ||
| expect(validate('Nabil', ['Online Banking', 'Online Banking'])).toBe(true); | ||
|
|
||
| // target does not match any value, field is empty -> valid (not required) | ||
| expect(validate('', ['Cash', 'Online Banking'])).toBe(true); | ||
| expect(validate(null, ['Cash', 'Online Banking'])).toBe(true); | ||
| expect(validate(undefined, ['Cash', 'Online Banking'])).toBe(true); | ||
| }); |
There was a problem hiding this comment.
The new tests don't cover parity with the existing required rule once the field becomes required (e.g. whitespace-only strings and false should fail, and 0 should pass). Adding those cases would prevent regressions and ensure required_if matches required behavior for the validated value.
| "@vee-validate/rules": patch | ||
| --- | ||
|
|
||
| Fix required_if rule not re-evaluating on subsequent submissions (#4868) |
There was a problem hiding this comment.
The changeset summary says this fixes required_if not re-evaluating on subsequent submissions, but the PR primarily re-introduces the required_if rule into @vee-validate/rules. Please align the changeset text with the actual change so the published changelog is accurate (e.g. mention re-adding/restoring the rule).
Summary
required_ifvalidation rule to@vee-validate/rules, which was removed during a prior refactor but remained listed in the README and all i18n locale filesrequired_if:@target,val1,val2) and object params ({ target: '@field', values: ['val1'] })Closes #4868
Test plan
required_ifrule covering:🤖 Generated with Claude Code