skip to Main Content

I want to create an app on React where a user can input a number of his bank card. In the input field will be a default value with 16 zeros and every next zero will immediately change to the inputed number.

import React, { useState } from 'react'


function CardNumber() {
  const [value, setValue] = useState('')


  const changeState = event => {
    setValue(event.target.value)
  }


  return (
    <input
    value={value}
    onChange={changeState}
    placeholder='0000 0000 0000 0000'/>
  )

}

export default CardNumber

2

Answers


  1. import React, { useState } from 'react';
        
        function CardNumber() {
          const [value, setValue] = useState('0000 0000 0000 0000');
        
          const changeState = event => {
            const inputValue = event.target.value;
            const sanitizedValue = inputValue.replace(/D/g, '');
            const formattedValue = sanitizedValue.replace(/(.{4})/g, '$1 ').trim();
            setValue(formattedValue);
          };
        
          return (
            <input
              value={value}
              onChange={changeState}
              maxLength={19}
              placeholder='0000 0000 0000 0000'
            />
          );
        }
        
        export default CardNumber;
    

    I just added for you that input length doesn’t exceed 16 digits +3 spaces ( total 19) and the formatted Value is 4 digits grouped. I hope this will do the job for you

    Login or Signup to reply.
  2. Using the onKeyUp event, you can access the event.key that was pressed by the user.

    So the idea here, is to store those numbers in an array first.
    Then on render, use that array to format what is to be shown.

    You wish to have some zeros after the entered digits. So on render, the input always is 19 characters (including 3 space)…
    Your users are then loosing the ability to place the cursor in the middle of the credit card number to change a specific digit.

    Note that this maybe considered bad UI, but it may be your choice to do it anyway. But the walk around here is extra simple, thanks to CSS:

    .creditCardInput {
      caret-color: transparent;
    }
    

    So the caret not being visible… the user will not be tempted to place it in the middle.
    This may be acceptable.

    I made sure to allow the Backspace key to have an effect.
    I also added a visual indication for the user to know the card number is complete:

    .creditcardComplete {
      background-color: green;
    }
    

    Here is the code… The demo is on CodeSandbox.

    import React, { useState, useCallback } from "react";
    
    function CardNumber() {
      const [cardNumbers, setCardNumber] = useState([]);
    
      const handleKeyUp = (event) => {
        const keyPressed = event.key;
    
        // If the key pressed is not a number
        if (!/d/.test(keyPressed)) {
          if (keyPressed === "Backspace") {
            setCardNumber((prev) => {
              const newValue = [...prev];
              newValue.pop();
    
              return newValue;
            });
          }
    
          return;
        }
    
        setCardNumber((prev) => {
          // If we already have 16 numbers, return unchanged state
          if (prev.length >= 16) {
            return prev;
          }
    
          // Add the new number to the array
          const newValue = [...prev];
          newValue.push(keyPressed);
    
          return newValue;
        });
      };
    
      const formatCardNumbers = (cardNumbers) => {
        console.log(`cardNumbers are: ${JSON.stringify(cardNumbers)}`);
    
        // Generate the extra zeros to add up
        const zeros = new Array(16 - cardNumbers.length).fill(0).join("");
        const displayNumbers = (cardNumbers.join("") + zeros)
          .replace(/(.{4})/g, "$1 ")
          .trim();
    
        return displayNumbers;
      };
    
      return (
        <input
          className={`creditCardInput ${
            cardNumbers.length === 16 ? "creditcardComplete" : ""
          }`}
          value={formatCardNumbers(cardNumbers)}
          onChange={() => {}}  // This is just to avoid a react warning
          onKeyUp={handleKeyUp}
          placeholder="0000 0000 0000 0000"
        />
      );
    }
    
    export default CardNumber;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search