Skip to content

Instantly share code, notes, and snippets.

@heracek
Forked from steida/gist:d54a2cd2296ec7c164d1
Last active August 29, 2015 14:22
Show Gist options
  • Save heracek/fbf63f71e22e2ee32f2a to your computer and use it in GitHub Desktop.
Save heracek/fbf63f71e22e2ee32f2a to your computer and use it in GitHub Desktop.
React.js field validation
/*
Simple serial "one by one" sync/async promises based validation.
*/
import validator from 'validator'
import Promise from 'bluebird'
export function focusInvalidField(reactComponent) {
return (error) => {
if (error instanceof ValidationError) {
if (!error.prop) return
const el = reactComponent.getDOMNode().querySelector(`[name=${error.prop}]`)
if (!el) return
el.focus()
return
}
throw error
}
}
export class ValidationError extends Error {
constructor(message: string, prop: string) {
this.message = message
this.prop = prop
}
}
export default class Validation {
constructor(object: Object) {
this._object = object
this._prop = null
this._validator = validator
this.promise = Promise.resolve()
}
custom(callback: Function, {required} = {}) {
const prop = this._prop
const value = this._object[prop]
const object = this._object
this.promise = this.promise.then(() => {
if (required && !this._isEmptyString(value)) return
callback(value, prop, object)
})
return this
}
_isEmptyString(value) {
return !this._validator.toString(value).trim()
}
prop(prop: string) {
this._prop = prop
return this
}
required() {
return this.custom((value, prop) => {
throw new ValidationError(
this.getRequiredMessage(prop, value),
prop
)
}, {required: true})
}
getRequiredMessage(prop, value) {
return `Please fill out '${prop}' field.`
}
email() {
return this.custom((value, prop) => {
if (this._validator.isEmail(value)) return
throw new ValidationError(
this.getEmailMessage(prop, value),
prop
)
})
}
getEmailMessage() {
return `Email address is not valid.`
}
simplePassword() {
return this.custom((value, prop) => {
const minLength = 5
if (value.length >= minLength) return
throw new ValidationError(
this.getSimplePasswordMessage(minLength),
prop
)
})
}
getSimplePasswordMessage(minLength) {
return `Password must contain at least ${minLength} characters.`
}
}
// Example
function validateForm(params) {
return validate(params)
.prop('email').required().email()
.prop('password').required().simplePassword()
.promise
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment