Skip to content

Commit

Permalink
Merge pull request #83 from rstgroup/fix/82/listFieldErrorHandling
Browse files Browse the repository at this point in the history
fix issue #82 ListField error handling
  • Loading branch information
mprzodala authored Dec 2, 2019
2 parents 9ab72ab + 27d29d6 commit 11b56ce
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 20 deletions.
54 changes: 36 additions & 18 deletions src/components/FieldConnect.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import isEqual from 'lodash/isEqual';
import PropTypes from 'prop-types';
import isEqual from 'lodash/isEqual';
import isEmpty from 'lodash/isEmpty';
import cloneDeep from 'lodash/cloneDeep';

export const FieldConnect = (Component) => {
Expand All @@ -12,6 +13,19 @@ export const FieldConnect = (Component) => {
this.shouldShowValidationErrors = false;
this.fieldValidationErrors = null;
this.fieldValidators = [];

this.setFieldValidator = this.setFieldValidator.bind(this);
this.removeFieldValidator = this.removeFieldValidator.bind(this);
this.registerFieldValidators = this.registerFieldValidators.bind(this);
this.unregisterFieldValidators = this.unregisterFieldValidators.bind(this);
this.onChangeData = this.onChangeData.bind(this);
this.getPath = this.getPath.bind(this);
this.getPropsFromSchema = this.getPropsFromSchema.bind(this);
this.getEventsEmitter = this.getEventsEmitter.bind(this);
this.getValidationErrors = this.getValidationErrors.bind(this);
this.getFieldAttributes = this.getFieldAttributes.bind(this);
this.hasValidationError = this.hasValidationError.bind(this);
this.submit = this.submit.bind(this);
}

getChildContext() {
Expand Down Expand Up @@ -47,7 +61,7 @@ export const FieldConnect = (Component) => {
this.unregisterFieldValidators();
}

onChangeData = (value) => {
onChangeData(value) {
const { name, callbacks: { onChange } } = this.props;
const {
setModel,
Expand Down Expand Up @@ -84,11 +98,11 @@ export const FieldConnect = (Component) => {
.join('.');
}

setFieldValidator = (validator) => {
setFieldValidator(validator) {
const modelPath = this.getModelPath();
this.context.setValidator(modelPath, validator);
this.fieldValidators.push(validator);
};
}

setCurrentFieldValue(value) {
this.fieldValue = cloneDeep(value);
Expand All @@ -108,16 +122,18 @@ export const FieldConnect = (Component) => {
return fieldValue;
}

getPropsFromSchema = () => {
getPropsFromSchema() {
const { name } = this.props;
const { getSchema } = this.context;
if (typeof getSchema !== 'function') return undefined;
return getSchema(name);
}

getEventsEmitter = () => this.context.eventsEmitter;
getEventsEmitter() {
return this.context.eventsEmitter;
}

getValidationErrors = () => {
getValidationErrors() {
const { name, callbacks: { onError } } = this.props;
const { getValidationErrors } = this.context;
this.shouldShowValidationErrors = this.shouldShowErrors();
Expand All @@ -129,14 +145,14 @@ export const FieldConnect = (Component) => {
return results;
}

getPath = () => {
getPath() {
const { name } = this.props;
const { getPath } = this.context;
if (typeof getPath !== 'function') return name;
return `${getPath()}.${name}`;
};
}

getFieldAttributes = () => {
getFieldAttributes() {
const { validateOnChange, isFormSubmitted } = this.context;
const { fieldAttributes, callbacks: { onFocus, onBlur } } = this.props;
return Object.assign(
Expand Down Expand Up @@ -167,15 +183,15 @@ export const FieldConnect = (Component) => {
}
}

removeFieldValidator = (validator) => {
removeFieldValidator(validator) {
const index = this.fieldValidators.indexOf(validator);
if (index > -1) {
this.context.removeValidator(validator);
this.fieldValidators.splice(index, 1);
}
};
}

registerFieldValidators = () => {
registerFieldValidators() {
if (this.props.validator) {
const { getModel } = this.context;
const fieldValidator = (...attr) => {
Expand All @@ -184,13 +200,13 @@ export const FieldConnect = (Component) => {
};
this.setFieldValidator(fieldValidator);
}
};
}

unregisterFieldValidators = () => {
unregisterFieldValidators() {
this.fieldValidators.forEach((validator) => {
this.context.removeValidator(validator);
});
};
}

shouldShowErrors() {
const { hasBeenTouched, validateOnChange, isFormSubmitted } = this.context;
Expand All @@ -202,7 +218,7 @@ export const FieldConnect = (Component) => {
return hasBeenTouched(this.getPath());
}

submit = (event) => {
submit(event) {
const { submitForm } = this.context;
if (typeof submitForm !== 'function') return;
submitForm(event);
Expand Down Expand Up @@ -269,7 +285,9 @@ export const FieldConnect = (Component) => {
}
}

hasValidationError = () => this.getValidationErrors().length > 0;
hasValidationError() {
return !isEmpty(this.getValidationErrors());
}

render() {
return (<Component
Expand Down
15 changes: 13 additions & 2 deletions src/components/Form.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,19 @@ import React from 'react';
import PropTypes from 'prop-types';
import cloneDeep from 'lodash/cloneDeep';
import get from 'lodash/get';
import isObject from 'lodash/isObject';
import Storage from './Storage';

export const setErrorOnSchema = (schema, path, error) => {
if (isObject(error)) {
Object.keys(error).forEach((key) => {
schema.setModelError(`${path}.${key}`, error[key]);
});
return;
}
schema.setModelError(path, error);
};

class Form extends React.Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -118,10 +129,10 @@ class Form extends React.Component {
if (asyncValidationError && typeof asyncValidationError === 'boolean') {
return asyncValidationError;
}
return schema.setModelError(path, asyncValidationError);
return setErrorOnSchema(schema, path, asyncValidationError);
});
}
return schema.setModelError(path, validationResults);
return setErrorOnSchema(schema, path, validationResults);
};
this.fieldsValidators.push({ path, validator, schemaValidator });
if (typeof this.state.schema.validate === 'function') {
Expand Down
19 changes: 19 additions & 0 deletions tests/integration/Form.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
FormEventsEmitter,
ErrorField,
} from '../../src/components';
import { setErrorOnSchema } from '../../src/components/Form';
import FormController from '../../src/components/FormController';
import FieldConnect from '../../src/components/FieldConnect';
import { titleSchema, bookSchema, fooBarSchema } from '../data/schemas';
Expand Down Expand Up @@ -868,3 +869,21 @@ describe('Form', () => {
});
});
});

describe('setErrorOnSchema', () => {
let schema;
beforeEach(() => {
schema = {
setModelError: jest.fn(),
};
});

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');
});
it('should set error on schema when error is string', () => {
setErrorOnSchema(schema, 'foo.bar', 'barError');
expect(schema.setModelError).toHaveBeenCalledWith('foo.bar', 'barError');
});
});

0 comments on commit 11b56ce

Please sign in to comment.