Skip to content

Commit

Permalink
feat: custom validator
Browse files Browse the repository at this point in the history
  • Loading branch information
ph-fritsche committed Jun 24, 2021
1 parent e70e4f5 commit d059288
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 6 deletions.
12 changes: 11 additions & 1 deletion docs/handler/validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,14 @@ You can provide a translation function to change representation of errors per `a
}/>
```


You can add errors on top of the schema validation by injecting your own validator.
```jsx
import { finalizeName } from 'liform-react-final'
const myValidator = (values, liformApi) => {
// inspect the values and return a flat error object
return {
[finalizeName('my.object.property')]: 'some error',
}
}
<Liform {...liformProps} validate={myValidator}/>
```
4 changes: 3 additions & 1 deletion src/form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ export function Liform(props) {

const onValidate = useMemo(() => buildFlatValidatorHandler(buildFlatValidatorStack(
buildFlatAjvValidate(props.ajv, liformApi.schema, props.ajvTranslator || translateAjv),
), liformApi), [props.ajv, props.ajvTranslator, liformApi])
...[props.validate].filter(Boolean),
), liformApi), [props.ajv, props.ajvTranslator, liformApi, props.validate])

const finalFormProps = {
debug: props.debug,
Expand Down Expand Up @@ -168,6 +169,7 @@ Liform.propTypes = {

ajv: PropTypes.func,
ajvTranslator: PropTypes.func,
validate: PropTypes.func,

...FinalForm.propTypes,
}
6 changes: 3 additions & 3 deletions src/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ export const flatAjvValidate = (ajv, schema, ajvTranslate, values) => {
}

export const buildFlatValidatorStack = (...validators) => {
return (values) => {
return (values, liform) => {
const flatErrors = {}

for (const validator of validators) {
const newErrors = validator(values)
const newErrors = validator(values, liform)
for (const fieldName in newErrors) {
flatErrors[fieldName] = (flatErrors[fieldName] || []).concat(
Array.isArray(newErrors[fieldName]) ? newErrors[fieldName] : [newErrors[fieldName]],
Expand All @@ -69,7 +69,7 @@ export const buildFlatValidatorStack = (...validators) => {

export const buildFlatValidatorHandler = (flatErrorValidator, liform) => {
return (values) => {
const flatErrors = flatErrorValidator(values)
const flatErrors = flatErrorValidator(values, liform)
liform.validationErrors = flatErrors
return Object.keys(flatErrors).length > 0 ? { [FORM_ERROR]: 'The form has errors - see Liform.validationErrors' } : {}
}
Expand Down
27 changes: 27 additions & 0 deletions test/form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,31 @@ describe('Liform', () => {

expect(getLastProps(fieldState).dirty).toBe(false)
})

it('use custom validator', () => {
const container = jest.fn(() => null)
const theme = { render: { container } }

const validator = jest.fn(() => ({
'foo.bar': 'baz',
}))

Renderer.create(<Liform theme={theme} validate={validator}/>)

expect(container).toBeCalled()

Renderer.act(() => {
getLastProps(container).form.registerField('someField', () => null, {})
getLastProps(container).form.change('someField', 'someValue')
})

expect(validator).toBeCalledWith(
{'someField': 'someValue', '_': undefined},
getLastProps(container).liform,
)

expect(getLastProps(container).liform.validationErrors).toEqual({
'foo.bar': ['baz'],
})
})
})
2 changes: 1 addition & 1 deletion test/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ describe('Flat validator stack', () => {
stack(values)

for(const f of validators) {
expect(f).toBeCalledWith(values)
expect(f).toBeCalledWith(values, undefined)
}
})

Expand Down

0 comments on commit d059288

Please sign in to comment.