Last active
July 20, 2016 22:15
-
-
Save prestonp/ef6d17c6b3ddf1e6567631ffb54365df to your computer and use it in GitHub Desktop.
react validation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TestForm extends React.Component { | |
constructor() { | |
super(); | |
this.state = { | |
name: '', | |
address: '', | |
}; | |
this.nameOnChange = this.nameOnChange.bind(this); | |
this.addressOnChange = this.addressOnChange.bind(this); | |
this.validate = this.validate.bind(this); | |
} | |
nameOnChange(e) { | |
this.setState({ name: e.target.value }); | |
} | |
addressOnChange(e) { | |
this.setState({ address: e.target.value }); | |
} | |
validate() { | |
// This validation schema could be anything but should follow this object pattern | |
// validationErrors = { input => [error, error, error, ... ] } | |
// Leaving validate() implementation up to the component allows users | |
// to use whatever validation lib they want | |
let validationErrors = { name: [], address: [] }; | |
const { name, address } = this.state; | |
if (name.length < 5) { | |
validationErrors.name.push('Name must be atleast 5 characters'); | |
} | |
if (name.indexOf('james') >= 0) { | |
validationErrors.name.push('Name cannot contain "james"'); | |
} | |
if (address.length < 5) { | |
validationErrors.address.push('Address must be atleast 5 characters'); | |
} | |
if (name === address) { | |
validationErrors.address.push('Address must not be the same as name'); | |
} | |
this.props.setValidationErrors(validationErrors); | |
} | |
render() { | |
return <div> | |
<label>Name</label> | |
<input | |
value={this.state.name} | |
onChange={this.nameOnChange} | |
className={this.props.getClassName('name')} | |
onBlur={this.validate} /> | |
<ValidationErrors errors={this.props.validationErrors['name'] || []} /> | |
<label>Address</label> | |
<input | |
value={this.state.address} | |
onChange={this.addressOnChange} | |
className={this.props.getClassName('address')} | |
onBlur={this.validate}/> | |
<ValidationErrors errors={this.props.validationErrors['address'] || []} /> | |
</div>; | |
} | |
} | |
module.exports = Validate(TestForm); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Higher order component for maintaining validation state and utility | |
* functions for accessing errors and decorating className | |
*/ | |
const Validate = ComposedComponent => class extends React.Component { | |
constructor() { | |
super(); | |
this.state = { | |
validationErrors: {} | |
}; | |
this.getClassName = this.getClassName.bind(this); | |
this.setValidationErrors = this.setValidationErrors.bind(this); | |
} | |
/** | |
* getClassName returns the className based on an input | |
* @param {string} name - input name | |
* @param {string} className - the original className | |
* @return {string} the className with 'invalid' if there is a validation | |
* error present for the given input name | |
*/ | |
getClassName(name, className='') { | |
const present = this.state.validationErrors[name]; | |
if (!present) return className; | |
const valid = !this.state.validationErrors[name].length; | |
if (valid) return className; | |
return (className + ' ' + 'invalid').trim(); | |
} | |
/** | |
* setValidationErrors sets the validation errors | |
* @param {object} validationErrors - object, keyed by input names associated | |
with the list of error strings | |
*/ | |
setValidationErrors(validationErrors) { | |
this.setState({ validationErrors }); | |
} | |
render() { | |
return <ComposedComponent {...this.props} {...this.state} | |
getClassName={this.getClassName} | |
setValidationErrors={this.setValidationErrors} />; | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function ValidationErrors({ errors }) { | |
const errs = errors.map((err, idx) => { | |
return <li key={idx}>{err}</li>; | |
}); | |
return <ul>{errs}</ul>; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment