react-native-advanced-form-validation
v1.0.2
Published
Advanced form validation for React Native with support for complex rules and custom error messages
Downloads
6
Maintainers
Readme
react-native-advanced-form-validation
Advanced form validation for React Native with support for complex rules, custom error messages, and real-time feedback with animations. This library integrates seamlessly with popular form libraries like Formik.
Installation
To install the package, use npm:
npm install react-native-advanced-form-validation
You will also need to install formik
and yup
if you haven't already:
npm install formik yup
Usage
Basic Setup
First, import the necessary modules and create your form validation schema using the provided helper function.
import React from 'react';
import { View, TextInput, Button, Text } from 'react-native';
import { Formik } from 'formik';
import { createFormikValidationSchema, withRealTimeValidation } from 'react-native-advanced-form-validation';
const RealTimeTextInput = withRealTimeValidation(TextInput);
const validationSchema = createFormikValidationSchema(['email', 'password', 'confirmPassword']);
const MyForm = () => {
return (
<Formik
initialValues={{ email: '', password: '', confirmPassword: '' }}
validationSchema={validationSchema}
onSubmit={values => {
console.log(values);
}}
>
{({ handleChange, handleBlur, handleSubmit, values, errors, touched }) => (
<View>
<RealTimeTextInput name="email" placeholder="Email" />
{touched.email && errors.email && <Text style={{ color: 'red' }}>{errors.email}</Text>}
<RealTimeTextInput name="password" placeholder="Password" secureTextEntry />
{touched.password && errors.password && <Text style={{ color: 'red' }}>{errors.password}</Text>}
<RealTimeTextInput name="confirmPassword" placeholder="Confirm Password" secureTextEntry />
{touched.confirmPassword && errors.confirmPassword && <Text style={{ color: 'red' }}>{errors.confirmPassword}</Text>}
<Button onPress={handleSubmit} title="Submit" />
</View>
)}
</Formik>
);
};
export default MyForm;
Custom Validation Schema
You can customize the validation schema by adding your own validation rules:
import * as Yup from 'yup';
import { createFormikValidationSchema } from 'react-native-advanced-form-validation';
const customValidationSchema = Yup.object().shape({
username: Yup.string().required('Username is required'),
phoneNumber: Yup.string().matches(/^\d+$/, 'Phone number is not valid').required('Phone number is required'),
});
const validationSchema = createFormikValidationSchema(['email', 'password', 'confirmPassword']).concat(customValidationSchema);
const MyForm = () => {
return (
<Formik
initialValues={{ email: '', password: '', confirmPassword: '', username: '', phoneNumber: '' }}
validationSchema={validationSchema}
onSubmit={values => {
console.log(values);
}}
>
{({ handleChange, handleBlur, handleSubmit, values, errors, touched }) => (
<View>
<RealTimeTextInput name="email" placeholder="Email" />
{touched.email && errors.email && <Text style={{ color: 'red' }}>{errors.email}</Text>}
<RealTimeTextInput name="password" placeholder="Password" secureTextEntry />
{touched.password && errors.password && <Text style={{ color: 'red' }}>{errors.password}</Text>}
<RealTimeTextInput name="confirmPassword" placeholder="Confirm Password" secureTextEntry />
{touched.confirmPassword && errors.confirmPassword && <Text style={{ color: 'red' }}>{errors.confirmPassword}</Text>}
<RealTimeTextInput name="username" placeholder="Username" />
{touched.username && errors.username && <Text style={{ color: 'red' }}>{errors.username}</Text>}
<RealTimeTextInput name="phoneNumber" placeholder="Phone Number" />
{touched.phoneNumber && errors.phoneNumber && <Text style={{ color: 'red' }}>{errors.phoneNumber}</Text>}
<Button onPress={handleSubmit} title="Submit" />
</View>
)}
</Formik>
);
};
export default MyForm;
Custom Error Messages
To customize error messages, you can create your own utility function:
// src/utils/customErrorMessages.js
export const getCustomErrorMessage = (error) => {
switch (error.type) {
case 'required':
return `${error.path} cannot be empty`;
case 'min':
return `${error.path} must be longer than ${error.min} characters`;
case 'email':
return `Please enter a valid email address`;
default:
return `Invalid ${error.path}`;
}
};
// Then use this function in your component:
import { getCustomErrorMessage } from './src/utils/customErrorMessages';
// In your component:
{touched.email && errors.email && <Text>{getCustomErrorMessage(errors.email)}</Text>}
Integration with Redux Form
For integration with Redux Form, you need to create custom field-level validation functions:
import { Field, reduxForm } from 'redux-form';
import validationSchemas from 'react-native-advanced-form-validation/src/validators';
const validate = values => {
const errors = {};
try {
validationSchemas.email.validateSync(values.email);
} catch (err) {
errors.email = err.message;
}
try {
validationSchemas.password.validateSync(values.password);
} catch (err) {
errors.password = err.message;
}
try {
validationSchemas.confirmPassword.validateSync({
password: values.password,
confirmPassword: values.confirmPassword
});
} catch (err) {
errors.confirmPassword = err.message;
}
return errors;
};
const MyReduxForm = ({ handleSubmit }) => (
<View>
<Field name="email" component={renderField} type="text" placeholder="Email" />
<Field name="password" component={renderField} type="password" placeholder="Password" />
<Field name="confirmPassword" component={renderField} type="password" placeholder="Confirm Password" />
<Button onPress={handleSubmit} title="Submit" />
</View>
);
const renderField = ({ input, placeholder, type, meta: { touched, error } }) => (
<View>
<TextInput {...input} placeholder={placeholder} type={type} />
{touched && error && <Text>{error}</Text>}
</View>
);
export default reduxForm({
form: 'myReduxForm',
validate,
})(MyReduxForm);
API
createFormikValidationSchema(fields: string[])
- Description: Creates a validation schema for Formik based on the specified fields.
- Parameters:
fields
(string[]): An array of field names for which the validation schema should be created.
- Returns: A Yup validation schema.
Default Validation Rules
- email: Must be a valid email address.
- password: Must be at least 8 characters long.
- confirmPassword: Must match the password field.
withRealTimeValidation(Component: React.ComponentType)
- Description: A higher-order component that provides real-time validation feedback with animations for the given input component.
- Parameters:
Component
(React.ComponentType): The input component to wrap with real-time validation feedback.
- Returns: A new component with real-time validation feedback.
Example Components
RealTimeValidationHOC
This higher-order component provides real-time feedback for form validation:
import React, { useRef, useEffect } from 'react';
import { useFormikContext } from 'formik';
import { TextInput, View, Text, Animated, StyleSheet } from 'react-native';
const withRealTimeValidation = (Component) => ({ name, ...props }) => {
const { values, errors, touched, handleChange, handleBlur } = useFormikContext();
const errorAnim = useRef(new Animated.Value(0)).current;
useEffect(() => {
if (touched[name] && errors[name]) {
Animated.timing(errorAnim, {
toValue: 1,
duration: 300,
useNativeDriver: true,
}).start();
} else {
Animated.timing(errorAnim, {
toValue: 0,
duration: 300,
useNativeDriver: true,
}).start();
}
}, [touched, errors, name, errorAnim]);
return (
<View>
<Component
onChangeText={handleChange(name)}
onBlur={handleBlur(name)}
value={values[name]}
{...props}
/>
{touched[name] && errors[name] && (
<Animated.View style={{ opacity: errorAnim }}>
<Text style={styles.errorText}>{errors[name]}</Text>
</Animated.View>
)}
</View>
);
};
const styles = StyleSheet.create({
errorText: {
color: 'red',
marginTop: 5,
},
});
export default withRealTimeValidation;
License
This project is licensed under the MIT License.
Contributing
Contributions are welcome! Please open an issue or submit a pull request.
Author
Mujahid Ramzan