Skip to content

Commit

Permalink
Clear errors on form reset (#1568)
Browse files Browse the repository at this point in the history
* Clear errors on form reset

* Abstract out `clearErrors` function

* Update tests

* Fix test

* Update changelog
  • Loading branch information
reinink authored Oct 25, 2023
1 parent 3a43b79 commit 74d682c
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 26 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ For changes prior to v1.0.0, see the [legacy releases](https://legacy.inertiajs.

## [Unreleased](https://github.com/inertiajs/inertia/compare/v1.0.12...HEAD)

- Nothing!
- Clear errors on form reset ([#1568](https://github.com/inertiajs/inertia/pull/1568))

## [v1.0.12](https://github.com/inertiajs/inertia/compare/v1.0.11...v1.0.12)

Expand Down
31 changes: 18 additions & 13 deletions packages/react/src/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,20 @@ export default function useForm<TForm extends FormDataType>(
[data, setErrors],
)

function clearErrors(...fields) {
setErrors((errors) => {
const newErrors = (Object.keys(errors) as Array<keyof TForm>).reduce(
(carry, field) => ({
...carry,
...(fields.length > 0 && !fields.includes(field) ? { [field]: errors[field] } : {}),
}),
{},
)
setHasErrors(Object.keys(newErrors).length > 0)
return newErrors
})
}

return {
data,
setData(keyOrData: keyof TForm | Function | TForm, maybeValue?: TForm[keyof TForm]) {
Expand Down Expand Up @@ -200,6 +214,8 @@ export default function useForm<TForm extends FormDataType>(
reset(...fields) {
if (fields.length === 0) {
setData(defaults)
setErrors({})
setHasErrors(false)
} else {
setData(
(Object.keys(defaults) as Array<keyof TForm>)
Expand All @@ -212,6 +228,7 @@ export default function useForm<TForm extends FormDataType>(
{ ...data },
),
)
clearErrors(...fields)
}
},
setError(fieldOrFields: keyof TForm | Record<keyof TForm, string>, maybeValue?: string) {
Expand All @@ -226,19 +243,7 @@ export default function useForm<TForm extends FormDataType>(
return newErrors
})
},
clearErrors(...fields) {
setErrors((errors) => {
const newErrors = (Object.keys(errors) as Array<keyof TForm>).reduce(
(carry, field) => ({
...carry,
...(fields.length > 0 && !fields.includes(field) ? { [field]: errors[field] } : {}),
}),
{},
)
setHasErrors(Object.keys(newErrors).length > 0)
return newErrors
})
},
clearErrors,
submit,
get(url, options) {
submit('get', url, options)
Expand Down
4 changes: 3 additions & 1 deletion packages/svelte/src/useForm.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { router } from '@inertiajs/core'
import isEqual from 'lodash.isequal'
import cloneDeep from 'lodash.clonedeep'
import isEqual from 'lodash.isequal'
import { writable } from 'svelte/store'

function useForm(...args) {
Expand Down Expand Up @@ -52,6 +52,7 @@ function useForm(...args) {
let clonedDefaults = cloneDeep(defaults)
if (fields.length === 0) {
this.setStore(clonedDefaults)
this.clearErrors()
} else {
this.setStore(
Object.keys(clonedDefaults)
Expand All @@ -61,6 +62,7 @@ function useForm(...args) {
return carry
}, {}),
)
this.clearErrors(...fields)
}

return this
Expand Down
2 changes: 2 additions & 0 deletions packages/vue2/src/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,15 @@ export default function useForm<TForm extends FormDataType>(...args): InertiaFor
if (fields.length === 0) {
defaults = clonedData
Object.assign(this, resolvedData)
this.clearErrors()
} else {
Object.keys(resolvedData)
.filter((key) => fields.includes(key))
.forEach((key) => {
defaults[key] = clonedData[key]
this[key] = resolvedData[key]
})
this.clearErrors(...fields)
}

return this
Expand Down
18 changes: 9 additions & 9 deletions packages/vue2/tests/cypress/integration/form-helper.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ describe('Form Helper', () => {
cy.get('#remember').should('be.checked')
})

it('does not reset errors when it resets a field to its initial value', () => {
it('resets error when it resets a field to its initial value', () => {
cy.get('#name').clear().type('A')
cy.get('#handle').clear().type('B')
cy.get('#remember').check()
Expand All @@ -361,11 +361,11 @@ describe('Form Helper', () => {
cy.get('#remember').should('be.checked')
cy.get('.errors-status').should('have.text', 'Form has errors')
cy.get('.name_error').should('have.text', 'Some name error')
cy.get('.handle_error').should('have.text', 'The Handle was invalid')
cy.get('.handle_error').should('not.exist')
cy.get('.remember_error').should('not.exist')
})

it('does not reset errors when it resets all fields to their initial values', () => {
it('reset errors when it resets all fields to their initial values', () => {
cy.get('#name').clear().type('A')
cy.get('#handle').clear().type('B')
cy.get('#remember').check()
Expand All @@ -379,14 +379,14 @@ describe('Form Helper', () => {
cy.get('.name_error').should('have.text', 'Some name error')
cy.get('.handle_error').should('have.text', 'The Handle was invalid')

cy.get('.reset-one').click()
cy.get('.reset').click()

cy.get('#name').should('have.value', 'A')
cy.get('#name').should('have.value', 'foo')
cy.get('#handle').should('have.value', 'example')
cy.get('#remember').should('be.checked')
cy.get('.errors-status').should('have.text', 'Form has errors')
cy.get('.name_error').should('have.text', 'Some name error')
cy.get('.handle_error').should('have.text', 'The Handle was invalid')
cy.get('#remember').should('not.be.checked')
cy.get('.errors-status').should('have.text', 'Form has no errors')
cy.get('.name_error').should('not.exist')
cy.get('.handle_error').should('not.exist')
cy.get('.remember_error').should('not.exist')
})

Expand Down
4 changes: 2 additions & 2 deletions packages/vue2/tests/cypress/integration/remember.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ describe('Remember (local state caching)', () => {
cy.get('#remember').should('be.checked')
cy.get('#untracked').should('have.value', 'C') // Unchanged from above
cy.get('.name_error').should('not.exist')
cy.get('.handle_error').should('have.text', 'The Handle was invalid')
cy.get('.handle_error').should('not.exist')
cy.get('.remember_error').should('not.exist')

cy.get('.link').click()
Expand All @@ -287,7 +287,7 @@ describe('Remember (local state caching)', () => {
cy.get('#remember').should('be.checked')
cy.get('#untracked').should('not.have.value', 'C') // Untracked, so now reset (page state was lost)
cy.get('.name_error').should('not.exist')
cy.get('.handle_error').should('have.text', 'The Handle was invalid')
cy.get('.handle_error').should('not.exist')
cy.get('.remember_error').should('not.exist')
})
})
Expand Down
2 changes: 2 additions & 0 deletions packages/vue3/src/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,15 @@ export default function useForm<TForm extends FormDataType>(
if (fields.length === 0) {
defaults = clonedData
Object.assign(this, resolvedData)
this.clearErrors()
} else {
Object.keys(resolvedData)
.filter((key) => fields.includes(key))
.forEach((key) => {
defaults[key] = clonedData[key]
this[key] = resolvedData[key]
})
this.clearErrors(...fields)
}

return this
Expand Down

0 comments on commit 74d682c

Please sign in to comment.