diff --git a/src/components/Form.jsx b/src/components/Form.jsx index 42106d5..f06cfc2 100644 --- a/src/components/Form.jsx +++ b/src/components/Form.jsx @@ -6,9 +6,15 @@ import isObject from 'lodash/isObject'; import Storage from './Storage'; export const setErrorOnSchema = (schema, path, error) => { - if (isObject(error)) { + if (isObject(error) || Array.isArray(error)) { Object.keys(error).forEach((key) => { - schema.setModelError(`${path}.${key}`, error[key]); + if (error[key]) { + if (typeof error[key] === 'string') { + schema.setModelError(path, error[key]); + return; + } + setErrorOnSchema(schema, `${path}.${key}`, error[key]); + } }); return; } diff --git a/src/demo/book/CustomField.jsx b/src/demo/book/CustomField.jsx new file mode 100644 index 0000000..7a11a3c --- /dev/null +++ b/src/demo/book/CustomField.jsx @@ -0,0 +1,70 @@ +import React, { Component } from 'react'; +import Schema from 'form-schema-validation'; +import isEmpty from 'lodash/isEmpty'; +import PropTypes from 'prop-types'; +import { FieldConnect } from '../../components/FieldConnect'; + +const getInternalSchema = () => new Schema({ + name: { + type: String, + validators: [ + { + validator: (value) => { + if (value.length === 2) { + return 'FieldValidatorError'; + } + return true; + }, + }, + ], + }, + surname: { + type: String, + }, + age: { + type: String, + }, +}); + +class CustomField extends Component { + constructor(props) { + super(props); + this.state = {}; + } + + componentDidMount() { + this.context.setFieldValidator(this.setAuthorsValidator); + } + + componentWillUnmount() { + this.context.removeFieldValidator(this.setAuthorsValidator); + } + + + setAuthorsValidator = (_model, value) => { + const schema = getInternalSchema(); + const allErrors = []; + value.forEach((author) => { + const errors = schema.validate(author); + allErrors.push(!isEmpty(errors) ? errors : undefined); + }); + return allErrors.length ? allErrors : true; + }; + + render() { + return ( +
+ ); + } +} + +CustomField.contextTypes = { + setFieldValidator: PropTypes.func, + removeFieldValidator: PropTypes.func, +}; + +CustomField.propTypes = {}; + +CustomField.defaultProps = {}; + +export default FieldConnect(CustomField); diff --git a/src/demo/book/index.jsx b/src/demo/book/index.jsx index 5098f8f..1493236 100644 --- a/src/demo/book/index.jsx +++ b/src/demo/book/index.jsx @@ -12,6 +12,7 @@ import { import { listWrapper, objectFormField, objectFieldClassName } from '../demo.css'; import { FormEventsEmitter } from '../../components'; import { consoleData } from '../demoHelpers'; +import CustomField from './CustomField'; const options = [ { @@ -32,6 +33,16 @@ const personSchema = new Schema({ name: { type: String, required: true, + validators: [ + { + validator: (value) => { + if (value.length < 3) { + return 'personError'; + } + return true; + }, + }, + ], }, surname: { type: String, @@ -104,6 +115,7 @@ const resetModel = { status: true, }; + const eventsEmitter = new FormEventsEmitter(); const BookForm = () => (
(

BOOK FORM

+ { it('should set error on schema when error has object structure', () => { setErrorOnSchema(schema, 'foo.0', { bar: 'barError' }); - expect(schema.setModelError).toHaveBeenCalledWith('foo.0.bar', 'barError'); + expect(schema.setModelError).toHaveBeenCalledWith('foo.0', 'barError'); }); it('should set error on schema when error is string', () => { setErrorOnSchema(schema, 'foo.bar', 'barError');