Skip to content

Instantly share code, notes, and snippets.

@dmitryshelomanov
Last active April 5, 2019 07:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmitryshelomanov/1b0ad923aad5eaf752d28eed409456a1 to your computer and use it in GitHub Desktop.
Save dmitryshelomanov/1b0ad923aad5eaf752d28eed409456a1 to your computer and use it in GitHub Desktop.
import React, { Component } from 'react'
import validatejs from 'validate.js'
const validate = (fieldName, value, rule) => {
const result = validatejs({ [fieldName]: value }, { [fieldName]: rule })
if (result) {
return result[fieldName][0]
}
return null
}
export const withForm = ({
initialState = {},
rules = {},
}) => (BaseComponent) =>
class WithForm extends Component {
state = {
form: typeof initialState === 'function'
? initialState(this.props)
: initialState,
errors: {},
}
validate = (field = undefined) => {
if (typeof field === 'string') {
const error = validate(field, this.state.form[field], rules[field])
this.setState((prev) => {
return {
...prev,
errors: {
...prev.errors,
[field]: error,
},
}
})
return !!error
}
if (typeof field === 'undefined') {
const errors = Object.keys(this.state.form)
.reduce((acc, key) => {
if (rules[key]) {
return { ...acc, [key]: validate(key, this.state.form[key], rules[key]) }
}
return acc
}, this.state.errors)
const isValid = Object.keys(errors)
.filter((key) => errors[key]).length === 0
this.setState((prev) => {
return {
...prev,
errors,
}
})
return isValid
}
}
updateField = (fields, value) => {
if (typeof fields === 'string') {
this.setState((prev) => {
return {
...prev,
form: {
...prev.form,
[fields]: value,
},
}
})
return
}
if (typeof fields === 'object') {
this.setState((prev) => {
return {
...prev,
form: {
...prev.form,
...fields,
},
}
})
}
}
render() {
return (
<BaseComponent
{...this.props}
{...this.state}
updateField={this.updateField}
validate={this.validate}
/>
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment