UNPKG

@bynder/react-formulation

Version:
130 lines (113 loc) 3.6 kB
import React from 'react'; import PropTypes from 'prop-types'; import defaultMessages from './utils/validationMessages'; const ValidatorForm = ({ onSubmit, children, ...props }, context) => { const onFormSubmit = (e) => { const validatedFields = context.validatorGetAllErrors(); e.preventDefault(); if ((context.validateOn !== 'submit' && validatedFields.isValid) || (context.validateOn === 'submit' && validatedFields.isValid)) { onSubmit(e); } }; return ( <form onSubmit={onFormSubmit} {...props} > {children} </form> ); }; ValidatorForm.propTypes = { onSubmit: PropTypes.func, children: PropTypes.node, }; ValidatorForm.contextTypes = { validatorCanSubmit: PropTypes.bool, validatorGetAllErrors: PropTypes.func, validateOn: PropTypes.string, }; const Validator = ({ name, hideErrors, children, }, context) => { const schema = context.validatorAttributes(name); return ( <div> {React.Children.map(children, (child) => { if (typeof child === 'object') { return React.cloneElement(child, { ...context.validatorBindInput(name, child.props.type), }); } return null; }, )} {(!hideErrors && schema.isValid === false && (schema.isTouched || context.validateOn === 'submit')) ? ( <ErrorsBlock errors={schema.errors} /> ) : null } </div> ); }; Validator.propTypes = { name: PropTypes.string, hideErrors: PropTypes.bool, children: PropTypes.node, }; Validator.contextTypes = { validatorBindInput: PropTypes.func, validatorAttributes: PropTypes.func, validateOn: PropTypes.string, }; const ErrorsBlock = ({ errors, }, context) => ( errors ? ( <div> {errors.map((error, index) => { let displayError = null; const messages = context.validatorMessages; if (typeof error === 'string') { displayError = error; } else if (messages && messages[error.rule]) { const customError = messages[error.rule]; if (typeof customError === 'function') { displayError = customError(error.condition); } else if (typeof customError === 'string') { displayError = customError; } } else if (defaultMessages[error.rule]) { displayError = defaultMessages[error.rule](error.condition); } else { displayError = error.rule; } return ( <div key={index}> {displayError} </div> ); })} </div> ) : null ); ErrorsBlock.propTypes = { errors: PropTypes.arrayOf( PropTypes.oneOfType([ PropTypes.object, PropTypes.string, ]), ), }; ErrorsBlock.contextTypes = { validatorMessages: PropTypes.object, }; Validator.Form = ValidatorForm; Validator.Errors = ErrorsBlock; Object.defineProperty(Validator.Errors, 'name', { value: 'Validator.Errors' }); Object.defineProperty(Validator.Form, 'name', { value: 'Validator.Form' }); export default Validator;