I'm trying to make credit/debit card form with React. I want to make autoinsert space after every 4 digit and to force the user type numbers only. For example, if input 1234567891234567 it will become with spaces 1234 5678 9123 4567. The problem is when I press backspace the spaces can't be deleted because I use onChange event. I'm new to React, probably need a different approach. What else I can use to make the backspace working properly and how to forbid writing of letters (digits only)?
const [cardNumber, setCardNumber] = useState('')
const handleChange = async (e) => {
if (e.target.value.length === 4) {
e.target.value += ' '
} else if (e.target.value.length === 9) {
e.target.value += ' '
} else if (e.target.value.length === 14) {
e.target.value += ' '
}
setCardNumber(e.target.value)
}
Id create a state variable to hold the cc-number
const [ccNumber, setCcNumber] = useState("");
And set the ccNumber
onChange
of the input
<input type="text" value={ccNumber} onChange={formatAndSetCcNumber} />
And inside fn formatAndSetCcNumber
I'd handle the logic
const formatAndSetCcNumber = e => {
const inputVal = e.target.value.replace(/ /g, ""); //remove all the empty spaces in the input
let inputNumbersOnly = inputVal.replace(/\D/g, ""); // Get only digits
if (inputNumbersOnly.length > 16) {
//If entered value has a length greater than 16 then take only the first 16 digits
inputNumbersOnly = inputNumbersOnly.substr(0, 16);
}
// Get nd array of 4 digits per an element EX: ["4242", "4242", ...]
const splits = inputNumbersOnly.match(/.{1,4}/g);
let spacedNumber = "";
if (splits) {
spacedNumber = splits.join(" "); // Join all the splits with an empty space
}
setCcNumber(spacedNumber); // Set the new CC number
};
Here is a demo