0

I am trying to build payment screen. And after writing this code, in expiry date input is not possible to type anything. when you type on keyboard numbers nothing is typed in text input. Also there is no any error on the screen. I write 2 code blocks. First one is the function for the card number and 2nd block of functions is for expiry date input. Those functions I found on the other question answers. Here is the code:

 constructor() {
  super()
  this.state = {
    isReady: false
  }
}

componentDidMount() {
  this.setState({
    isReady: true
  })
}
onChange(text) {
    let newText = '';
    let numbers = '0123456789';

    for (var i = 0; i < text.length; i++) {
        if ( numbers.indexOf(text[i]) > -1 ) {
            newText = newText + text[i];
        }
    }
    this.setState({myNumber: newText})
}
formatFunction(cardExpiry = ""){
   //expiryDate will be in the format MMYY, so don't make it smart just format according to these requirements, if the input has less than 2 character return it otherwise append `/` character between 2nd and 3rd letter of the input.
   if(cardExpiry.length < 2){
    return cardExpiry;
   }
   else{
    return cardExpiry.substr(0, 2) + "/" + (cardExpiry.substr(2) || "")
   }
}

inputToValue(inputText){
    //if the input has more than 5 characters don't set the state
    if(inputText.length < 6){
         const tokens = inputText.split("/");
         // don't set the state if there is more than one "/" character in the given input
         if(tokens.length < 3){
            const month = Number(tokens[1]);
            const year = Number(tokens[2]);
            //don't set the state if the first two letter is not a valid month
            if(month >= 1 && month <= 12){
               let cardExpiry = month + "";
               //I used lodash for padding the month and year with  zero
               if(month > 1 || tokens.length === 2){
                    // user entered 2 for the month so pad it automatically or entered "1/" convert it to 01 automatically
                    cardExpiry = _.padStart(month, 2, "0");
               }
               //disregard changes for invalid years
               if(year > 1 && year <= 99){
                   cardExpiry += year;
               }
               this.setState({cardExpiry});
            }
         }
    }
}

render (){
   let {cardExpiry} = this.state;
  return (
    <Image style={styles.image} source={require('../img/cover.jpg')}
  >


         <Content style={styles.content}>

            <Form>
              <Item >
                <Icon active name='card'/>
                <Input keyboardType='numeric' maxLength={16} placeholder='Card Number'
                onChangeText = {(text)=> this.onChange(text)}
      value = {this.state.myNumber}/>
      </Item>

      <Grid>
      <Row>
      <Col>

              <Item style={{ marginBottom:10}}>
                <Icon active name='calendar' />
                <Input keyboardType='numeric' placeholder='MM/YY' 
                value = {this.formatFunction(cardExpiry)}
       onChangeText={this.inputToValue.bind(this)}/>
              </Item>
              </Col>
              <Col>

                      <Item style={{ marginBottom:10}}>
                        <Icon active name='lock' />
                        <Input maxLength={3} secureTextEntry={true}  placeholder='CVV'/>
                      </Item>
                      </Col>
              </Row>
              </Grid>

How can this issue be solved?

Syuzanna
  • 509
  • 2
  • 8
  • 14

1 Answers1

0

If you look at this line:

//if the input has more than 5 characters don't set the state
if(inputText.length < 6){

you will have your answer ;) Your input's value comes from state, but you do not update it so it will not get updated. As a test try to paste correct string into it and that should work.

To deal with this you have two options: 1) Always update cardExpiry state but set additional isExpiryValid flag in your state and use it to display errors etc.

2) Add additional state value like cardExpiryInputValue which will be updated on change text and your input will get that value, but set cardExpiry only when value is valid and then you can use it as a model value. (although this solution seems overcomplicated for validation purposes)

MSadura
  • 1,032
  • 13
  • 18
  • Sorry but I am confused. Can you insert it on the my script? I need just get it typed not needed notification or other messages. E.g. for card number its ok when just type number then it will be typed. For card expiry I need the same approach as well – Syuzanna Sep 21 '17 at 11:13
  • Even after adding whole string nothing is typed. – Syuzanna Sep 21 '17 at 14:50