UNPKG

@piscium2010/v-form

Version:

This is not a form, instead it is only a form shell of which the single responsibility is validating and providing error messages. Capable of definding flexiable rules and validating multi fields at a time.

83 lines (71 loc) 2.24 kB
import React from 'react' import { MessageContainer, connectToMessageContainer } from 'react-input-message' import Field from './Field' import { VFormContext } from './Context' import v from './v' export default class VForm extends React.Component { static defaultProps = { validation: v.create({}) // validation with empty rules } static fieldFactory = C => { const CustomField = connectToMessageContainer(Field(C), { mapMessages: ( messages, names, props, container ) => { const one = messages[props.name] const message = [].concat(one)[0] return message || '' } }) return CustomField } constructor(props) { super(props) this.state = { messages: props.defaultMessages || {} } this.validation = props.validation } get messages() { return 'messages' in this.props ? this.props.messages : this.state.messages } onMessages = messages => { const newMessages = { ...this.state.messages, ...messages } this.setState({ messages: newMessages }) } subscribe = () => { const { validation } = this.props const { has, addListener } = validation if (has && addListener) { if (!validation.has(this)) { this.unSubscribe() // first unsubscribe previous this.validation = validation this.validation.addListener(this, this.onMessages) } } else { throw 'invalid valition passed to VForm' } } unSubscribe = () => { this.validation.removeListener(this) } componentDidUpdate() { this.subscribe() } componentDidMount() { this.subscribe() } componentWillUnmount() { this.unSubscribe() } render() { return ( <VFormContext.Provider value={{name:'VForm', validation: this.props.validation}}> <MessageContainer messages={this.messages}>{this.props.children}</MessageContainer> </VFormContext.Provider> ) } }