react-validable
v0.5.4
Published
Simple configless validation for React
Downloads
20
Readme
react-validable
==============
Simple configless validation for React. Only simple High-Ordered Components and rules.
No field configuration needed!
Installation
$ npm install react-validable --save
Testing
Go to project folder and run
$ npm install
$ npm test
Usage Guide
See exampes here https://sick-sad-world.github.io/react-validable/
Step One - Make field suitable for validation
You may take whatever form input component you have. After being wrapped by Validable.Element
it recieve props listed in table below. If you pass props with same names they will be overritten
Props injected to Child Component
valid
- represents current validation statetrue
if valid.Array[String]
of messages otherwise.pristine
-Boolean
- Determine whatever field was touched or not. Most of time it equalsfalse
(Scope - Elemnt) Global form pristine state you manage by our ownvalidate
-function(val, opts)
Function given to check whatever new value is valid.
Validate function usage
Syntax validate(value, options)
.
Params:
value
- value to check validationoptions
-Array[Object]
Options to override. Should be an array of 1 to [n] items.
Note options will be passed in the order as rules defined in
Validable.Element
HOC. So if you haveValidable.Element(['required', 'numeric'])
options[{message: 'Required'}, {message: 'Numeric'}]
will be passed accordinately. If you need to update options only fornumeric
you should use something like this[null, {message: 'Numeric'}]
Note Dosen't matter how and when you call
validate
method it changes globalValidable.Form
state through context. You can pass result inonChange
handler oronBlur
and build whatever interaction you want. Read more for details.
export default function TextInput({ label, type, name, value, validate, valid, pristine, onChange, ...props }) {
// Check file validation
const invalid = Array.isArray(valid);
// Define change handler
const changeHandler = (e) => {
onChange(
{ [name]: e.target.value },
validate(
// Value to check
e.target.value,
// You can change options here like message or validation specific ones
[{message: 'Required message'}, {message: 'Numeric message'}]
)
);
};
// Set class if field is invalid and was changed
const className = `row ${(invalid && !pristine) ? 'invalid' : ''}`;
// Show message if field is invalid and was changed
const message = (invalid && !pristine) ? <span>{valid.join(', ')}</span> : null;
return (
<div className={className}>
<label htmlFor={`id-${name}`}>{label}</label>
<input
id={`id-${name}`}
type={type}
name={name}
value={value || ''}
onChange={changeHandler}
{...props}
/>
{message}
</div>
);
}
Step Two - Create fields with validation
- Import
Validable.Element
hoc - Wrap your input and define rules
- Use it in form
Validation rule syntax
import Validable from 'react-validable';
// or
import { Element } from 'react-validable';
// Simple one-rule validation w/o options
// If you want declare one rule with default options
const NameInput = Validable.Element('required')(YourAwesomeInput);
// Simple one-rule validation with options
// If you want declare one rule with default options
const TextInput = Validable.Element({
type: 'maxLength', // pick rule
treshold: 100, // provide option required by rule
message: 'Text should be less than 100 symbols' // Customize message
})(YourAwesomeInput);
// You may pass any number of rules in array in any form
const ZipCodeInput = Validable.Element(['required', {
type: 'maxLength', // pick rule
treshold: 6, // provide option required by rule
message: 'Text should be less than 100 symbols' // Customize message
}])(YourAwesomeInput);
// You can cache settings as it presumed in React-Redux connect method and use preset for multiple inputs
const RequiredDecimal = Validable.Element(['required', 'decimal']);
const Input1 = RequiredDecimal(YourAwesomeInput);
const Input2 = RequiredDecimal(YourAwesomeInput);
const Input3 = RequiredDecimal(YourAwesomeInput);
// Somewhere inside your form component
// ======================================================================
render() {
return (
<form>
<NameInput name='name' value={value} onChange={this.onChange}>
<TextInput name='text' value={value} onChange={this.onChange}>
<ZipCodeInput name='zip' value={value} onChange={this.onChange}>
</form>
)
}
Connect inputs together
Common case: Match password fields
Create two fields with equal
matchers. And provide values to opposing field.
// Field one
const Pass1 = Validable.Element('equal')(Field);
// Retype password
const Pass2 = Validable.Element('equal')(Field);
// Somewhere in form
render() {
<form>
<Pass1 value={pass1} match={pass1}/>
<Pass2 value={pass2} match={pass2}/>
</form>
}
// In input fields
class Field extends React.Component {
componentWillReceiveProps(nextProps) {
// To handle change of other input you may use lifecycle hooks
if (this.props.match !== newProps.match) {
// Compare current value with new match
this.props.validate(this.props.value, newProps.match);
}
}
onChange() {
// You can match value with opponent value on change or blur or whatever you want
this.props.validate(this.props.value, [{math: this.props.match}]);
}
render() {
<input type='password' onChange={this.onChange} value={this.props.value} />
}
}
Options flow.
You have number of possibilities to define options
Here they is given in order. Bottom one may override upper one.
- in validator (When you create your own custom Validator)
- while using
Validable.Element
HOC where you define rules - right in
validate
function call inside input
Part Three - Put Your validation All-Together
To get results of validation in cetralized manner Validable.Form
HOC provided
How to use it:
- Create your form component
- Make sure Form accepts
valid
property asBoolean
- You can get whole validation state by passing
exposeRaw={true}
to your Form component - You can control validation state from outside using
onValidation={Function}
property
import Validable from 'react-validable';
// or
import { Form } from 'react-validable';
class AwesomeForm extends React.Component {
onSubmit(e) {
e.preventDefault();
if (this.props.valid) {
// Do something
}
}
render() {
// This will be full validation state copy. if [exposeRaw] is passed
const { validationState } = this.props;
return (
<form onSubmit={this.onSubmit}>{Some form stuff}</form>
)
}
}
export default Validable.Form(AwesomeForm);
// Use it somewhere
<AwesomeForm
exposeRaw={true} // Get whole validation state
onValidation={someOutsideCallback(valid = Bool, state = Object)} // Get validation from outside
/>
Note! You may use
Validable.Element
WITHOUTValidable.Form
but then you need to manage whole validation state by your own withvalidate
method return values, or through defining your ownupdatePosition
context handler with this signaturefunction({ key: inputId, valid: bool or [message]})
Part Four - Validation rules list
message
- validation error message - common for ALL rules
|Name|Opions|Description|
|:---|:---|:---|
|required
|none|Check if value
is not null
or undefined
|
|match
|pattern
- RegExp
to match |Match value to given RegExp
|
|numeric
|none|Check if value
is number|
|float
|none|Check if value
is float|
|url
|none|Check if value
is valid URL adderss|
|email
|none|Check if value
is valid email address|
|maxLength
|treshold
- Number
string lenght limit|Check if value
is string length less than limit|
|oneOf
|possible
- Array
choises to match|Check if value
matches one of given options|
|file
|size
- Number
max sie in Kbstype
- String
or Array[String]
- mime-types acceptable by input |Specialized validator for file
type inputs. Can check file size and mime-type.|
Note in rule not found
Validable.Element
will throw an Error. You may add new rules via method described below
Part Five - Add new Validation rule via addRule
Extends global rules object with given rules
import Validable from 'react-validable';
// or
import { addRules } from 'react-validable';
Validable.addRules({
customRule: (value, {message, opt1, opt2, ...opts}) => {
if (valid) {
// Validator should return [true] if value is valid
return true;
} else {
// Or text message if something wrong
return 'Some message';
}
}
})
Now you can use custom rule.
// And use it
Validabe.Element(['required', 'customRule'])(SomeInput);
// or with options
Validabe.Element(['required', {
rule: 'customRule',
opt1: 'bar',
opt2: 'foo'
}])(SomeInput);
Licence
This project is licensed under the MIT License - see the LICENSE.md file for details