npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-native-form-input-validator

v1.3.1

Published

Doing validation to form inputs in React Native app

Downloads

8

Readme

react-native-form-input-validator

It's to validate the input's value in RN app such as TextInput or other kind of inputs. The value is validated based on the rule defined for the input. If the input is invalid, the error message is shown beneath the input. It's very useful before submitted to the server. See the pictures below for some examples.

validation for different types of inputs

More fancy example which uses an icon to reflect the validation status:

validation with status icon

A Brief Example

import React from 'react';
import {
    Button,
    StyleSheet,
    Text,
    TextInput,
    View,
} from 'react-native';
import {
    setStatusStyleDefault,
    ValidationContext,
    withValidation,
} from "react-native-form-input-validator";
import {
    email,
    required,
} from 'react-native-form-input-validator/rules';
import server from './server';

const UserName = withValidation(TextInput, {
    rules: [email, required],
    setStatusStyle: setStatusStyleDefault,
});
const Password = withValidation(TextInput, {
    rules: required,
    setStatusStyle: setStatusStyleDefault,
});

export default function LoginForm() {
    const validationRef = React.useRef();
    const [userName, setUserName] = React.useState('');
    const [password, setPassword] = React.useState('');
    
    return (
        <ValidationContext ref={validationRef}>
            <Text style={styles.title}>Please login:</Text>
            <UserName
                autoCorrect={false}
                onChangeText={setUserName}
                placeholder="Email"
                style={styles.input}
                value={userName}
            />
            <Password
                onChangeText={setPassword}
                placeholder="Password"
                secureTextEntry
                style={styles.input}
                value={password}
            />
            <View style={styles.buttonRow}>
                <Button
                    onPress={() => {
                        if (validationRef.current?.validate()) {
                            server.login(userName, password);
                        }
                    }}
                    title="Login"
                />
            </View>
        </ValidationContext>
    );
}

const styles = StyleSheet.create({
    buttonRow: {
        flexDirection: 'row',
        justifyContent: 'flex-end',
    },
    input: {
        borderColor: '#ccc',
        borderRadius: 4,
        borderWidth: 1,
        color: 'black',
        marginBottom: 10,
    },
    title: {
        marginBottom: 10,
    },
});

API Reference

You have seen the example above. You may concern to withValidation and ValidationContext most. At a glance, you may have concluded that withValidation is to specify the validation rules for the input and ValidationContext is to validate all inputs inside it. Actually, each input can be validated individually and doesn't need to be put inside ValidationContext (see detailly here). ValidationContext exists to validate many input at once.

ValidationContext

This element can validate all contained inputs in it that have been set by withValidation. Also, it can clear the validation status of those inputs. You may treat this element like form tag in HTML document. Some properties that can be set for this element are:

Methods and property of ValidationContext reference (the object that we get from ref property):

  • clearValidation
    It executes clearValidation method of all contained inputs to clear the validation status of all contained inputs.

  • isValid is the property to check the validity status of all inputs inside the context. If there is an invalid input, this property will have false value. Otherwise it's true. The value of this property is trusted after calling validate or validateAsync.

  • getErrorMessage(name)
    returns the error message that is being displayed for the input whose the name specified by name parameter and inside the current ValidationContext. It returns an empty string if no error message displayed for that input. It returns undefined if no input whose such name.

  • getInput(name)
    returns the reference of the input whose the name specified by name parameter and inside the current ValidationContext. It returns undefined if no input whose such name.

  • refreshMessage
    For a multi languange app, this method is useful to update the language of the error messages. This methods will re-validate all contained inputs so that their error messages are refreshed. Because of that, if the input is already valid then the error message will be gone.

  • setErrorMessage(name, message)
    This method is to set error message for an input whose the name specified by name parameter. message parameter is the error message to show. The input must be inside the current ValidationContext. This method is useful when dealing with server-side validation.

  • validate
    It executes validate method of all contained inputs to validate all contained inputs. This method returns false if any invalid input and returns true otherwise.

  • validateAsync
    It executes validateAsync method of all contained inputs to validate all contained inputs. This method returns a Promise object that will resolve to false if any invalid input or true if otherwise.

withValidation

