1.0.9 ā€¢ Published 3 years ago

validate-form-in-expo-style v1.0.9

Weekly downloads
6
License
MIT
Repository
github
Last release
3 years ago

React-Native Expo Form Validation Component Library with Floating Label!

N|Solid

šŸ˜‰ 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

$ 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:-

Watch the video

šŸ’” 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

PropRequiredTypeDefault valueDescription
onSubmittruefunctionCallback for form that fires when all validations are passed
instantValidatefalsebooltrueIf true, form will be validated after each field change. If false, form will be validated only after clicking submit button.
onErrorfalsefunctionCallback for form that fires when some of validations are not passed. It will return array of elements which not valid.
debounceTimefalsenumber0Debounce time for validation i.e. your validation will run after debounceTime ms when you stop changing your input

InputText Props

PropRequiredTypeDefault valueDescription
nametruestringName of input field
labelfalsestringName of input Floating Label
placeholderfalsestringPlaceholder of input before any value
validateNamesfalsearrayArray of validation. See list of default validation rules in above example.
errorMessagesfalsearrayArray of error messages. Order of messages should be the same as validateNames prop.
errorStylefalseobject{ container: { top: 0, left: 0, position: 'absolute' }, text: { color: 'red' }, underlineValidColor: 'gray', underlineInvalidColor: 'red' } }Add your own error styles
validatorListenerfalsefunctionIt triggers after each validation. It will return true or false
withRequiredValidatorfalseboolAllow to use required validator in any validation trigger, not only form submit
leftIconfalsecode, imageEither include image or add Icon tag code to display left icon see above example
invalidIconfalsecode, imageEither include image or add Icon tag code to display error icon on right side see above example
validIconfalsecode, imageEither include image or add Icon tag code to display success icon on right side see above example
secureTextEntryfalseboolfalseIf true than show hide icon will get added automatically

šŸ”— Methods

Form Methods

NameParamsReturnDescriptipon
resetValidationsReset validation messages for all validated inputs
isFormValiddryRun: bool (default true)PromiseGet form validation state in a Promise (true if whole form is valid). Run with dryRun = false to show validation errors on form

InputText Methods

NameParamsReturnDescriptipon
getErrorMessageGet error validation message
validatevalue: any, includeRequired: boolRun validation for current component
isValidboolReturn current validation state
makeInvalidSet invalid validation state
makeValidSet valid validation state

šŸ’¼ Contributing

This component covers all my needs, but feel free to contribute.

šŸ–‹ License

MIT Ā© Radhakishan Jangid