react-input-mask
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.
- previousState: Input state before change. Only defined on
change
event. - currentState: Current raw input state. Not defined during component render.
- nextState: Input state with applied mask. Contains
value
andselection
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:
- Set
maskChar
to null and trim space after «+1» withbeforeMaskedStateChange
if no more digits are entered. - 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.
- 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:
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 lettermaskChar
: 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 themask
property) by changing this propertyalwaysShowMask
: the library usually shows the mask when the user focuses on the masked input; set this property totrue
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) orK
(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
and1
for the first digit. If the user entered 0, the second digit position allows any digit between1
and9
. If the user entered1
, the user can only enter digits between0
and2
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 from01
to28
for the date part, since 2022 February’s last day is28
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-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
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
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:
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.
- previousState: Input state before change. Only defined on
change
event. - currentState: Current raw input state. Not defined during component render.
- nextState: Input state with applied mask. Contains
value
andselection
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:
- Set
maskChar
to null and trim space after «+1» withbeforeMaskedStateChange
if no more digits are entered. - 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.
- 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:
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.