This function is to create higher-order component that wraps an input component so that it can apply some validation rules and also some attributes needed to define the behavior. You can see in the example above that this function takes two parameters. The first parameter is the function/class component that will be validated. The second parameter is the option object. The object has properties which specify validation rules and the other attributes. But if you only need to set the validation rule(s) for the input, the second parameter can a rule object or an array of rule objects.

I think the example above is enough to depict how to use this function. So, in this section, we will discuss the option properties more detailedly. The only property you must specify is rules.

Methods and properties of the input reference (the object that we get from ref property):

  • clearValidation
    It's to clear validation status. The error message will disappear and the input style is reverted to normal. After executing this method, isValid will be reset to true even if the input is invalid. If auto validation is disabled, this method will be called when the user changes the input value right after the validation.

  • getErrorMessage
    This method returns the error message being displayed for the input. It returns an empty string if no error.

  • isValid
    It shows the validity status of input. It's true if valid and false if invalid. The value of this property is trusted after calling validate or validateAsync.

  • name
    It's the name of input. The value of this property is the same as that specified for name option.

  • setErrorMessage(message)
    This method can set the error message for the input without calling validate or validateAsync. It won't validate any rule that has been applied to the input. By calling this method, the input status becomes invalid (isValid property is false).

    For example, we need to validate the input on the server because we must read the database to make sure the inputed user name is unique. (NOTE: The example below should be solved using asynchronous validation interfaces).

    const validateAsync = () => new Promise((resolve, reject) => {
        fetch(
            `https://yourserver.com/validate/unique-user-name?uname=${encodeURIComponent(userName)}`
        ).then(async (response) => {
            if (response.ok) return response.json();
            reject(await response.text());
        }).then(data => {
            if (data.userNameExists) {
                userNameInput.current?.setErrorMessage('The user name has been used');
                resolve(false);
            }
            else {
                resolve(true);
            }
        }).catch(err => {
            reject(err);
        });
    })
    .catch(err => {
        /*If there is a problem with the server, you may tell the user here or you may just keep it silent and
          try to re-validate it on the server when the form is submitted. In fact, backend validation is still
          needed all time to avoid tampered data.*/
        //userNameInput.current?.setErrorMessage('The server cannot validate');
    });
    <UserNameInput ref={userNameInput} onBlur={validateAsync} onChangeText={setUserName} value={userName} />

    Another example, when the validation process yields an error:

    <UserNameInput ref={userNameInput} onChangeText={setUserName} value={userName}
       onBlur={() => {
          try {
              userNameInput.current.validate();
          }
          catch {
              userNameInput.current.setErrorMessage('An error happens when validating');
          }
       }}
    />

    Need to remember that rules option is required. If you want to use setErrorMessage method but doesn't need to apply any validation rule, you can use alwaysValid rule.

  • validate
    This method is to validate the input based on the specified rules. Below is the example how to validate input when it's lost focus.

      <NameTextInput ref={nameInput} onBlur={() => nameInput.current?.validate()} onChangeText={setName} value={name} />

    This method returns true if input value is valid or false if invalid. This method will throw an error if there is a rule object which does the asynchronous validation.

  • validateAsync
    As validate, this method is also to validate the input based on the specified rules but the process is executed in asynchronous mode. This method returns a Promise object that will resolve to true if the input value is valid or false if otherwise.

If the original input has the same methods and property as listed above, they will be overriden. If you want to access the overridden method/property of original input, follow the example below:

const inputRef = React.useRef();
...
<Input ref={inputRef} onBlur={() => {
    //This statement will validate the input
    inputRef.current.validate();
    
    //This statement will invoke `validate` method of original input
    inputRef.current.__proto__.validate();
}} ... />

Style Handling

To make the input and the error message stick together, withValidation wraps them into a View container. However, we want the component yielded by withValidation behaves the same as the original input except we add the validation feature to it. All properties for the input must apply for the new component. Every property seems ok, we can just distribute them to the wrapped input. Except one property we think it has a problem. That is the property which defines the style for the input. Because now, the input is inside a View container. We must modify the style property if we still want the same style as if the input is unwrapped. The big concern is all style attributes dealing with layout. That is how the parent of input arranges the area for input, before. Because now, the parent must arrange the View container. Therefore, the component yielded by withValidation will move all style attributes dealing with layout to be the style attributes of View container. Then, the input must be set to fill the area of View container.

