Skip to content

Commit 09fff77

Browse files
committed
fix(form-core): validateAllFields not validating with form level validators
1 parent 070caca commit 09fff77

2 files changed

Lines changed: 101 additions & 6 deletions

File tree

packages/form-core/src/FormApi.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,18 +1548,21 @@ export class FormApi<
15481548
*/
15491549
validateAllFields = async (cause: ValidationCause) => {
15501550
const fieldValidationPromises: Promise<ValidationError[]>[] = [] as any
1551+
15511552
batch(() => {
15521553
void (Object.values(this.fieldInfo) as FieldInfo<any>[]).forEach(
15531554
(field) => {
15541555
if (!field.instance) return
15551556
const fieldInstance = field.instance
1557+
15561558
// Validate the field
15571559
fieldValidationPromises.push(
15581560
// Remember, `validate` is either a sync operation or a promise
15591561
Promise.resolve().then(() =>
15601562
fieldInstance.validate(cause, { skipFormValidation: true }),
15611563
),
15621564
)
1565+
15631566
// If any fields are not touched
15641567
if (!field.instance.state.meta.isTouched) {
15651568
// Mark them as touched

packages/form-core/tests/FormApi.spec.ts

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1945,7 +1945,79 @@ describe('form api', () => {
19451945
).toBeUndefined()
19461946
})
19471947

1948-
it('should validate all fields consistently', async () => {
1948+
it('should validate all fields consistently - form level onChange validators', async () => {
1949+
const form = new FormApi({
1950+
defaultValues: {
1951+
firstName: '',
1952+
lastName: '',
1953+
},
1954+
validators: {
1955+
onChange: ({ value }) => {
1956+
return {
1957+
fields: {
1958+
firstName: value.firstName.length > 0 ? undefined : 'is required',
1959+
lastName: value.lastName.length > 0 ? undefined : 'is required',
1960+
},
1961+
}
1962+
},
1963+
},
1964+
})
1965+
1966+
const fieldFirstName = new FieldApi({
1967+
form,
1968+
name: 'firstName',
1969+
})
1970+
const fieldLastName = new FieldApi({
1971+
form,
1972+
name: 'lastName',
1973+
})
1974+
1975+
form.mount()
1976+
fieldFirstName.mount()
1977+
fieldLastName.mount()
1978+
1979+
await form.validateAllFields('change')
1980+
expect(fieldFirstName.getMeta().errorMap.onChange).toEqual('is required')
1981+
expect(fieldLastName.getMeta().errorMap.onChange).toEqual('is required')
1982+
})
1983+
1984+
it('should validate all fields consistently - form level onSubmit validators ', async () => {
1985+
const form = new FormApi({
1986+
defaultValues: {
1987+
firstName: '',
1988+
lastName: '',
1989+
},
1990+
validators: {
1991+
onSubmit: ({ value }) => {
1992+
return {
1993+
fields: {
1994+
firstName: value.firstName.length > 0 ? undefined : 'is required',
1995+
lastName: value.lastName.length > 0 ? undefined : 'is required',
1996+
},
1997+
}
1998+
},
1999+
},
2000+
})
2001+
2002+
const fieldFirstName = new FieldApi({
2003+
form,
2004+
name: 'firstName',
2005+
})
2006+
const fieldLastName = new FieldApi({
2007+
form,
2008+
name: 'lastName',
2009+
})
2010+
2011+
form.mount()
2012+
fieldFirstName.mount()
2013+
fieldLastName.mount()
2014+
2015+
await form.validateAllFields('submit')
2016+
expect(fieldFirstName.getMeta().errorMap.onSubmit).toEqual('is required')
2017+
expect(fieldLastName.getMeta().errorMap.onSubmit).toEqual('is required')
2018+
})
2019+
2020+
it('should validate all fields consistently - field level onChange validators', async () => {
19492021
const form = new FormApi({
19502022
defaultValues: {
19512023
firstName: '',
@@ -1957,18 +2029,38 @@ describe('form api', () => {
19572029
form,
19582030
name: 'firstName',
19592031
validators: {
1960-
onChange: ({ value }) =>
1961-
value.length > 0 ? undefined : 'first name is required',
2032+
onChange: ({ value }) => (value.length > 0 ? undefined : 'is required'),
19622033
},
19632034
})
19642035

19652036
form.mount()
19662037
field.mount()
19672038

19682039
await form.validateAllFields('change')
1969-
expect(field.getMeta().errorMap.onChange).toEqual('first name is required')
1970-
await form.validateAllFields('change')
1971-
expect(field.getMeta().errorMap.onChange).toEqual('first name is required')
2040+
expect(field.getMeta().errorMap.onChange).toEqual('is required')
2041+
})
2042+
2043+
it('should validate all fields consistently - field level onSubmit validators', async () => {
2044+
const form = new FormApi({
2045+
defaultValues: {
2046+
firstName: '',
2047+
lastName: '',
2048+
},
2049+
})
2050+
2051+
const field = new FieldApi({
2052+
form,
2053+
name: 'firstName',
2054+
validators: {
2055+
onSubmit: ({ value }) => (value.length > 0 ? undefined : 'is required'),
2056+
},
2057+
})
2058+
2059+
form.mount()
2060+
field.mount()
2061+
2062+
await form.validateAllFields('submit')
2063+
expect(field.getMeta().errorMap.onSubmit).toEqual('is required')
19722064
})
19732065

19742066
it('should validate a single field consistently if touched', async () => {

0 commit comments

Comments
 (0)