Source:  Twitter logo

In React Native, I have two <TextInput/>, one which receives MM/YY and the other 16-digit card number.

In the first input for MM/YY, I have:

  <TextInput
    onChangeText={this._handlingCardExpiry.bind(this)}
    placeholder='MM/YY'
    value={cardExpiry}
  />

And for the 16-digit card number:

  <TextInput
    onChangeText={this._handlingCardNumber.bind(this)}
    placeholder='0000 0000 0000 0000'
    value={cardNumber}
  />

For the expiry, I attempted to split them up and store in the value property as ${cardMonth}/${cardYear}, but the text would not even rather, and adding space after every 4 digits to the card number input cause texts to not appear in the input.

What would be the right approach to handling the following with the < TextInput />'s onChangeText and value properties:

  1. When a user starts typing in <TextInput/>, show a / in the middle and inputting first two digits would appear before the / and next two after.
  2. When a user starts typing in 16-digit card number, automatically place space after every 4 digits entered in.

Thank you in advance and will vote up/accept the answer.

I'll add the handling card number, since it was part of the original question:

_handlingCardNumber(number) {
  this.setState({
    cardNumber: number.replace(/\s?/g, '').replace(/(\d{4})/g, '$1 ').trim()
  });
}

where:

  <TextInput
    onChangeText={(text) => this._handlingCardNumber(text)}
    placeholder='0000 0000 0000 0000'
    value={this.state.cardNumber}
  />
13 users liked answer #0dislike answer #013
Samuli Hakoniemi profile pic
Samuli Hakoniemi

You should be using a state variable to update your TextInput value, so that each time the text changes, you can handle the change and update the state, thereby updating the value as you want within the component. For example, try the following:

<TextInput
    onChangeText={this._handlingCardExpiry.bind(this)}
    placeholder='MM/YY'
    keyboardType={'numeric'}
    value={this.state.cardExpiry}
   />

Above, I have changed the value of TextInput to be this.state.cardExpiry. You can do something similar for the other component. Also note that I've added keyboardType={'numeric'} which essentially provides the user with a keyboard that only allows them to input numbers. Below, I'll show you how to handle a text change and update the state.

_handlingCardExpiry(text) {
    if (text.indexOf('.') >= 0 || text.length > 5) {
        // Since the keyboard will have a decimal and we don't want
        // to let the user use decimals, just exit if they add a decimal
        // Also, we only want 'MM/YY' so if they try to add more than
        // 5 characters, we want to exit as well
        return;
    }

    if (text.length === 2 && this.state.cardExpiry.length === 1) {
        // This is where the user has typed 2 numbers so far
        // We can manually add a slash onto the end
        // We check to make sure the current value was only 1 character
        // long so that if they are backspacing, we don't add on the slash again
        text += '/'
    }

    // Update the state, which in turns updates the value in the text field
    this.setState({
        cardExpiry: text
    });
}

You can try this code and tweak it to fit your needs, but this is the general concept. You can apply similar formatting to your 16-digit field, where every 4 digits you add a space before updating the state.

8 users liked answer #1dislike answer #18
Joseph Roque profile pic
Joseph Roque

Copyright © 2022 QueryThreads

All content on Query Threads is licensed under the Creative Commons Attribution-ShareAlike 3.0 license (CC BY-SA 3.0).