We know, the value for style property is not always plain object or a falsy value but it can be a recursive array. Therefore, the first step is to flatten it if it's an array. Fortunately, react native has provided StyleSheet.flatten function to do that. After getting a single plain object, the following style attributes will be assigned to View container:

  • alignSelf
  • bottom
  • display
  • end
  • flexGrow
  • flexShrink
  • flexBasis
  • left
  • margin
  • marginBottom
  • marginEnd
  • marginHorizontal
  • marginLeft
  • marginRight
  • marginStart
  • marginTop
  • marginVertical
  • maxWidth
  • minWidth
  • position
  • right
  • start
  • top
  • transform
  • width
  • zIndex

Some other attributes will be moved to View containner under a condition:

  • height, minHeight and maxHeight, if having the percentage value
  • flex, if greater than 0.

To make sure the input fill the area of View container, its flex attribute is set to 1 if the View container has one of attributes: height (percentage), flex or flexBasis. But if input has height (number) attribute, the flex attribute won't be set.

There are two handlers you may define in withValidtion option which involves in this modification of style. Those are getStyle and setStyle.

There is still a possibility that the layout will mess up when the error message comes up. That possibility happens, especially when the parent of input (that becomes the parent of View container) lays its children horizontally (flexDirection is row). To avoid it, you should set the height (not percentage) for the input.

The process explained above is executed in every render. To increase performance, it must be sure that the process is run only if the style value changes. To do that, the package has isDifferentStyle function. You can import this function for your own purpose. This function does more detailedly than a shallow compare. Let's explain in the example below:

const style1 = {flex: 2},
      style2 = {flex: 3};
isDifferentStyle(style1, style2); //return true
isDifferentStyle(style1, [style1]); //return false
isDifferentStyle([style1], [style1]); //return false
isDifferentStyle([style1, style2], [style1, style2]); //return false
isDifferentStyle([style1, style2], [style2, style1]); //return true
isDifferentStyle(style1, [style2]); //return true
isDifferentStyle([style1], [style1, style2]); //return true

So, the function simply just compares the entry in the array at the same index. The more detailedly logic can be done to make sure that they are really different but it can cause a more complicated process that won't help increasing performance.

To help increasing performance, you must also set the style value to a constant value, not variable. For example:

const styles = StyleSheet.create({
    input: {borderWidth: 1, ...},
    hightlight: {...},
});
const Input = withValidation(TextInput, ...);
...
export default function Form(props) {
    ...
    return (
        ...
        //It's BAD example
        <Input style={{borderWidth: 1, ...}} ... />

        //It's good
        <Input style={styles.input} ... />

        //If you want to make a different style for
        //a condition, it's a good example
        <Input style={[
            styles.input,
            highlighted ? styles.hightlight : null,
        ]} ... />
        ...
    );
}

Asynchronous Validation

In some cases, we need to execute the validation process in asynchronous mode. The prominent example is when we need to call back the server to check the validity of input value. May be, we need to check the database to ensure the input is valid or not. For making an HTTP request purpose, this package has provided httpReq rule.

To make the process of validation in asynchronous mode, first thing you need is a rule object that can validate a value asynchronously. This package has provided some rule objects that can make the process asynchronously. One of them has been mentioned before, that is httpReq. The another one is ruleAsync. If these rule objects don't satisfy you, create your own rule class which inherits ValidationRuleAsync class.

