Маска для телефона react js

react-input-mask

Build Status npm version npm downloads

Input masking component for React. Made with attention to UX.

This is a development branch for version 3.0. For the latest stable version see v2 branch.

Demo

Table of Contents

  • Installation
  • Usage
  • Properties
  • Known Issues

Installation

npm install react-input-mask@next --save

react-input-mask requires React 16.8.0 or later. If you need support for older versions, use version 2.

Usage

import React from "react"
import InputMask from "react-input-mask";

function DateInput(props) {
  return <InputMask mask="99/99/9999" onChange={props.onChange} value={props.value} />;
}

Properties

Name Type Default Description
mask {String|Array<String, RegExp>} Mask format
maskPlaceholder {String} _ Placeholder to cover unfilled parts of the mask
alwaysShowMask {Boolean} false Whether mask prefix and placeholder should be displayed when input is empty and has no focus
beforeMaskedStateChange {Function} Function to modify value and selection before applying mask
children {ReactElement} Custom render function for integration with other input components

mask

Mask format. Can be either a string or array of characters and regular expressions.

<InputMask mask="99/99/99" />

Simple masks can be defined as strings. The following characters will define mask format:

Character Allowed input
9 0-9
a a-z, A-Z
* 0-9, a-z, A-Z

Any format character can be escaped with a backslash.

More complex masks can be defined as an array of regular expressions and constant characters.

// Canadian postal code mask
const firstLetter = /(?!.*[DFIOQU])[A-VXY]/i;
const letter = /(?!.*[DFIOQU])[A-Z]/i;
const digit = /[0-9]/;
const mask = [firstLetter, digit, letter, " ", digit, letter, digit];
return <InputMask mask={mask} />;

maskPlaceholder

// Will be rendered as 12/--/--
<InputMask mask="99/99/99" maskPlaceholder="-" value="12" />

// Will be rendered as 12/mm/yy
<InputMask mask="99/99/99" maskPlaceholder="dd/mm/yy" value="12" />

// Will be rendered as 12/
<InputMask mask="99/99/99" maskPlaceholder={null} value="12" />

Character or string to cover unfilled parts of the mask. Default character is «_». If set to null or empty string, unfilled parts will be empty as in a regular input.

alwaysShowMask

If enabled, mask prefix and placeholder will be displayed even when input is empty and has no focus.

beforeMaskedStateChange

In case you need to customize masking behavior, you can provide beforeMaskedStateChange function to change masked value and cursor position before it’s applied to the input.

It receieves an object with previousState, currentState and nextState properties. Each state is an object with value and selection properites where value is a string and selection is an object containing start and end positions of the selection.

  1. previousState: Input state before change. Only defined on change event.
  2. currentState: Current raw input state. Not defined during component render.
  3. nextState: Input state with applied mask. Contains value and selection fields.

Selection positions will be null if input isn’t focused and during rendering.

beforeMaskedStateChange must return a new state with value and selection.

// Trim trailing slashes
function beforeMaskedStateChange({ nextState }) {
  let { value } = nextState;
  if (value.endsWith("/")) {
    value = value.slice(0, -1);
  }

  return {
    ...nextState,
    value
  };
}

return <InputMask mask="99/99/99" maskPlaceholder={null} beforeMaskedStateChange={beforeMaskedStateChange} />;

Please note that beforeMaskedStateChange executes more often than onChange and must be pure.

children

To use another component instead of regular <input /> provide it as children. The following properties, if used, should always be defined on the InputMask component itself: onChange, onMouseDown, onFocus, onBlur, value, disabled, readOnly.

import React from 'react';
import InputMask from 'react-input-mask';
import MaterialInput from '@material-ui/core/Input';

// Will work fine
function Input(props) {
  return (
    <InputMask mask="99/99/9999" value={props.value} onChange={props.onChange}>
      <MaterialInput type="tel" disableUnderline />
    </InputMask>
  );
}

// Will throw an error because InputMask's and children's onChange props aren't the same
function InvalidInput(props) {
  return (
    <InputMask mask="99/99/9999" value={props.value}>
      <MaterialInput type="tel" disableUnderline onChange={props.onChange} />
    </InputMask>
  );
}

Known Issues

Autofill

