React-Native Expo Form Validation Component Library with Floating Label!
Hey! I'm Radhakishan Jangid . More about me Here .
validate-form-in-expo-style is a Simple form validation component with floating label for React-Native inspired by react-native-form-validator. You can add floating label with this library and can validate form. I created this package for my personal use you can use it in yours too.
My bad, that I don't have Mac or IPhone, so this library is tested only in android. Do check it in Mac and let me know if any problem occurs.
Table of Contents
- Install
- Supported Types
- Default Validation Rules
- Example
- How to use
- Props
- Methods
- Contributing
- License
Install
$ npm install validate-form-in-expo-style
or
$ yarn add react-native-stylish-accordion
Now we need to install react-native-reanimated and react-lifecycles-compat. If you are using Expo, to ensure that you get the compatible versions of the libraries, run:
expo install react-native-reanimated react-native-gesture-handler react-lifecycles-compat
If you are not using Expo, run the following:
yarn add react-native-reanimated react-native-gesture-handler react-lifecycles-compat
Supported types:-
- TextInput
Default Validation Rules are:-
- matchRegexp
- isEmail
- isEmpty
- required
- trim
- isNumber
- isFloat
- isPositive
- minNumber
- maxNumber
- minFloat
- maxFloat
- minStringLength
- maxStringLength
- isString
Some rules that are added in validationName can accept extra parameter for validation, like:
<InputText
{...otherProps}
validateNames={['minNumber:1', 'maxNumber:255', 'matchRegexp:^[0-9]
See the full example of form validation in react-native Expo:-
How to use:-
import React from 'react';
import { StyleSheet, View, Text, Dimensions, TouchableOpacity, Image, ScrollView } from 'react-native';
import { Form, InputText } from 'validate-form-in-expo-style';
import { FontAwesome, Feather } from "@expo/vector-icons";
class App extends React.Component {
state = {
first_name: "",
number: "",
last_name: "",
email: '',
user: { password: "", repeatPassword: "" },
}
componentDidMount() {
//You can add your own rules
Form.addValidationRule('isValidPassword', (value) => {
let passwordReg = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[a-zA-Z]).{8,}$/;
if (passwordReg.test(value) === false) {
return false;
}
return true;
});
Form.addValidationRule('isPasswordMatch', (value) => {
if (value !== this.state.user.password) {
return false;
}
return true;
});
}
componentWillUnmount() {
// Remove own rules
Form.removeValidationRule('isPasswordMatch');
Form.removeValidationRule('isValidPassword');
}
handlePassword = (event) => {
const { user } = this.state;
user.password = event.nativeEvent.text;
this.setState({ user });
}
handleRepeatPassword = (event) => {
const { user } = this.state;
user.repeatPassword = event.nativeEvent.text;
this.setState({ user });
}
handleChange = (email) => {
this.setState({ email });
}
handleFirstName = (first_name) => {
this.setState({ first_name });
}
handleLastName = (last_name) => {
this.setState({ last_name });
}
handleNumber = (number) => {
this.setState({ number });
}
submit = () => {
alert("form submit, thank you.")
}
handleSubmit = () => {
this.refs.form.submit();
}
render() {
let Image_Http_URL = { uri: 'https://radhakishan.vpran.in/img/radhakishan-web-3.jpg' };
const { user } = this.state;
return (
<ScrollView>
<View style={[styles.container, {marginTop: 50}]}>
<View style={[styles.action, { alignItems: "center" }]} >
<Image source={Image_Http_URL} style={{ width: 100, height: 100, borderRadius: 100 / 2 }} />
<FontAwesome name="github" size={24} /><Text style={{fontSize: 18}}>radhakishan404</Text>
<Text style={{ fontSize: 20, padding: 10 }}>validate-form-in-expo-style</Text>
</View>
<View style={styles.action} >
<Form ref="form" onSubmit={this.submit} >
<InputText
name="first_name"
label="First Name"
placeholder="textfield with floating label"
validateNames={['required', "isString", "maxStringLength:30"]}
errorMessages={["This field is required", "Only characters allowed", "Max character limit is 30"]}
value={this.state.first_name}
onChangeText={this.handleFirstName}
type="text"
leftIcon={<FontAwesome name="user-o" color="#0A3055" size={20} />}
invalidIcon={< Feather
name="alert-circle"
color="red"
size={20}
/>}
validIcon={<Feather name="check-circle" color="green" size={20} />}
labelStyle={styles.labelStyle}
style={[styles.inputStyle]}
containerStyle={styles.inputContainerStyle}
floatingTopValue={hp('1%')}
floatingFontSize={hp('0.5%')}
/>
<InputText
name="last_name"
placeholder="textfield without floating label"
validateNames={['required', "isString", "maxStringLength:30"]}
errorMessages={["This field is required", "Only characters allowed", "Max character limit is 30"]}
value={this.state.last_name}
onChangeText={this.handleLastName}
type="text"
leftIcon={<FontAwesome name="user-o" color="#0A3055" size={20} />}
invalidIcon={< Feather
name="alert-circle"
color="red"
size={20}
/>}
validIcon={<Feather name="check-circle" color="green" size={20} />}
labelStyle={styles.labelStyle}
style={[styles.inputStyle]}
containerStyle={styles.inputContainerStyle}
floatingTopValue={hp('1%')}
floatingFontSize={hp('0.5%')}
/>
<InputText
name="phone"
label="Mobile"
placeholder="textfield with only number"
validateNames={['required', "isNumber", "maxStringLength:10"]}
errorMessages={["This field is required", "Only numbers allowed", "Max string limit is 10"]}
value={this.state.number}
onChangeText={this.handleNumber}
type="text"
leftIcon={<FontAwesome name="phone" color="#0A3055" size={20} />}
invalidIcon={< Feather
name="alert-circle"
color="red"
size={20}
/>}
validIcon={<Feather name="check-circle" color="green" size={20} />}
labelStyle={styles.labelStyle}
style={[styles.inputStyle]}
containerStyle={styles.inputContainerStyle}
floatingTopValue={hp('1%')}
floatingFontSize={hp('0.5%')}
/>
<InputText
name="email"
label="email"
validateNames={['required', 'validEmail']}
errorMessages={['This field is required', 'Enter valid email address']}
placeholder="textfield with email validation"
type="text"
keyboardType="email-address"
value={this.state.email}
onChangeText={this.handleChange}
leftIcon={<FontAwesome name="user-o" color="#0A3055" size={20} />}
invalidIcon={< Feather
name="alert-circle"
color="red"
size={20}
/>}
validIcon={<Feather name="check-circle" color="green" size={20} />}
labelStyle={styles.labelStyle}
style={[styles.inputStyle]}
containerStyle={styles.inputContainerStyle}
floatingTopValue={hp('1%')}
floatingFontSize={hp('0.5%')}
/>
<InputText
name="password"
label="Password"
secureTextEntry
passwordHideIcon={< Ionicons
name="eye-off-outline"
color={constants.white}
size={20}
/>}
passwordShowIcon={< Ionicons
name="eye-outline"
color={constants.white}
size={20}
/>}
validateNames={['isValidPassword', 'required']}
errorMessages={['Minimum eight characters, at least one uppercase letter, one lowercase letter and one number', 'This field is required']}
type="text"
value={user.password}
placeholder="custom password validation"
leftIcon={<FontAwesome name="lock" color="#0A3055" size={20} />}
onChange={this.handlePassword}
labelStyle={styles.labelStyle}
style={[styles.inputStyle]}
containerStyle={styles.inputContainerStyle}
floatingTopValue={hp('1%')}
floatingFontSize={hp('0.5%')}
/>
<InputText
name="repeatPassword"
label="Confirm Password"
secureTextEntry
validateNames={['isPasswordMatch', 'required']}
errorMessages={['Password mismatch', 'This field is required']}
type="text"
value={user.repeatPassword}
placeholder="Confirm your password"
onChange={this.handleRepeatPassword}
invalidIcon={< Feather
name="alert-circle"
color="red"
size={20}
/>}
leftIcon={<FontAwesome name="lock" color="#0A3055" size={20} />}
labelStyle={styles.labelStyle}
style={[styles.inputStyle]}
containerStyle={styles.inputContainerStyle}
floatingTopValue={hp('1%')}
floatingFontSize={hp('0.5%')}
/>
<TouchableOpacity
activeOpacity={0.8}
onPress={this.handleSubmit}
style={styles.appButtonContainer}
>
<Text style={styles.appButtonText}>Submit</Text>
</TouchableOpacity>
</Form>
</View>
</View>
</ScrollView>
);
}
}
export default App;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
action: {
width: Dimensions.get('window').width,
padding: 20
},
appButtonContainer: {
elevation: 8,
backgroundColor: "#009688",
borderRadius: 10,
paddingVertical: 10,
paddingHorizontal: 12,
marginTop: 10
},
appButtonText: {
fontSize: 18,
color: "#fff",
fontWeight: "bold",
alignSelf: "center",
textTransform: "uppercase"
}
labelStyle: {
fontSize: hp('1.8%'),
color: constants.white,
paddingTop: hp('0.8%'),
opacity: .9,
// top: 20
},
inputStyle: {
color: constants.white,
paddingTop: hp('1%'),
},
inputContainerStyle: {
paddingBottom: hp('1%'),
paddingTop: hp('1.3%'),
borderWidth: 2,
borderBottomWidth: 2,
// borderColor: "#333333",
// borderBottomColor: "#333333",
borderColor: constants.primaryColor,
borderBottomColor: constants.primaryColor,
borderRadius: 15
},
inputIconStyle: {
marginHorizontal: 10,
fontSize: hp('2.3%'),
backgroundColor: "#333333",
borderRadius: 5,
alignSelf: "center",
paddingHorizontal: hp('0.2%'),
paddingVertical: hp('0.1%'),
}
});
Props
Form Props
Prop
Required
Type
Default value
Description
onSubmit
true
function
Callback for form that fires when all validations are passed
instantValidate
false
bool
true
If true, form will be validated after each field change. If false, form will be validated only after clicking submit button.
onError
false
function
Callback for form that fires when some of validations are not passed. It will return array of elements which not valid.
debounceTime
false
number
0
Debounce time for validation i.e. your validation will run after debounceTime ms when you stop changing your input
InputText Props
Prop
Required
Type
Default value
Description
name
true
string
Name of input field
label
false
string
Name of input Floating Label
placeholder
false
string
Placeholder of input before any value
validateNames
false
array
Array of validation. See list of default validation rules in above example.
errorMessages
false
array
Array of error messages. Order of messages should be the same as validateNames prop.
errorStyle
false
object
{ container: { top: 0, left: 0, position: 'absolute' }, text: { color: 'red' }, underlineValidColor: 'gray', underlineInvalidColor: 'red' } }
Add your own error styles
validatorListener
false
function
It triggers after each validation. It will return true or false
withRequiredValidator
false
bool
Allow to use required validator in any validation trigger, not only form submit
leftIcon
false
code, image
Either include image or add Icon tag code to display left icon see above example
invalidIcon
false
code, image
Either include image or add Icon tag code to display error icon on right side see above example
validIcon
false
code, image
Either include image or add Icon tag code to display success icon on right side see above example
secureTextEntry
false
bool
false
If true than show hide icon will get added automatically
Methods
Form Methods
Name
Params
Return
Descriptipon
resetValidations
Reset validation messages for all validated inputs
isFormValid
dryRun: bool (default true)
Promise
Get form validation state in a Promise (true if whole form is valid). Run with dryRun = false to show validation errors on form
InputText Methods
Name
Params
Return
Descriptipon
getErrorMessage
Get error validation message
validate
value: any, includeRequired: bool
Run validation for current component
isValid
bool
Return current validation state
makeInvalid
Set invalid validation state
makeValid
Set valid validation state
Contributing
This component covers all my needs, but feel free to contribute.
License
]}
/>
See the full example of form validation in react-native Expo:-
How to use:-
__CODE_BLOCK_5__Props
Form Props
| Prop | Required | Type | Default value | Description |
|---|---|---|---|---|
| onSubmit | true | function | Callback for form that fires when all validations are passed | |
| instantValidate | false | bool | true | If true, form will be validated after each field change. If false, form will be validated only after clicking submit button. |
| onError | false | function | Callback for form that fires when some of validations are not passed. It will return array of elements which not valid. | |
| debounceTime | false | number | 0 | Debounce time for validation i.e. your validation will run after __INLINE_CODE_0__ ms when you stop changing your input |
InputText Props
| Prop | Required | Type | Default value | Description |
|---|---|---|---|---|
| name | true | string | Name of input field | |
| label | false | string | Name of input Floating Label | |
| placeholder | false | string | Placeholder of input before any value | |
| validateNames | false | array | Array of validation. See list of default validation rules in above example. | |
| errorMessages | false | array | Array of error messages. Order of messages should be the same as __INLINE_CODE_1__ prop. | |
| errorStyle | false | object | { container: { top: 0, left: 0, position: 'absolute' }, text: { color: 'red' }, underlineValidColor: 'gray', underlineInvalidColor: 'red' } } | Add your own error styles |
| validatorListener | false | function | It triggers after each validation. It will return __INLINE_CODE_2__ or __INLINE_CODE_3__ | |
| withRequiredValidator | false | bool | Allow to use __INLINE_CODE_4__ validator in any validation trigger, not only form submit | |
| leftIcon | false | code, image | Either include image or add Icon tag code to display left icon see above example | |
| invalidIcon | false | code, image | Either include image or add Icon tag code to display error icon on right side see above example | |
| validIcon | false | code, image | Either include image or add Icon tag code to display success icon on right side see above example | |
| secureTextEntry | false | bool | false | If true than show hide icon will get added automatically |
Methods
Form Methods
| Name | Params | Return | Descriptipon |
|---|---|---|---|
| resetValidations | Reset validation messages for all validated inputs | ||
| isFormValid | dryRun: bool (default true) | Promise | Get form validation state in a Promise (__INLINE_CODE_5__ if whole form is valid). Run with __INLINE_CODE_6__ to show validation errors on form |
InputText Methods
| Name | Params | Return | Descriptipon |
|---|---|---|---|
| getErrorMessage | Get error validation message | ||
| validate | value: any, includeRequired: bool | Run validation for current component | |
| isValid | bool | Return current validation state | |
| makeInvalid | Set invalid validation state | ||
| makeValid | Set valid validation state |
Contributing
This component covers all my needs, but feel free to contribute.