After you defines the asynchronous rule(s), as usual, set the rule(s) to rules option of withValidation. You may mix asynchronous and synchronous rules. priority property still applies as appropriately (an asynchronous rule won't be examined after a synchronous rule that has lower priority).

The last step, to validate the input(s) asynchronously, you must call validateAsync method of the input reference or validateAsync method of the context reference. Both methods return a Promise object. So, if you want to get the validation result, you should use the following statement:

inputRef.validateAsync()
    .then(isValid => {
        //... rest of your code
    });

or

let isValid = await inputRef.validateAsync();

The last statement must be inside an async function.

Server-side Validation

react-native-form-input-validator pakcage is to validate inputs in React Native app. In other words, it's for client-side validation. By existence of client-side validation, we are more confident to submit data to the server. However, is it enough? Absolutely not. A hacker can make a request without using our app and use an invalid data. So, the server-side validation is always needed exactly as if we are not using a rich user interface application (like an oldish web app).

Then, you may think that if we use a rule like httReq then the server-side validation has been done because the validation by this rule is examined on the server. Unfortunately, it's not. We must validate the inputs right before they are used by the corresponding business process. Clearly, the URI used by httpReq is different from that to where the data is submitted. Knowing this fact, you may think that a rule like httReq is not needed because there will be more round-trip. Yes, you are true but people always have different preference and there may be a situation it's needed.

Now, if we agree that the server-side validation is needed then how to notify user if there are one or more invalid inputs. You may use an alert dialog or a Toast popup. But, it may be better if we show each error message below the corresponding input with hightlighting style like this package does in client-side validation. It's possible by the favor of setErrorMessage method. Follow the example below. In the example, if there are one or more invalid inputs, the server returns status code 400 (Bad Request) and the response body is a JSON data key-ed by the invalid input names. The value of each key is the error message for that input.

    <Button
        onPress={() => {
            function okAction() {
                //The code to be executed when all inputs are valid ...
            }

            fetch('https://yourserver.com/check-password', {
                body: JSON.stringify(this.state),
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                }
            })
            .then(async (response) => {
                if (response.ok) okAction();
                else if (response.status == 400) {
                    const errors = await response.json();
                    for (let inputName in errors) {
                        this.contextRef.current.setErrorMessage(inputName, errors[inputName]);
                    }
                    if (this.contextRef.current.isValid) {
                        //Although, the response status is invalid but no error message provided.
                        //Therefore, we consider all inputs are valid.
                        okAction();
                    }
                }
                else {
                    Alert.alert('Validation', 'Server response is not OK');
                }
            })
            .catch(() => {
                Alert.alert('Validation', 'An error happened.');
            })
        }}
        title="Validate on server"
    />

To keep consistency, the logic used for the server-side validation must be the same as that used by client-side validation. If you use Node server, you may use react-native-form-input-validator pakcage. However, you must import the rule objects and the needed fuctions from "dist" directory. For example:

    const {
        validate
    } = require("react-native-form-input-validator/dist/helpers");
    const {
        required,
        rule,
        strlen,
    } = require('react-native-form-input-validator/dist/rules');

To validate an input, follow the example below:

    const passwordRules = [
        required,
        strlen(8),
        rule(
            value => {
                return /[a-z]/.test(value) && /[A-Z]/.test(value) && /[0-9]/.test(value) && /[^a-zA-Z\d\s]/.test(value);
            },
            'The password must contain capital and non capital letter, number and non-alphanumeric characters'
        ),
    ];
    errMsg = validate(inputValue, passwordRules, inputName);
    if (typeof(errMsg) == 'string') {
        errors[inputName] = errMsg; //the error message is collected for the response data
    }

Asynchronous validation is still needed in server-side validation, for example, if we need to connect to database to check the validity of input. Database connection is usually in asynchronous mode.

Validation Component

Validation component can be used to validate a value without wrapping an input component. It has some properties which are the same as withValidion option. These properties are auto, errorTextStyle, lang and rules. The purpose of these properties are exactly the same as withValidion option's. These properties are write-once. They are only set when the component is mounted. If you change the properties in the next render, it won't have effect.

Beside the properties mentioned before, there are two more properties:

  • style is the style for View container rendered by Validation component. See Style Handling section, which style attributes that have effect.
  • value is the validated value. It can be an actual value or a function. If it's a function then the function will be executed to get the real value. The fuction is useful to create a dynamic value.

Validation object reference also has the same methods and property as those owned by input component reference resulted by withValidation

Example:

import React from 'react';
import {... TextInput, ...} from 'react-native';
import {Validation, ValidationContext} from "react-native-form-input-validator";
import {email, required} from 'react-native-form-input-validator/rules';
...

export default function Form() {
    ...
    const [emailAddress, setEmailAddress] = React.useState('');
    ...

    return (
        <ValidationContext ref={validation}>
            ...
            <TextInput onChangeText={setEmailAddress} placeholder="Email" value={emailAddress} />
            <Validation rules={[required, email]} value={emailAddress} />
            ...
        </ValidationContext>
    );
}

You notice this example, the value of Validation is the same as the value of email TextInput. By this way, it's like to apply the use of withValidation to the email TextInput.

Functions

The functions here can be imported from the package.

setStatusStyleDefault

This function is intended to be assigned to withValidation setStatusStyle option. This function executes the common statements to set input style. Here is the source code which may inspire you to make your own.