Browser’s autofill requires either empty value in input or value which exactly matches beginning of the autofilled value. I.e. autofilled value «+1 (555) 123-4567» will work with «+1» or «+1 (5», but won’t work with «+1 (___) ___-____» or «1 (555)». There are several possible solutions:

  1. Set maskChar to null and trim space after «+1» with beforeMaskedStateChange if no more digits are entered.
  2. Apply mask only if value is not empty. In general, this is the most reliable solution because we can’t be sure about formatting in autofilled value.
  3. Use less formatting in the mask.

Please note that it might lead to worse user experience (should I enter +1 if input is empty?). You should choose what’s more important to your users — smooth typing experience or autofill. Phone and ZIP code inputs are very likely to be autofilled and it’s a good idea to care about it, while security confirmation code in two-factor authorization shouldn’t care about autofill at all.

Cypress tests

The following sequence could fail

cy.get("input")
  .focus()
  .type("12345")
  .should("have.value", "12/34/5___"); // expected <input> to have value 12/34/5___, but the value was 23/45/____

Since focus is not an action command, it behaves differently than the real user interaction and, therefore, less reliable.

There is a few possible workarounds

// Start typing without calling focus() explicitly.
// type() is an action command and focuses input anyway
cy.get("input")
  .type("12345")
  .should("have.value", "12/34/5___");

// Use click() instead of focus()
cy.get("input")
  .click()
  .type("12345")
  .should("have.value", "12/34/5___");

// Or wait a little after focus()
cy.get("input")
  .focus()
  .wait(50)
  .type("12345")
  .should("have.value", "12/34/5___");

Thanks

Thanks to BrowserStack for the help with testing on real devices

Modern web applications accept various user inputs: mouse clicks, screen tap and keyboard events, gestures, audio, and files.

Almost all web applications use keyboard events to capture detailed user input data. In other words, users can enter required data into typical web applications using their devices’ keyboards. For example, a user can enter a name, phone number, postal code, and email address during a particular web application’s registration process, and that information is then communicated to the backend.

Every user is different. They may have unique practices when it comes to form-filling, and they often try to use various formats in input fields. If a particular web application displays a raw text input field to capture a phone number, for example, the user may face several usability issues, such as not being able to predict the input field’s accepted format when they’re typing.

To avoid these types of issues, you can use input masks to provide user-friendly constraints for a particular user input field. In this article, I’ll explain how you can use input masking in your React applications.

What is input masking?

In user experience (UX) design, an input mask refers to a string template that is created based on a specific input format to prevent transcription errors. If the user tries to enter an invalid character, the masked input element blocks the invalid keystroke. For example, users won’t be able to enter English letters in a masked phone number field.

Frontend developers can use input masks to help ensure clean and valid user inputs are sent to their web application backends. At the same time, input masks motivate users to enter clean, correct inputs.

Input masking in React applications

There are several libraries that we can use to create input masks in React. The react-input-mask library is the most popular one, and it offers a very flexible API for developers. As a bonus, its behavior follows a UX-friendly design pattern.

You can either test this tutorial’s code snippets in a new React project or use them in your existing project. If you are going to get started with a new one, create a new project with the following command:

npx create-react-app input-masking

Next, install the react-input-mask npm package to create input masks in your React application.

npm install react-input-mask --save

Now, let’s try to create a simple masked input box for a phone number to check whether or not the library works. Add the following code into your App.js file or component.

import { useState } from 'react';
import InputMask from 'react-input-mask';
function PhoneInput(props) {
  return (
    <InputMask 
      mask='(+1) 999 999 9999' 
      value={props.value} 
      onChange={props.onChange}>
    </InputMask>
  );
}
function App() {
  const [phone, setPhone] = useState('');
  const handleInput = ({ target: { value } }) => setPhone(value);
  return (
    <div>
      <PhoneInput 
        value={phone} 
        onChange={handleInput}>
      </PhoneInput>
      <div style={{paddingTop: '12px'}}>Phone: {phone}</div>
    </div>
  );
}
export default App;

If you start the React development server with npm start or yarn start, you will see a masked input to enter a standard USA phone number (starting with the +1 dialing code), as shown below:

A simple example for masked input in React

A simple example for masked input in React.

We implemented a reusable component to accept phone numbers with the library’s InputMask component. The library’s generic mask component responds to the following React props:

  • mask: a template of the user input with predefined special characters — 9 for matching a number, a for a letter, and * for either a number or a letter
  • maskChar: this character can be used to fill the missing part of the input string; the default value is _ (underscore)
  • formatChars: you can change the default characters and regular expressions used for masking (in the mask property) by changing this property
  • alwaysShowMask: the library usually shows the mask when the user focuses on the masked input; set this property to true if you always want to show the mask

Like any other typical input element, we can use the onChange event to change the component state based on user inputs.

Basic react-input-mask examples

The input masking concept can be used in many different scenarios to enhance the user-friendliness of web applications. Check the following basic masking examples.

4-digit PIN

function PINInput(props) {
  return (
    <InputMask 
      mask='9999' 
      value={props.value} 
      onChange={props.onChange}
      placeholder='Enter PIN'>
    </InputMask>
  );
}

Google-style OTP

function GoogleOTP(props) {
  return (
    <InputMask 
      mask='G-999999' 
      maskChar={null}
      value={props.value} 
      onChange={props.onChange}>
    </InputMask>
  );
}

Standard credit card

function CreditCardInput(props) {
  return (
    <InputMask 
      mask='9999 9999 9999 9999' 
      value={props.value} 
      onChange={props.onChange}>
    </InputMask>
  );
}

Simple date input

Format: DD-MM-YYYY

function DateInput(props) {
  return (
    <InputMask
      mask='99-99-9999'
      placeholder='DD-MM-YYYY'
      value={props.value}
      onChange={props.onChange}>
    </InputMask>
  );
}

Format: YYYY-MM-DD

function DateInput(props) {
  return (
    <InputMask
      mask='9999-99-99'
      placeholder='YYYY-MM-DD'
      value={props.value}
      onChange={props.onChange}>
    </InputMask>
  );
}

The above masked input offers a simple date input with minimal constraints. It accepts only digits for the year, month, and day, but it accepts invalid user inputs like 2020–50–50. Most masked date inputs out there are implemented like this due to backend validations and the user’s knowledge about standard calendars.

However, I will explain how to block invalid dates from date input masks in the upcoming advanced masking examples section.

Advanced react-input-mask examples

The above examples use built-in regular expressions for masking. For example, the four-digit PIN’s mask uses 9 to match digits.

However, we cannot implement every masking rule with these predefined regular expressions. In other words, we need to define custom masking characters with different regular expressions. In some scenarios, we also need to have dynamic masks, where the user’s input directs the constraints of subsequent characters they enter in the field.

Below, we’ll look at some advanced examples that use custom masking characters and conditional masks.

A custom product code

Assume that you need to implement a mask to capture a valid product code in a grocery store management app written in React. Let’s define the rules for a valid product code as such:

  • Every product code starts with P (single product) or K (kit)
  • The rest of the product code consists of four even digits

We need to define custom masking characters to implement the above rules. Check the following code.

const MaskedInput = (props) => {
  // Defining custom masking characters
  // P will match P or K
  // 0 (zero) will match even digits
  const formatChars = {
    'P': '[PK]',
    '0': '[02468]'
  };
  return (<InputMask 
    mask='P0000' 
    value={props.value} 
    onChange={props.onChange}
    formatChars={formatChars}
    placeholder='Eg: P2266'>
  </InputMask>)
};

Time input

Assume that you need to ask the user to enter a time by using the hh:mm format. The simpler implementation of the time input mask may use the 99:99 mask, but users can still enter some invalid time entries, such as 59:10, 08:65, etc.

An input mask typically refers to a string input with a specific format — not related to strict validation. However, we can apply conditional masking based on user input to add improvements to these scenarios.

For example, we can only accept the digits 0, 1, and 2 for the first mask character position. After that, we can change the second mask character’s logic based on the first digit of the user input.

Take a look at the following code that uses conditional masking.

function TimeInput(props) {
  let mask = '12:34';
  let formatChars = {
    '1': '[0-2]',
    '2': '[0-9]',
    '3': '[0-5]',
    '4': '[0-9]'
  };

  let beforeMaskedValueChange = (newState, oldState, userInput) => {
    let { value } = newState;

    // Conditional mask for the 2nd digit base on the first digit
    if(value.startsWith('2'))
      formatChars['2'] = '[0-3]'; // To block 24, 25, etc.
    else
      formatChars['2'] = '[0-9]'; // To allow 05, 12, etc.
    return {value, selection: newState.selection};
  }
return (
    <InputMask 
      mask={mask}
      value={props.value} 
      onChange={props.onChange}
      formatChars={formatChars}
      beforeMaskedValueChange={beforeMaskedValueChange}>
    </InputMask>
  );
}

The beforeMaskedValueChange event will be triggered before the masked input field gets updated with the most recent user input. This means we can use it to change the mask dynamically.


More great articles from LogRocket:

  • Don’t miss a moment with The Replay, a curated newsletter from LogRocket
  • Learn how LogRocket’s Galileo cuts through the noise to proactively resolve issues in your app
  • Use React’s useEffect to optimize your application’s performance
  • Switch between multiple versions of Node
  • Discover how to animate your React app with AnimXYZ
  • Explore Tauri, a new framework for building binaries
  • Compare NestJS vs. Express.js

Improved date input

In the previous simple date input examples, we used the default format character 9 for the mask. Those implementations provide correct input masks for users to enter a date, but they don’t provide strict validation. Therefore, we can implement validation for the date mask like in the previous time input.

Format YYYY-MM-DD input

We are going to improve the date input mask by adding the following validation rules:

  • The month part accepts only 0 and 1 for the first digit. If the user entered 0, the second digit position allows any digit between 1 and 9. If the user entered 1, the user can only enter digits between 0 and 2 for the second digit’s location
  • The date part accepts digits based on the last day of the user-entered month. For example, if the user entered 2022-02, the masked input accepts only integers from 01 to 28 for the date part, since 2022 February’s last day is 28

We can implement the above validation rules with react-input-mask library API, as shown below.

import { useState } from 'react';
import InputMask from 'react-input-mask';

function TimeInput(props) {
  let mask = 'YYYY-mM-dD';
  let formatChars = {
    'Y': '[0-9]',
    'm': '[0-1]',
    'M': '[0-9]',
    'd': '[0-3]',
    'D': '[1-9]'
  };

  let beforeMaskedValueChange = (newState, oldState, userInput) => {
    let { value } = newState;

    let dateParts = value.split('-');
    let yearPart = dateParts[0];
    let monthPart = dateParts[1];
    let dayPart = dateParts[2]

    // Conditional mask for the 2nd digit of month based on the first digit
    if(monthPart.startsWith('1'))
      formatChars['M'] = '[0-2]'; // To block 13, 15, etc.
    else
      formatChars['M'] = '[1-9]'; // To allow 05, 08, etc - but blocking 00.

    // Conditional mask for day
    if(!yearPart.includes('_') && !monthPart.includes('_')) {

      // Find last day of the month
      let endOfMonth = new Date(`${yearPart}-01-01`);
      endOfMonth.setMonth(parseInt(monthPart));
      endOfMonth.setDate(0);
      let lastDayOfMonth = endOfMonth.getDate().toString();

      // Set [0-x] dynamically for the first digit based of last day
      formatChars['d'] = `[0-${lastDayOfMonth[0]}]`;

      if(dayPart.startsWith(lastDayOfMonth[0]))
        formatChars['D'] = `[0-${lastDayOfMonth[1]}]`; // Limit month's last digit based on last day
      else if(dayPart.startsWith('0'))
        formatChars['D'] = '[1-9]'; // To block 00.
      else
        formatChars['D'] = '[0-9]'; // To allow days to start with 1 Eg: 10, 12, 15, etc.
    }

    return {value, selection: newState.selection};
  }
  return (
    <InputMask
      mask={mask}
      value={props.value}
      onChange={props.onChange}
      formatChars={formatChars}
      beforeMaskedValueChange={beforeMaskedValueChange}>
    </InputMask>
  );
}

function App() {
  const [date, setDate] = useState('');
  const handleInput = ({ target: { value } }) => setDate(value);
  return (
    <div>
      <TimeInput
        value={date}
        onChange={handleInput}>
      </TimeInput>
      <div style={{paddingTop: '12px'}}>Date: {date}</div>
    </div>
  );
}
export default App;

Format DD-MM-YYYY input

For the DD-MM-YYYY date format, we have to enter the date before the month. Therefore, we cannot implement a proper validation for date digits.

As a solution, we can simplify the validation logic by allowing an integer value up to 31 for the date part regardless of the month — assuming that the user knows the end date of a specific month. Look at the following DD-MM-YYYY formatted date mask validation.

import { useState } from 'react';
import InputMask from 'react-input-mask';

function TimeInput(props) {
  let mask = 'dD-mM-YYYY';
  let formatChars = {
    'Y': '[0-9]',
    'd': '[0-3]',
    'D': '[0-9]',
    'm': '[0-1]',
    'M': '[1-9]'
  };

  let beforeMaskedValueChange = (newState, oldState, userInput) => {
    let { value } = newState;

    let dateParts = value.split('-');
    let dayPart = dateParts[0];
    let monthPart = dateParts[1];

    // Conditional mask for the 2nd digit of day based on the first digit
    if(dayPart.startsWith('3'))
      formatChars['D'] = '[0-1]'; // To block 39, 32, etc.
    else if(dayPart.startsWith('0'))
      formatChars['D'] = '[1-9]'; // To block 00.
    else
      formatChars['D'] = '[0-9]'; // To allow 05, 15, 25  etc.


    // Conditional mask for the 2nd digit of month based on the first digit
    if(monthPart.startsWith('1'))
      formatChars['M'] = '[0-2]'; // To block 15, 16, etc.
    else
      formatChars['M'] = '[1-9]'; // To allow 05, 06  etc - but blocking 00.

    return {value, selection: newState.selection};
  }
  return (
   <InputMask
      mask={mask}
      value={props.value}
      onChange={props.onChange}
      formatChars={formatChars}
      beforeMaskedValueChange={beforeMaskedValueChange}>
    </InputMask>
  );
}

function App() {
  const [date, setDate] = useState('');
  const handleInput = ({ target: { value } }) => setDate(value);
  return (
    <div>
      <TimeInput
        value={date}
        onChange={handleInput}>
      </TimeInput>
      <div style={{paddingTop: '12px'}}>Date: {date}</div>
    </div>
  );
}
export default App;

How to style input masks

The react-input-mask library renders masked input boxes using typical HTML inputs. Therefore, you can change styling by adding CSS classes as you wish. If you would like to use another component instead of HTML input, such as Material, implement your component as below.

import InputMask from 'react-input-mask';
import Input from '@material-ui/core/Input';

const MaskedInput = (props) => (
  <InputMask 
    mask='9999' 
    maskChar={null} 
    value={props.value} 
    onChange={props.onChange}
    placeholder='Enter your PIN'>
    {(inputProps) => <Input {...inputProps} />}
  </InputMask>
);

The above code snippet renders the Material input element instead of the native HTML input element as the masked PIN input field.

React input masking with Material UI components

react-input-mask alternatives

The react-input-mask library is a flexible library for creating any masked input. Unfortunately, it’s no longer actively maintained, so developers who use this library started looking for alternatives. As a result, now there is an active fork, and it is well-maintained.

Also, there are several alternative libraries that you can use instead of react-input-mask. If you are implementing masks for only digits, such as credit card numbers, dates, monetary values, the react-number-format library is a good alternative. For example, you can implement an input mask for a 4-digit PIN with the following code snippet.

import NumberFormat from 'react-number-format';

<NumberFormat format="####" mask="_" placeholder="Enter PIN"/>

The react-maskedinput library offers most features that react-input-mask has, such as dynamic masking, copy-pasting support, predefined format characters, etc. Also, it offers a feature to transform user inputs. For example, you can implement a simple license plate number mask that only accepts capital letters and digits, as shown below.

import MaskedInput from 'react-maskedinput';

<MaskedInput mask="AAA 1111" placeholder="ABC 1234"/> // A: Auto uppercase letter

However, the react-input-mask library offers a more comfortable way to handle complex masks with custom validations compared to react-maskedinput. Therefore, react-input-mask is suitable for complex and dynamic input masks.

Conclusion

The input masking concept is suitable for capturing user inputs with a specific, standard format, such as IP addresses, credit card numbers, product codes, and ID card numbers, among others.

The maintainer of the react-input-mask library is planning to release a new stable version (v3.0), and already there is a v3.0 alpha version with some enhancements and modifications to the API. The next stable release may contain their current development branch’s implementation. We used the current stable version (v2.0.4) in this tutorial because alpha-versioned dependencies are not recommended for any production system.

Cut through the noise of traditional React error reporting with LogRocket

LogRocket
is a React analytics solution that shields you from the hundreds of false-positive errors alerts to just a few truly important items. LogRocket tells you the most impactful bugs and UX issues actually impacting users in your React applications.

LogRocket Dashboard Free Trial Banner

LogRocket
automatically aggregates client side errors, React error boundaries, Redux state, slow component load times, JS exceptions, frontend performance metrics, and user interactions. Then LogRocket uses machine learning to notify you of the most impactful problems affecting the most users and provides the context you need to fix it.

Focus on the React bugs that matter —
try LogRocket today.

Introduction

An input mask is a string expression that constrains user input.

In this article, we’ll look at how to use an input mask to enforce input format in a React app.

Getting Started

We can add an input that enforces an input mask in a React app.

The react-input-mask package makes this very easy.

First, we run:

npm install react-input-mask --save

to install the package in our React project.

Then we can use it by adding it component provided by the package and specify the format of the input that we want to accept.

For instance, if we want to incorporate an input that takes a North American phone number, then we can write:

import React from "react";
import InputMask from "react-input-mask";

export default function App() {
  return (
    <div className="App">
      <InputMask mask="+1(999) 999-9999" maskChar=" " />
    </div>
  );
}

The mask prop has the input mask.

And the maskChar has the character we want to cover over the unfilled parts of a mask.

We can also use the formatChars prop to specify the format characters with the characters as keys and the corresponding regex string as a value.

alwaysShowMask is a boolean prop to specify whether we want to show the mask when input is empty and has no focys.

inputRef prop lets us specify the input ref of the input element so that we can manage focus, selection, etc.

We can use the formatChars prop as follows:

import React from "react";
import InputMask from "react-input-mask";

export default function App() {
  return (
    <div className="App">
      <InputMask
        formatChars={{
          "9": "[0-9]",
          a: "[A-Za-z]",
          "*": "[A-Za-z0-9]"
        }}
        mask="+1(999) 999-9999"
        maskChar=" "
      />
    </div>
  );
}

Setting State

We can set the input value to a state by using a change handler and the useState hook as usual with the InputMask component.

For instance, we can write:

import React from "react";
import InputMask from "react-input-mask";

export default function App() {
  const [phone, setPhone] = React.useState("");
  return (
    <div className="App">
      <InputMask
        value={phone}
        onChange={e => setPhone(e.target.value)}
        mask="+1(999) 999-9999"
        maskChar=" "
      />
      <p>{phone}</p>
    </div>
  );
}

We added onChange={e => setPhone(e.target.value)} to call setPhone when the input value changes.

It also takes a value prop so that we can set the input value to the phone number that we can change.

Now when we type something into the input, we’ll see the inputted value displayed below it.

Conclusion

We can add input with format being enforced by an input mask by using the react-input-mask package.

Using the component in the package, we can set the mask to enforce the format and handle input value changes like a regular input element.

The mask format can also be adjusted to our liking.

Web developer specializing in React, Vue, and front end development.

View Archive

Cover image for Input Mask in React without libraries

Juan Manuel Crego Risso

How to create a simple input mask only with React:

There are many libraries to do this, but it is always good to know how to do things that work in any type of web development. In this case we will create an entry for credit cards.

Step 1:

In a functional component we import

import React, { useState, useEffect, useRef } from 'react';

Enter fullscreen mode

Exit fullscreen mode

Now, we can created the component, in this case, the name is InputMask

const InputMask = () => {

}

export default InputMask;

Enter fullscreen mode

Exit fullscreen mode

Step 2:

We create first a new state, called card, and setCard is the function to modify that state, later we create a const called inputCard for the useRef hook.

import React, { useState, useEffect, useRef } from "react";

const InputMask = () => {
  const [card, setCard] = useState();
  const inputCard = useRef()
}

export default InputMask;

Enter fullscreen mode

Exit fullscreen mode

Now, we return an input with a ref property binding the InputCard const

import React, { useState, useEffect, useRef } from 'react';

const InputMask = () => {
  const [card, setCard] = useState();
  const inputCard = useRef();

  return (
    <>
      <input type="text" ref={inputCard} />
    </>
  );
};

export default InputMask;

Enter fullscreen mode

Exit fullscreen mode

If you do not know the hook useRef I share the official React documentation for useRef in this link

Step 3:

Now, we can target the events of the input, useRef works like a eventListener in JavaScript! For that, we create a function called handleChange and pass this function to the input in a onChange event

import React, { useState, useEffect, useRef } from 'react';

const InputMask = () => {
  const [card, setCard] = useState();
  const inputCard = useRef();

  const handleChange = () => {

  };

  return (
    <>
      <input type="text" ref={inputCard} onChange={handleChange} />
    </>
  );
};

export default InputMask;

Enter fullscreen mode

Exit fullscreen mode

Step 4:

In handleChange we use regex (Regular expressions) in a first step we use replace to replace all the expressions that not numbers with a blank space, later we use match for grouping the digits of the credit card in four groups of four digits each one

import React, { useState, useEffect, useRef } from 'react';

const InputMask = () => {
  const [card, setCard] = useState();
  const inputCard = useRef();

  const handleChange = () => {
    const cardValue = inputCard.current.value
      .replace(/D/g, '')
      .match(/(d{1,4})(d{0,4})(d{0,4})(d{0,4})/);
    inputCard.current.value = !cardValue[2]
      ? cardValue[1]
      : `${cardValue[1]}-${cardValue[2]}
      ${(`${cardValue[3] ? `-${cardValue[3]}` : ''}`)}
      ${(`${cardValue[4] ? `-${cardValue[4]}` : ''}`)}`;
  };

  return (
    <>
      <input type="text" ref={inputCard} onChange={handleChange} />
    </>
  );
};

export default InputMask;

Enter fullscreen mode

Exit fullscreen mode

Look at this, after match, we use aternary operator to set the value forinputCard in a first step, we set the condition of the second group to false, because group one will always exist, in a second step , we write many conditions, at the beginning group one, then the second group will continue, then if group three exists it will be after a -, the same is for group four…

Step 5:

Finally, we use the useEffect hook to manage the component lifecycle, inside useEffect, we set the callback for handleChange, and we specify the render when the card state changes, for this, we use setCard to save the input value on card state

import React, { useState, useEffect, useRef } from 'react';

const InputMask = () => {
  const [card, setCard] = useState();
  const inputCard = useRef();

  const handleChange = () => {
    const cardValue = inputCard.current.value
      .replace(/D/g, '')
      .match(/(d{0,4})(d{0,4})(d{0,4})(d{0,4})/);
    inputCard.current.value = !cardValue[2]
      ? cardValue[1]
      : `${cardValue[1]}-${cardValue[2]}${`${
          cardValue[3] ? `-${cardValue[3]}` : ''
        }`}${`${cardValue[4] ? `-${cardValue[4]}` : ''}`}`;
    const numbers = inputCard.current.value.replace(/(D)/g, '');
    setCard(numbers);
  };

  useEffect(() => {
    handleChange();
  }, [card]);

  return (
    <>
      <input type="text" ref={inputCard} onChange={handleChange} />
    </>
  );
};

export default InputMask;

Enter fullscreen mode

Exit fullscreen mode

This code works on phone inputs! in that case we must use (xxx) in the beginning of the input.

Demo

Hope you like this post!

Masking on the form controls like input, allows a user to enter predefined patterns. Adding a mask-like Number, Alphanumeric, Date etc prevents misinformation submission informs and also helps users to make data entry more friendly.

We can add validation to show errors after the user enters a wrong value, but this process takes unnecessary time to validate and even network consumption if validation is server-side. Masking helps in validating data in real-time and filling up correct details in specified formats.

In this guide, you will learn how to easily add Pattern making with various examples in a React js application. W will be using a profound library known as iMask JS in our React application. You can easily add some predefined masks on input controls also create custom patterns with ease in few steps.

Let’s get started!

How to Add Pattern Mask on Input Fields in React JS App?

  • Step 1 – Create React App
  • Step 2 – Install iMask Js Library Package
  • Step 3 – Using iMask Input Controls in React App
  • Step 4 – Phone, Email, Number, Username, Function, Date, Range Numbers Mask Example
  • Step 5 – Bootstrap Styles Input Tags with IMaskInput
  • Step 6 – See in Action

Step 1 – Create React App

if you already have an app, skip this step. Else execute the below command to download and create a new react application.

npx create-react-app react-mask-app

Move inside the application root

cd react-mask-app

Step 2 – Install iMask Js Library Package

After creating the React app, we will install the React adapter plugin for iMask Js. Execute the following npm command to install the package in our app:

npm install react-imask

Step 3 – Using iMask Input Controls in React App

To use the iMask feature in react js component, you simply need to import the IMaskInput component and use it in the template render function. Open the App.js file with the function component and add the <IMaskInput> component that will create an Input control that allows only Numbers.

import React from "react";
import "./App.css";
import { IMaskInput } from "react-imask";

export default function App() {
  return (
    <div className="container parent-component">
      <h1>Add Form Control Pattern Mask using iMask Plugin @ FreakyJolly</h1>

      <h4>Number Mask</h4>
      <IMaskInput
        mask={Number}
        value="123"
        onAccept={(value, mask) => console.log(value, mask)}
        placeholder="Enter number here"
      />

    </div>
  );
}

It will create a simple native Input control, having a number mask on it. The user will not be able to enter anything else Numbers.

Let’s have a look at various types of Mask implementation based on built-in Masks, Pattern Regex based Masks, Functions Masks and String masks as well.

We will also discuss how to use hooks provided by iMask to implement Mask on any existing Input control without any major modifications.

Step 4 – Phone, Email, Number, Username, Function, Date, Range Numbers Mask Example

We have updated the App.js function component to display various types on input controls with various Masks to restrict unintended values in the form controls.

We covered the following in our example implementation:

  • Number Mask
  • Phone Mask using String
  • Number (Range From-To) Mask
  • Date Mask
  • Email Address Mask using Regex
  • Email or Phone Mask using Min Max props
  • Custom(No Space, Only AlphaNumeric) Mask using functions

Open the App.js file and update as shown below:

import React from "react";
import "./App.css";
import { IMaskInput } from "react-imask";

const PhoneMask = "+{00}(0000)00-0000";
const EmailMask = /^S*@?S*$/;
const phoneEmailMask = [
  {
    mask: PhoneMask,
  },
  {
    mask: EmailMask,
  },
];

const customMask = function (value) {
  var pattern = new RegExp(/^[a-z0-9]+$/i);
  console.log(value, pattern.test(value));
  return pattern.test(value);
};

export default function App() {
  return (
    <div className="container parent-component">
      <h1>Add Form Control Pattern Mask using iMask Plugin @ FreakyJolly</h1>

      <h4>Number Mask</h4>
      <IMaskInput
        mask={Number}
        value="123"
        onAccept={(value, mask) => console.log(value, mask)}
        placeholder="Enter number here"
      />

      <h4>Phone Mask</h4>
      <IMaskInput
        mask={PhoneMask}
        value=""
        onAccept={(value, mask) => console.log(value, mask)}
        placeholder="Phone eg +71(9696)86-8602"
      />

      <h4>Number (Range From-To) Mask</h4>
      <IMaskInput
        mask={Number}
        min={100}
        max={2000}
        value=""
        onAccept={(value, mask) => console.log(value, mask)}
        placeholder="Number 100 - 2000"
      />

      <h4>Date Mask</h4>
      <IMaskInput
        mask={Date}
        min={new Date(2019, 0, 1)}
        max={new Date(2022, 0, 1)}
        onAccept={(value, mask) => console.log(value, mask)}
        placeholder="Date"
      />

      <h4>Email Address Mask</h4>
      <IMaskInput
        mask={EmailMask}
        onAccept={(value, mask) => console.log(value, mask)}
        placeholder="Email Address"
      />

      <h4>Email or Phone Mask</h4>
      <IMaskInput
        mask={phoneEmailMask}
        onAccept={(value, mask) => console.log(value, mask)}
        placeholder="Enter Contact"
      />

      <h4>Custom(No Space, Only AlphaNumeric) Mask</h4>
      <IMaskInput mask={customMask} placeholder="Username eg Jolly1239" />
    </div>
  );
}

You can see the working demo on StackBlitz on the tutorial’s end.

Step 5 – Bootstrap Styles Input Tags with IMaskInput

To add bootstrap style, you need to install the bootstrap package in the React JS app:

npm install bootstrap

After that, import the bootstrap.min.css file into App.js file. Then you just need to add classes and put labels as shown below:

import React from "react";
import "./App.css";
import "../node_modules/bootstrap/dist/css/bootstrap.min.css";
import { IMaskInput, IMaskMixin } from "react-imask";

const PhoneMask = "+{00}(0000)00-0000";
const EmailMask = /^S*@?S*$/;
const phoneEmailMask = [
  {
    mask: PhoneMask,
  },
  {
    mask: EmailMask,
  },
];

const customMask = function (value) {
  var pattern = new RegExp(/^[a-z0-9]+$/i);
  console.log(value, pattern.test(value));
  return pattern.test(value);
};

export default function App() {
  return (
    <div className="container parent-component">
      <form>
        <h1>Bootstrap Styles IMask Controls @ FreakyJolly</h1>

        <div className="form-group mt-3">
          <label>Number Mask</label>
          <IMaskInput
            className="form-control"
            mask={Number}
            value="123"
            onAccept={(value, mask) => console.log(value, mask)}
            placeholder="Enter number here"
          />
        </div>
        <div className="form-group mt-3">
          <label>Phone Mask</label>
          <IMaskInput
            className="form-control"
            mask={PhoneMask}
            value=""
            onAccept={(value, mask) => console.log(value, mask)}
            placeholder="Phone eg +71(9696)86-8602"
          />
        </div>

        <div className="form-group mt-3">
          <label>Number (Range From-To) Mask</label>
          <IMaskInput
            className="form-control"
            mask={Number}
            min={100}
            max={2000}
            value=""
            onAccept={(value, mask) => console.log(value, mask)}
            placeholder="Number 100 - 2000"
          />
        </div>

        <div className="form-group mt-3">
          <label>Date Mask</label>
          <IMaskInput
            className="form-control"
            mask={Date}
            min={new Date(2019, 0, 1)}
            max={new Date(2022, 0, 1)}
            onAccept={(value, mask) => console.log(value, mask)}
            placeholder="Date"
          />
        </div>

        <div className="form-group mt-3">
          <label>Email Address Mask</label>
          <IMaskInput
            className="form-control"
            mask={EmailMask}
            onAccept={(value, mask) => console.log(value, mask)}
            placeholder="Email Address"
          />
        </div>

        <div className="form-group mt-3">
          <label>Email or Phone Mask</label>
          <IMaskInput
            className="form-control"
            mask={phoneEmailMask}
            onAccept={(value, mask) => console.log(value, mask)}
            placeholder="Enter Contact"
          />
        </div>

        <div className="form-group mt-3">
          <label>Custom(No Space, Only AlphaNumeric) Mask</label>
          <IMaskInput
            className="form-control"
            mask={customMask}
            placeholder="Username eg Jolly1239"
          />
        </div>
      </form>
    </div>
  );
}

Here we added the className prop with bootstrap classes. instead on Bootstrap, you can customise Input controls as per your needs in a similar manner.

Step 6 – See in Action

Finally, you can run the application by hitting npm start to start the application at the following URL:

http://localhost:3000

Check working demo @ StackBlitz here:

Build Status npm version npm downloads

Input masking component for React. Made with attention to UX.

This is a development branch for version 3.0. For the latest stable version see v2 branch.

Demo

Table of Contents

  • Installation
  • Usage
  • Properties
  • Known Issues

Installation

npm install react-input-mask@next --save

react-input-mask requires React 16.8.0 or later. If you need support for older versions, use version 2.

Usage

import React from "react"
import InputMask from "react-input-mask";

function DateInput(props) {
  return <InputMask mask="99/99/9999" onChange={props.onChange} value={props.value} />;
}

Properties

Name Type Default Description
mask {String|Array<String, RegExp>} Mask format
maskPlaceholder {String} _ Placeholder to cover unfilled parts of the mask
alwaysShowMask {Boolean} false Whether mask prefix and placeholder should be displayed when input is empty and has no focus
beforeMaskedStateChange {Function} Function to modify value and selection before applying mask
children {ReactElement} Custom render function for integration with other input components

mask

Mask format. Can be either a string or array of characters and regular expressions.

<InputMask mask="99/99/99" />

Simple masks can be defined as strings. The following characters will define mask format:

Character Allowed input
9 0-9
a a-z, A-Z
* 0-9, a-z, A-Z

Any format character can be escaped with a backslash.

More complex masks can be defined as an array of regular expressions and constant characters.

// Canadian postal code mask
const firstLetter = /(?!.*[DFIOQU])[A-VXY]/i;
const letter = /(?!.*[DFIOQU])[A-Z]/i;
const digit = /[0-9]/;
const mask = [firstLetter, digit, letter, " ", digit, letter, digit];
return <InputMask mask={mask} />;

maskPlaceholder

// Will be rendered as 12/--/--
<InputMask mask="99/99/99" maskPlaceholder="-" value="12" />

// Will be rendered as 12/mm/yy
<InputMask mask="99/99/99" maskPlaceholder="dd/mm/yy" value="12" />

// Will be rendered as 12/
<InputMask mask="99/99/99" maskPlaceholder={null} value="12" />

Character or string to cover unfilled parts of the mask. Default character is «_». If set to null or empty string, unfilled parts will be empty as in a regular input.

alwaysShowMask

If enabled, mask prefix and placeholder will be displayed even when input is empty and has no focus.

beforeMaskedStateChange

In case you need to customize masking behavior, you can provide beforeMaskedStateChange function to change masked value and cursor position before it’s applied to the input.

It receieves an object with previousState, currentState and nextState properties. Each state is an object with value and selection properites where value is a string and selection is an object containing start and end positions of the selection.

  1. previousState: Input state before change. Only defined on change event.
  2. currentState: Current raw input state. Not defined during component render.
  3. nextState: Input state with applied mask. Contains value and selection fields.

Selection positions will be null if input isn’t focused and during rendering.

beforeMaskedStateChange must return a new state with value and selection.

// Trim trailing slashes
function beforeMaskedStateChange({ nextState }) {
  let { value } = nextState;
  if (value.endsWith("/")) {
    value = value.slice(0, -1);
  }

  return {
    ...nextState,
    value
  };
}

return <InputMask mask="99/99/99" maskPlaceholder={null} beforeMaskedStateChange={beforeMaskedStateChange} />;

Please note that beforeMaskedStateChange executes more often than onChange and must be pure.

children

To use another component instead of regular <input /> provide it as children. The following properties, if used, should always be defined on the InputMask component itself: onChange, onMouseDown, onFocus, onBlur, value, disabled, readOnly.

import React from 'react';
import InputMask from 'react-input-mask';
import MaterialInput from '@material-ui/core/Input';

// Will work fine
function Input(props) {
  return (
    <InputMask mask="99/99/9999" value={props.value} onChange={props.onChange}>
      <MaterialInput type="tel" disableUnderline />
    </InputMask>
  );
}

// Will throw an error because InputMask's and children's onChange props aren't the same
function InvalidInput(props) {
  return (
    <InputMask mask="99/99/9999" value={props.value}>
      <MaterialInput type="tel" disableUnderline onChange={props.onChange} />
    </InputMask>
  );
}

Known Issues

Autofill

Browser’s autofill requires either empty value in input or value which exactly matches beginning of the autofilled value. I.e. autofilled value «+1 (555) 123-4567» will work with «+1» or «+1 (5», but won’t work with «+1 (___) ___-____» or «1 (555)». There are several possible solutions:

  1. Set maskChar to null and trim space after «+1» with beforeMaskedStateChange if no more digits are entered.
  2. Apply mask only if value is not empty. In general, this is the most reliable solution because we can’t be sure about formatting in autofilled value.
  3. Use less formatting in the mask.

Please note that it might lead to worse user experience (should I enter +1 if input is empty?). You should choose what’s more important to your users — smooth typing experience or autofill. Phone and ZIP code inputs are very likely to be autofilled and it’s a good idea to care about it, while security confirmation code in two-factor authorization shouldn’t care about autofill at all.

Cypress tests

The following sequence could fail

cy.get("input")
  .focus()
  .type("12345")
  .should("have.value", "12/34/5___"); // expected <input> to have value 12/34/5___, but the value was 23/45/____

Since focus is not an action command, it behaves differently than the real user interaction and, therefore, less reliable.

There is a few possible workarounds

// Start typing without calling focus() explicitly.
// type() is an action command and focuses input anyway
cy.get("input")
  .type("12345")
  .should("have.value", "12/34/5___");

// Use click() instead of focus()
cy.get("input")
  .click()
  .type("12345")
  .should("have.value", "12/34/5___");

// Or wait a little after focus()
cy.get("input")
  .focus()
  .wait(50)
  .type("12345")
  .should("have.value", "12/34/5___");

Thanks

Thanks to BrowserStack for the help with testing on real devices

Overview

This is a step by step on how to create a component that validates a masked phone field using Material UI and React Number Format library. You can get the code for this post at the Full Stack Soup GitHub Repo here. The input uses the react-text-mask library and Material UI to build a phone input field that only accepts 10 digit phone numbers. The field will have the standard blue borders unless it has been touched. Using the error properties the field will have red borders if the number does not meet the 10 digit validation rule.

Other Related Articles

Please check out the following article with source files on GitHub.

Source Files For This Article

Get Source Code

Prerequisite

Create a new React-App.

npx create-react-app my-app
cd my-app

React Material UI Version 4

Install the Material Core with Node Package Manager.

npm install @material-ui/core @material-ui/icons

React Input Mask

Install the React Text Mask with Node Package Manager.

npm install react-input-mask

Parent Form Class Component

Create a new class component labeled FormParent.js. Add the following imports and state variables. Grid is used to align the field and submit button.

import React, {Component} from 'react';
import Grid from '@material-ui/core/Grid';
import Button from '@material-ui/core/Button';
import InputPhoneField from './InputPhoneField';

export default class OfferSupportForm extends React.Component {

constructor(props) {
     super(props);
     this.state = {
         Phone: '',
         IsValidPhone: false,
     };           
     this.handlePhoneNumberChange.bind(this);
}

Handle Input and Submit Events

Handle both phone number and submit events.

handlePhoneNumberChange = (value, isValid) => {        
    this.setState({Phone: value, isValidPhone: isValid});                        }

handleSubmitForm = (event) => {        
  console.log('handleSubmitForm  ', event);
}

Render Phone Field

Render the Input Field and the Submit Button. Notice the submit button is disabled until IsValidPhone is equal to true.

 render() {
    return (                        
        <>            
            <Grid container spacing={1} style={{marginTop: '20px'}}>        
            
                <Grid sm={4} align="left"></Grid>
                
                <Grid sm={1} >                    
                    <InputPhoneField    helperText="(Required)" 
                                        label="Phone" 
                                        fieldName="Phone" 
                                        handleChange={this.handlePhoneNumberChange}  />
                </Grid>

                <Grid sm={1} align="right" className="fieldLayoutT25B25R5">                    
                    {this.state.IsValidPhone === true ?
                        <Button variant="contained"  color="primary" onClick={this.handleSubmitForm}>                             
                            Submit
                        </Button>
                        :
                        <Button variant="contained"  color="primary" disabled>                             
                            Submit
                        </Button>
                    }                                                             
                </Grid>
                        
            </Grid>                                            
        </>
    );
}

Masked Input Component

Create a new JavaScript file labeled InputPhoneFIeld.js and import the following libraries.

import React from 'react';
import PropTypes from 'prop-types';
import MaskedInput from 'react-text-mask';
import InputLabel from '@material-ui/core/InputLabel';
import FormControl from '@material-ui/core/FormControl';
import FormHelperText from '@material-ui/core/FormHelperText';
import OutlinedInput from '@material-ui/core/OutlinedInput';

Masking the Input

Create a function using <MaskedInput /> to define the Mask and valid characters, in this case numbers.

The mask{[‘(‘, /[1-9]/, /d/, /d/, ‘)’, ‘ ‘, /d/, /d/, /d/, ‘-‘, /d/, /d/, /d/, /d/]} will allow three digit area code in braces following by another seven numbers with a hyphen after the third character.

function TextMaskCustom(props) {
  const { inputRef, ...other } = props;

  return (
    <MaskedInput      
      {...other}
      ref={(ref) => {
        inputRef(ref ? ref.inputElement : null);
      }}
      mask={['(', /[1-9]/, /d/, /d/, ')', ' ', /d/, /d/, /d/, '-', /d/, /d/, /d/, /d/]}
      placeholderChar={'u2000'}
      showMask
    />
  );
}

In the function portion of the component set the phone number state and the change event handler. The handleChange() will count the number of digits 0-9 and if there are 10 digits, set a boolean variable to true. Both the phone n umber and validation boolean variable are sent to the parent by props.handlePhoneNumberChange( val, isValid ).

export default function InputMaskedPhoneField(props) {

  const [phoneNumber, setPhoneNumber] = React.useState(0)
  
  const handleChange = event => {
    const val = event.target.value;
    
    let count = 0;
    
    for (let i = 0; i < val.length; i++) 
      if (val.charAt(i) in [0,1,2,3,4,5,6,7,8,9]) 
          count++
    
    var isValid = (count === 10) ? true : false;
    
    setPhoneNumber(val);
    props.handlePhoneNumberChange(val, isValid);
  }

Render the Phone Number Input Field

Render the TextMaskCustom() function in OutlinedInput

Set the inputComponent property to TextMaskCustom().

The input field will render as an outlined field with the label embedded in the upper left using the InputLabelProps setting shrink to true.

  return (
    <>
      <FormControl  variant="outlined" size={'small'} >
        <InputLabel htmlFor="phone" >Phone</InputLabel>        
        <OutlinedInput                     
          onChange={(e) => handleChange(e)}
          name="phone"
          label="Phone"
          size={'small'}
          value={phoneNumber}
         // Shrink Label
          InputLabelProps={{
            shrink: true,
          }}
          inputComponent={TextMaskCustom}
        />
        <FormHelperText id="my-helper-text">{props.helperText}</FormHelperText>
      </FormControl>
    </>
  );

Material Field Error Property

In addition to disabling a Submit Button we can use the error property in Material <TextField /> which will show a red border input. Before showing an error when the form hasn’t been touched we can set another variable to track if the field is pristine or dirty. In the example below we just want to know is the field is dirty (has been modified by the user). Also we can contain the states inside the input component.

const [isValid, setIsValid] = useState(false)  
const [dirty, setDirty] = useState(false);

Show Error

Using the error property to show a red border if the field does not have a valid phone number.

error={dirty && !isValid}              

Pristine or Dirty Input

Using the onBlur() event, set the dirty to true. This means the user touched the field and went elsewhere on the form.

  <OutlinedInput                                     
    error={dirty && isValid === false}                                        
    onBlur={() => setDirty(true)}
    onChange={(e) => handleChange(e)}
    name="phone"
    label="Phone"
    size={'small'}          
    value={phoneNumber}
    InputLabelProps={{
      shrink: true,
    }}
    inputComponent={TextMaskCustom}
  />

Validation With Formik

Formik with Yup are the most commonly used form validation library combo for react. The method above is easier to understand at first but can result in more code to maintain.

Other Articles related to Form Validation with Formik & Yup

Please check out the following articles each with source files for a working example on GitHub.
React Form Validation with Formik & Yup Click Here.
React Stepper Form Validation with Formik & Yup Click Here.

Install Formik and Yup

Formik and Yup are used for form validation.

npm i formik
npm i yup

Yup Validation Schema

Import the following libraries

import { useFormik } from 'formik';
import * as yup from 'yup';

Create a validation schema with Yup, This can validate against the masked phone number Regex.

const phoneRegExp = /^((+[1-9]{1,4}[ -]?)|(([0-9]{2,3})[ -]?)|([0-9]{2,4})[ -]?)*?[0-9]{3,4}[ -]?[0-9]{3,4}$/;

const validationSchema = yup.object({
  phone: yup
    .string('Enter your phone number')
    .matches(phoneRegExp, 'Phone number is not valid')
    .required('Phone is required'),  

});

Formik

Create a formik function with the useFormik() hook. The validationSchema defined with Yup will check if the input is valid and if it passes then submit the form.

const formik = useFormik({
    initialValues: {
      phone: '',
    },
    validationSchema: validationSchema ,    
    onSubmit: values => {     
        // Handle Submit
    },
});

Masked Input

The input events and properties, onChange, helperText, error, and value are handled by formik.

<OutlinedInput                                     
    name="phone"
    label="Phone"
    size={'small'}          
    value={props.formik.values.phone}
    error={props.formik.touched.phone &&      Boolean(props.formik.errors.phone)}
    helperText={props.formik.touched.phone && props.formik.errors.phone}    
    onChange={props.formik.handleChange}
    InputLabelProps={{
      shrink: true,
    }}
    inputComponent={TextMaskCustom}
  />

Submit Form

The onClick calls the formik.handleSubmit event

<Button variant="contained" color="primary" onClick={formik.handleSubmit}>
    Submit
</Button>

A comprehensive guide will help you understand how to implement pattern masking in form input controls within React app. To add the patterned masking in React, we will use the iMask JavaScript plugin in React application.

In form validation, every input control is validated. A form validation process is genuinely refraining from gathering wrong information. If validation is not implemented correctly, it may end up your inbox filled with reluctant or spammy information.

What if we told you a new paradigm in form validation?

Input pattern masking – In form input controls, we can effortlessly yet eloquently add pattern masking. You can add a mask on the phone, number, date, email input controls.

This input masking feature will stop site visitors from submitting wrong information. It is as easy as pie, even it makes the form submission process more conventional.

We will use the iMask library to add a mask on form values in React. The iMask js allows you to validate the form data on the go in conjunction with the predefined formats.

The iMask is a vanilla JavaScript input mask package. It offers tons of features that give you robust control over form input values.

It doesn’t just support input masking in React, but it also supports other Vue, Angular, React Native, and Svelte frameworks.

How to Integrate Pattern Mask in Phone, Number, Date, Email Inputs in React Js

  • Step 1: Download New React Project
  • Step 2: Install Bootstrap Library
  • Step 3: Add iMask Package in React
  • Step 4: Build Form Component
  • Step 5: Register Form Component
  • Step 6: Invoke React Application

Download New React Project

First, open the command prompt and get ready to evoke the installation process of the new React application.

Just type the below command and hit enter.

You may jump on to a subsequent step if the app already exists.

npx create-react-app hello-web

Wait until the app is utterly installed, thereafter get into the application directory.

cd hello-web

Install Bootstrap Library

In the frontend development realm, it is always good to have acquaintance with CSS.

However, if you are trying your hand newly and willing to know the secret to create the UI at a blazingly fast speed.

So, You must try out Bootstrap. We install this package to build the UI at a rapid pace.

npm install bootstrap

It hasn’t been finished yet, to make the Bootstrap work in your React project.

Ensure that you add or import the bootstrap CSS in primary App.js template.

import React from 'react'
import 'bootstrap/dist/css/bootstrap.min.css'

export default function App() {
  return (
    <div>
    </div>
  )
}

Add iMask Package in React

Up until now, you have created and respectively entered into the app. In this step, you will see how to install the iMask js package into the React app.

We assume you are into the terminal window, copy the given command, paste onto the command-line tool and execute it.

npm i react-imask

Build Input Pattern Mask Component

Ever since we are using it, we fell in love of every aspect of this eloquent framework. In React, things are pretty easy to manage, all hail to its creators.

Let us try to comprehend the process of adding pattern masking in form input controls.

You have to make a new MaskForm.js file, in general such type of files, which handle particular feature or functionality is called by the name of component.

You have to append the following code in component/MaskForm.js file.

import React from 'react'
import { IMaskInput } from 'react-imask'

const PhoneContactMask = '+{00}(0000)00-0000'
const EmailAddMask = /^S*@?S*$/

export default function MaskForm() {
  return (
    <div className="mt-3">
      <form>
        <h2>React Add Pattern Mask in Inputs Example - RemoteStack</h2>

        <div className="form-group mb-4">
          <label>
            <strong>Phone Mask</strong>
          </label>
          <IMaskInput
            className="form-control"
            placeholder="+31(8787)75-9513"
            mask={PhoneContactMask}
            onAccept={(value, mask) => console.log(value, mask)}
            value=""
          />
        </div>

        <div className="form-group mb-4">
          <label>
            <strong>Number (Range From-To) Mask</strong>
          </label>
          <IMaskInput
            className="form-control"
            placeholder="Number 50 - 1500"
            mask={Number}
            min={50}
            max={1500}
            onAccept={(value, mask) => console.log(value, mask)}
            value=""
          />
        </div>

        <div className="form-group mb-4">
          <label>
            <strong>Date Mask</strong>
          </label>
          <IMaskInput
            className="form-control"
            placeholder="Date"
            mask={Date}
            min={new Date(2018, 0, 1)}
            max={new Date(2021, 0, 1)}
            onAccept={(value, mask) => console.log(value, mask)}
          />
        </div>

        <div className="form-group mb-4">
          <label>
            <strong>Email Mask</strong>
          </label>
          <IMaskInput
            className="form-control"
            placeholder="Email"
            mask={EmailAddMask}
            onAccept={(value, mask) => console.log(value, mask)}
          />
        </div>
      </form>
    </div>
  )
}

We have blatantly added the pattern mask in Phone, Number, Date, and Email form Input fields with iMask js library.

Register Form Component

The following process is to diligently import and call the new component in the App.js template.

import React from 'react'
import 'bootstrap/dist/css/bootstrap.min.css'
import MaskForm from './components/MaskForm'

export default function App() {
  return (
    <div className="container mt-2">
      <MaskForm />
    </div>
  )
}

Therefore, go ahead, copy the given code and insert the provided code with delicacy into the suggested locus.

Invoke React Application

Most probably, you have followed every instruction with utmost attentiveness.

Subsequently, make sure to start the React app; you can do it with the suggested command.

npm start

Even though the app starts automatically on the browser, if somehow it doesn’t.

Copy the above URL, put it into the address bar and hit enter.

http://localhost:3000

Here is how the output appears on the browser:

React Js Integrate Pattern Mask in Input Fields with iMask Tutorial

Summary

We displayed the instructions for incorporating pattern masking in form input fields in React application with so much persistence.

This tutorial might be a boon for those just getting started in React and who have no prior knowledge of pattern masking and the iMask JavaScript library.

However, you may go with the conventional method where the user sees the error messages after providing the wrong values. But this process can be made better by the input control masking.

This quick React guide will make your development journey facile, as well as remove all the conjugated obstacles from your learning journey.

  • Маска для телефона jquery
  • Маска для номера телефона input
  • Маска для лица номер 1
  • Маска для волос номера
  • Маска для ввода номера телефона