react-native-sk-validatable-form
v1.0.1
Published
component that wraps your form fields, it’s easy to get their value, validate their value.
Downloads
26
Maintainers
Readme
react-native-sk-validatable-form
##Why it comes
Inspired by react-native-gifted-form and formsy-react, I appreciate these project, but I want more:
- Validate form fields in react-native.
- Easy to add validation rules and messages, and use them with simple syntax.
- Field's state(value) should be maintained by itself, not by form, but form can get fields' value, not store them.
- Validation rule should be declarative, it should follow component's declaration, e.g.
<TextInput validations='isRequired,isLength:[1,50]'/>
- Each rule binds one error message, when you call a rule everywhere, you don't need write the message everywhere.
- Field component should be easy to extend, not just traditional input components(e.g. TextInput, Swith), but any other input components.
- Form scrolls to the focused input component automatically.
So I come up with this project.
##What is it
react-native-sk-validatable-form is a component that wraps your form fields, it’s easy to get their value, validate their value.
There are some concepts you need to know
- Form: Component that represents a form, wraps ScrollView, contains input components, validates/gets their values
- Widget: Component that represents a field, wraps input components(e.g. TextInput/Switch) to accept field's value, validates/get its value, keeps validation error. You can create a Widget class by 2 ways: 1 inherits
WidgetMixin
2 useWidgetClassFactory
. You can set validation rules through 'validations' property (e.g.validations='isRequired,isLength:[1,50]'
) - Validation: Class that parse validation rules and checks the rules. You can add rule validator through Validation.addValidator(rule, func)
- Message: Helper that contains every rule's error message template, and translates it into real message. You can add a message templdate for a rule through Message.addMessage(rule, messageTemplate)
##How to use it
Example
npm install react-native-sk-validatable-form@latest --save
Write this in index.ios.js / index.android.js
'use strict';
import React, {
AppRegistry,
Alert,
} from 'react-native';
var {SKNavigator} = require('react-native-sk-navigator');
var { Form, Widget, WidgetMixin, WidgetClassFactory, Validation, Message } = require('react-native-sk-validatable-form');
// 如果你想显示中文的错误消息
// Message.setLanguage('cn');
var Home = React.createClass({
submit(){
var title, msg;
if(this.refs.form.validate()){ // validate form (validate all fields' value in form)
title = 'Success';
msg = 'validate success';
}else{
title = 'Fail';
msg = this.refs.form.getErrorMessages().join('\n'); // get all fields' validation error message
}
Alert.alert(
title,
msg,
[
{text:'ok'},
]
);
},
render() {
return (
<Form
ref='form'
navigator={this.props.navigator}
keyboardShouldPersistTaps={true}
scrollEventThrottle={200}
style={[styles.container, this.props.style]}>
{/* title 标题 */}
<Widget.TextInputInline
name='title' // field name
title='title' // field title
validations='isRequired,isLength:[1,50]' // field's validation rules
validateOnBlur={true} // validate when input component blurs / onBlur() happens
maxLength={50}
style={[styles.textInput, styles.titleInput]}
placeholderTextColor='#B9B9B9'
placeholder='Please input title(limit 50 character)'
/>
{/* married 已婚 */}
<Widget.SwitchInline
name='married'
title='married'
defaultValue={false}
onTintColor='#F59E21'
validations='isRequired'
/>
{/* sex 性别 */}
<Widget.SexLinkInline
name='sex1'
title='sex1'
validations='isRequired'
placeholder='Please select sex'
/>
{/* sex 性别 */}
<Widget.PickerIOSLinkInline
name='sex2'
title='sex2'
validations='isRequired'
placeholder='Please select sex'
items={{'female': 'Female/Woman', 'male': 'Male/Man'}}
/>
{/* sex 性别 */}
<Widget.PickerLinkInline
name='sex3'
title='sex3'
validations='isRequired'
placeholder='Please select sex'
items={{'female': 'Female/Woman', 'male': 'Male/Man'}}
/>
{/* date 日期 */}
<Widget.DateIOSLinkInline
name='date'
title='date'
validations='isRequired'
placeholder='please select date'
/>
{/* place 地点 */}
<Widget.MapLinkInline
name='place'
title='place'
validations='isRequired'
placeholder='please select place'
/>
{/* content 内容 */}
<Widget.TextInput
name='content'
title='content'
validations='isRequired,isLength:[1,200]'
validateOnBlur={true}
maxLength={200}
style={[styles.textInput, styles.contentInput]}
placeholderTextColor='#B9B9B9'
placeholder='Please input content'
onFocus={() => this.refs.form.scrollTo({y: 60})}
multiline={true}
/>
</Form>
);
}
});
var SKFormExample = React.createClass({
render() {
return (
<SKNavigator
initialRoute={{ // 初始路由
title: 'Home',
component: Home,
passProps: {
ref: (ref) => this.home = ref,
},
rightButtonTitle: 'submit',
onRightButtonPress: () => this.home.submit(),
}}/>
)
}
})
var styles = {
container: {
flex: 1,
backgroundColor: '#FFF',
},
textInput:{
fontSize: 15,
},
titleInput: {
flex: 1,
color: 'black',
},
contentInput: {
marginLeft: 10,
height: 160,
color: '#5E5D5D',
},
};
AppRegistry.registerComponent('SKFormExample', () => SKFormExample);
##Form Component
Form wraps ScrollView, contains widgets, validates/gets their values, and scrolls to the focused input component automatically.
Form's properties
Form's methods
| Method | Description | Params |
|---|---|---|
|registerInput(widget)
|Remember a input widget. |None|
|unregisterInput(widget)
|Forget a input widget. |None|
|scrollTo(...)
|Delegate ScrollView's method scrollTo()
. |None|
|scrollToFocusedInput(input)
|Scroll to the focuse input widget. |None|
|getTitles()
|Get all fields' title. |None|
|getValues()
|Get all fields' value. |None|
|validate()
|Validate all fields' value. |None|
|getErrorMessages()
|Get all fields' validation error message. |None|
##Widget Component(Inherits WidgetMixin)
Widget's properties
Any property of input component(e.g. TextInput/Switch) which widget wraps(Widget will pass these properties to input component).
And the following:
| Prop | Description | Default |
|---|---|---|
|name
|Field name. |None|
|title
|Field title. |None|
|defaultValue
|Field's default value. |None|
|validations
|Field's validation rules. |None|
|validateOnBlur
|Validate when input component blurs / onBlur() happens. |false|
Widget's methods
| Method | Description | Params |
|---|---|---|
|setValue(value)
|Set current field's value. |None|
|getValue()
|Get current field's value. |None|
|validate()
|Validate current field' value. |None|
|getErrorMessage()
|Get current field' validation error message. |None|
How to define a widget
1 inherits WidgetMixin
var TextInputWidget = React.createClass({
mixins: [WidgetMixin],
render(){
return (
<TextInput
{...this.props}
onChangeText={this.setValue}
value={this.state.value} />
)
}
})
2 use WidgetClassFactory
WidgetClassFactory
is a helper to define a widget, with the same inplements as above(1 inherits WidgetMixin
).
create()
method needs 3 parameters:
1 input component
2 value change callback (e.g. TextInput.onChangeText / Switch.onValueChange)
3 value property (e.g TextInput.value / Switch.value)
var TextInputWidget = WidgetClassFactory.create(TextInput, 'onChangeText', 'value');
Widegt's uses
<TextInputWidget
name='title' // field name
title='title' // field title
validations='isRequired,isLength:[1,50]' // field's validation rules
validateOnBlur={true} // validate when input component blurs / onBlur() happens
/>
Validation rules string
validations='isRequired,isLength:[1,50],equalsPassword:#password'
validations
contains validation rules, which is defined in validator or you can define it yourself by Validation.addValidator(rule, func).
Multiple rules are split by ,
.
One rule contains name and parameter which are split by :
.
Parameter can be a json(e.g. [1,50]
) or a string(e.g. abc123
) or a field(e.g. #xxx
, it will pass 'xxx' field's value when check the rule)
Validation Class
Validation is a class that contains validation rules, and will check the rules.
Validation's methods
| Method | Description | Params |
|---|---|---|
|static addValidator(rule, func)
|Add a rule validator, which is used by Validation rules string |None|
|static parse(validations)
|Parse validation rules string (into a Validation object). |None|
|check(value, values)
|check the rules, called by WidgetMixin.validate() |None|
Add a rule validator
Validation.addValidator('equalsPassword', (value, password) => {
return value == password;
})
Each rule has a validator function, which check the rule and return bool result.
Message helper
Message is a helper to offer error message for a rule.
Message's methods
| Method | Description | Params |
|---|---|---|
|setLanguage(language, messages = null)
|Toggle language, only support cn(chinese) and en(english), you can add your implements by parameter messages
. |None|
|addMessage(rule, messageTemplate)
|add a message template for a rule. |None|
Toggle message language
// If you want to show chinese error message, 如果你想显示中文的错误消息
Message.setLanguage('cn');
Add a message templdate for a rule
Message.addMessage('isEmail', '{TITLE} must be an email');
Message.addMessage('equalsPassword', '{TITLE} must be an {password}');
In Message.addMessage(rule, messageTemplate)
, messageTemplate is a string template which contains parameter and will be translated when showing a error message.
About messageTemplate parameters, {TITLE}
represents current field's title, {xxx}
represents 'xxx' field's title.