function setStatusStyleDefault(props, style) {
    /**
     * Need to remember: the input's style property has been flattened by `withValidation` function. So, normally,
     * it can't be an array.
     */
    let inputStyle = getStyleDefault(props);
    if (style) { //The input style needs to change
        if (Array.isArray(inputStyle)) {
            //The input has got the error/success style. Don't be double set so that it can be reverted to normal style easily
            if (style !== inputStyle[1]) {
                setStyleDefault(props, [inputStyle[0], style]);
            }
        }
        else {
            setStyleDefault(props, [inputStyle, style]);
        }
    }
    else //back to normal style 
        if (Array.isArray(inputStyle)) {
            setStyleDefault(props, inputStyle[0]);
        }
}

str(template, valueMap)

This function is to construct a string from a template string and a map of values. In the template string contains the placeholders for variables to be replaced by the real value. The placeholder is in format ${variable_name}. The real values is in valueMap parameter. For example:

str('${name} must be at least ${min}', {name: 'count', min: 5})

will return string "count must be at least 5".

Rule Object

Rule object defines how to validate the input value. For example whether it's required (cannot be empty), must be a numeric value, must be minimum at a certain value etc. The rule object is reponsible to check whether the input value meets the desired condition or not, to be valid. Mostly, one rule object is responsible to check only one condition. However, we can combine some rule objects so that the input value must meet some conditions to be valid. This is why withValidation rules option can be a single rule object or an array of rule objects.

This package has some built-in rule objects which are ready to use. These rule objects are explained in the next sections. You can create your own rule object by creating a class that extends ValidationRule or ValidationRuleAsync. All rule objects are imported from 'react-native-form-input-validator/rules'.

ValidationRule

This is the base class for all rule objects. Therefore, all object rules must have all properties and methods explained here.

Properties:

  • errorMessage
    Read-only. The error message if the input is invalid. If you define a new rule class, you should override this property to return the default error message. The value of this property can be a template string that can include some properties of the defined rule object. For example: "${name} is invalid. ${value} is not valid phone number".

  • isValid
    It's true if valid and false if invalid. It's set by validate method. Therefore, it's trusted just after calling validate method.

  • lang
    is a function to translate the error message to the active languange. By default, the message is in english. It will be set by validate method of input ref that will be the same as context lang or widthValidation lang option.

  • messageFunc
    Read-only. It's a function which returns the error message. This error message overwrites the default message specified by errorMessage. The parameter of the function is the rule object itself. To set this property, use setMessageFunc method.

  • name
    is the name of validated input. It's set by validate method of input ref which is the same as widthValidation name option.

  • priority
    Read-only. If we specify some rules to validate the input, priority determines which rule to be examined first. priority has a number value. The lower value means the higher priority. By existence of priority, you don't need to bother the order in rules array of withValidation option. The value of this property is set by setPriority.

    By default, the built-in rules have the priority as following (ordered based on which is examined first):

    • required, required.if (the priority cannot be changed, always the highest)
    • email, numeric, strlen, strlenmax
    • integer
    • max, min
    • regex
    • rule
    • httpReq, ruleAsync

    If two rules have the same priority, the order in the rules array determines which one first.

  • value
    is the input value that is validated. It's set by validate method of input ref.

  • resultValue
    After calling validate, resultValue will save a value with valid data type. For example, for numeric rule, it will save a number value, not string like value. By default, it's the same as value (with the same data type).

Methods:

  • setMessageFunc
    is to set messageFunc property.

  • setName
    is to set name propety.

  • setPriority
    is to set priority. You should set a non-negative number.

  • setValue
    is to set value property.

  • validate
    is to validate value and then set isValid based on the validity of value.

You may ask why there are some set* method, why don't leave read-write property alone. It is to make fluent interface which is more convenient. For example, when you set rule for withValidation rules option:

const Input = withValidation(..., {
    ...
    rules: [
        numeric,
        integer,
        min(0).setPriority(5),
        max(4).setMessageFunc(() => 'Too many'),
    ],
    ...
});

or in unit test:

expect(email.setValue('abc').validate().isValid).toBe(false);

Example:

An example class which you may create to validate a credit card number:

import {ValidationRule} from 'react-native-form-input-validator/rules';
const validator = require("card-validator");

export class CreditCardNumber extends ValidationRule {
    contructor() {
        super();
        this.setPriority(0); //0 is default, but here if you want to set the priority
    }

