public/js/components/ManagedEditor/ManagedEditorField.js (60 lines of code) (raw):
import React from 'react';
import {PropTypes} from 'prop-types';
import _get from 'lodash/fp/get';
import _set from 'lodash/fp/set';
import validateField from '../../util/validateField';
export class ManagedField extends React.Component {
state = {
fieldErrors: [],
touched: false
};
static propTypes = {
fieldLocation: PropTypes.string.isRequired,
children: PropTypes.oneOfType([
PropTypes.element,
PropTypes.arrayOf(PropTypes.element)
]),
updateData: PropTypes.func,
updateFormErrors: PropTypes.func,
data: PropTypes.object,
name: PropTypes.string,
label: PropTypes.string,
isRequired: PropTypes.bool,
customValidation: PropTypes.arrayOf(PropTypes.func)
};
componentDidMount() {
this.runValidations(_get(this.props.fieldLocation, this.props.data));
}
runValidations(data) {
Promise.resolve(validateField(data, this.props.isRequired, this.props.customValidation))
.then(fieldErrors => {
if (this.props.updateFormErrors){
this.setState({
fieldErrors: fieldErrors
});
this.props.updateFormErrors(fieldErrors, this.props.name);
}
});
}
updateFn = (newValue) => {
this.setState({
touched: true
});
this.runValidations(newValue);
this.props.updateData(_set(this.props.fieldLocation, newValue, this.props.data));
};
getLabel() {
const fieldLabel = this.props.label ? this.props.label : this.props.name;
return this.props.isRequired ? fieldLabel + " *" : fieldLabel;
}
render () {
const hydratedChildren = React.Children.map(this.props.children, (child) => {
return React.cloneElement(child, {
fieldName: this.props.name,
fieldLabel: this.getLabel(),
fieldValue: _get(this.props.fieldLocation, this.props.data),
fieldErrors: this.state.touched ? this.state.fieldErrors : undefined,
onUpdateField: this.updateFn,
});
});
return <div>{hydratedChildren}</div>;
}
}