    get errorMessage() {
        return this.lang('invalid credit card number');
    }

    validate() {
        this.isValid = validator.number(this.value).isValid;
        return this;
    }
}

export const ccNumber = new CreditCardNumber(); //`ccNumber` is more convienent to write than `new CreditCardNumber()`

ValidationRuleAsync

All rule objects which do validation in asynchronous mode, should inherit this class. This class has all methods and properties as owned by ValidationRule except the validate method of this class return a Promise object. For example, we have to validate a credit card number input like in ValidationRule example. But here, we have a list of valid card numbers in database. So, it must make an HTTP request to ask server to validate the number. We change validate method in the example before to be:

    async validate() {
        this.isValid = await fetch(
            `https://wwww.yourserver.com/check-cc-number?number=${encodeURIComponent(this.value)}`
        ).then(response => {
            //If card number has been registered in database, server returns HTTP status code 200 (OK)
            //If not, server returns 404 (Not Found)
            return response.ok;
        });
        return this;
    }

new Email() or email

The rule for examined the input value whether it's a valid email address or not.

new HttpReq(uri, option) or httpReq(uri, option)

This rule will make an HTTP request to validate the value. The validation is executed in asynchronous mode.

Parameters:

  • uri is the URI string for HTTP request. This parameter is required.
  • option defines the settings for HTTP request. This parameter is optional. option is a plain object whose one or more properties listed below (all properties are optional):
    • data is request data that will be sent to server. data can be a plain object or a URLSearchParams object. If data is set then the request will use POST method. name and value will be automatically included in data (you doesn't need to set them in data).
      If data is not set then the request will use GET method. name and value will be inserted into URI string as the query part. If you want to use POST method but have no data other than name and value, set data as an empty object ({}) or as new URLSearchParams() without setting any data.

    • headers is a plain object contains request HTTP headers. The keys of object are the header names and their values are their corresponding header values. For example:

      httpReq(
          'https://www.yourserver.com/checkdata',
          {
              headers: {
                  { Authorization: `Bearer ${publicKey}` },
                  {'X-Requested-With': 'MyApp'}
              }
          }
      )
    • silentOnFailure if it's true then there won't be any error message if a problem happens to the server response. The problems that can happen are timeout, response code is not ok etc. The input value is also considered valid. You must revalidate the input value on the server. In fact, backend validation on the server is still needed all time to avoid tampered data. By default, silentOnFailure is false (there will be an error message if a problem happens).

    • timeout defines the connection timeout in milliseconds. The default value is 0 (no timeout).

The server script that handles the request made by this rule object must return a boolean value (true is valid or false is invalid) or a string of the error message. For example, if using node express, the code would look like the following one:

app.get('/check-validity', function(req, res) {
    const validity = validate(req.query.value); //suppose the function returns object: {isValid: boolean, errorMessage: string}
    let responseText;
    if (validity.isValid) responseText = JSON.stringify(true); //or just "true"
    else {
        if (validity.errorMessage) responseText = JSON.stringify(validity.errorMessage);
        else responseText = JSON.stringify(false); //or just "false"
    }
    res.send(responseText);
});

new Integer() or integer

Checks if the input value is integer or not. If the input value is a string (such as getting from TextInput) and you want it considered as number, you must also specify numeric rule for the input. The numeric rule must have higher priority (default).

new Max(maxValue) or max(maxValue)

To limit the input value at maximum of maxValue. The data type of maxValue can be string, number or Date. If maxValue is number but the input value is string (such as getting from TextInput) then you must also specify numeric rule for the input. The numeric rule must have higher priority (default).
Property:

  • max is the maximum value (the same as maxValue parameter of contructor)

new Min(minValue) or min(minValue)

To limit the input value at minimum of minValue. The data type of minValue can be string, number or Date. If minValue is number but the input value is string (such as getting from TextInput) then you must also specify numeric rule for the input. The numeric rule must have higher priority (default).
Property:

  • min is the minimum value (the same as minValue parameter of contructor)

new Numeric() or numeric

To assess if the input value is numeric or not.

new Regex(pattern, flags) or regex(pattern, flags)

To examine if pattern applies to the input value. pattern can be a RegExp object or a pattern string. If pattern is a string, flags parameter is the flags to add to the pattern (see this doc for more information).

new Required() or required

It's to specify the input value cannot be empty. This rule is the highest priority, examined at the first time. If this rule is not specified then the input is optional. If optional then when the input is not filled, it's assessed as valid, the other rules that has been specified won't be examined.

Required.If(predicate) or required.if(predicate)

It's the same as required rule but under a condition. The predicate parameter is a function. If it returns true then the input is required. Otherwise, it's optional. The parameter for predicate function is the input value.

Required.If(() => false) or alwaysValid

Use this rule if you want to only use setErrorMessage method without applying any other rules.

new CustomRule(predicate, errorMessage) or rule(predicate, errorMessage)

If you need more complicated logic to assess whether the input value is valid or invalid, this rule fits for it. The predicate parameter is a function to asses the input value. The parameter of this function is the input value. The predicate function may return boolean (true is valid, false is invalid) or a string. If it returns a string then the input is considered as invalid. The returned string is the error message (by this way, you may create different error message for different condition). The errorMessage parameter is used as the error message if predicate function doesn't return a string (returns false). If you set messageFunc then the error message will be taken from messageFunc.

Example:

The example below is the validator to check whether the number is between 5 to 9. If not then the value is invalid. If the value is not a number then it return the error message "Not valid number". If the value less than 5 then the message is "The value is too small". If the value is higher than 9 then the message is "The value is too big".

rule(
    value => {
        const numb = parseFloat(value);
        if (isNaN(numb)) { //Needs more checking to ensure the `value` is really a number
            return false;
        }
        else if (numb < 5) {
            return 'The value is too small';
        }
        else if (numb > 9) {
            return 'The value is too big';
        }
        return true;
    },
    'Not valid number'
)

new CustomRuleAsync(predicate, errorMessage) or ruleAsync(predicate, errorMessage)

It is almost the same as rule rule. The difference is it runs in asynchronous mode. The predicate function for this rule doesn't return anything. As a replacement, to set the validation status (valid/invalid or the error message), it has a second parameter which is a function. The validation status is set using this function.

Example:

As an example, we change the example for rule to be an approprite one for ruleAsync.

ruleAsync(
    (value, resolve) => {
        const numb = parseFloat(value);
        if (isNaN(numb)) { //Needs more checking to ensure the `value` is really a number
            resolve(false);
        }
        else if (numb < 5) {
            resolve('The value is too small');
        }
        else if (numb > 9) {
            resolve('The value is too big');
        }
        else {
            resolve(true);
        }
    },
    'Not valid number'
)

new StrLength(minValue, maxValue) or strlen(minValue, maxValue) or strlenmax(maxValue)

After the input value is converted to string, this rule is to limit the length of the value string. The minimum length is specified by minValue parameter and the maximum length is specified by maxValue parameter. If minValue is undefined then the minimum length is 0. If maxValue is undefined then no limit for maximum length.
Properties:

  • max is the maximum length (the same as maxValue parameter of contructor)
  • min is the minimum length (the same as minValue parameter of contructor)

Messages

Each built-in rule object has default error message. All messages are collected in one object. You must inspect them in the case that you want to translate them to the other languages. The messages can be found in messages.js. The messages are listed in the following code:

{
    asyncFail: 'cannot validate',
    email: 'invalid email address',
    httpReq: {
        disconnected: "Can't connect to server",
        notOk: "Server failed to process data",
        invalid: "Can't interpret server response",
    },
    integer: 'must be the round number',
    invalid: 'invalid',
    max: 'maximum ${max}',
    min: 'minimum ${min}',
    numeric: 'invalid numeric value',
    required: 'required',
    strlenmax: "don't exceed ${max} characters",
    strlenmin: 'must be at least ${min} characters',
}

These default messages can be changed that will affect the whole app. For example, you want to change 'required' message to be 'must be filled'. To do that, insert some codes into index.js in the root directory of app like the following:

The lines which have bold font are the inserted code.

If you read the message for max or min rule, you find the special words ${max} and ${min}. They are the variable placeholder that will be replaced by the real value. The error message will be processed by str function. The second parameter for the function is the examined rule object. Therefore, the variable name in the template string is the property name of the rule object. For example, in the example before, you want to display the input name in the message. You must change the second bold line to be

messages.required = '${name} must be filled';

To make it works, you must also set the input name in withValidation name option.

Example App

There is an example app you can find here