thegamenicorus / react-native-phone-input

Phone input box for React Native
https://www.npmjs.com/package/react-native-phone-input
MIT License
394 stars 447 forks source link

issue with common dial codes #48

Open ujwal-setlur opened 6 years ago

ujwal-setlur commented 6 years ago

When country is switched to another country that has the same international prefix, say USA and Canada, then when you start typing the phone number, the flag switches back to the first one. This is due to this code in index.js:

  updateFlagAndFormatNumber(number, actionAfterSetState = null) {
    const { allowZeroAfterCountryCode, initialCountry } = this.props;
    let iso2 = initialCountry;
    let phoneNumber = number;

    if (number) {
      if (phoneNumber[0] !== "+") phoneNumber = `+${phoneNumber}`;
      phoneNumber = allowZeroAfterCountryCode
        ? phoneNumber
        : this.possiblyEliminateZeroAfterCountryCode(phoneNumber);
      iso2 = PhoneNumber.getCountryCodeOfNumber(phoneNumber);
    }
    this.setState({ iso2, formattedNumber: phoneNumber }, actionAfterSetState);
  }

This in turn calls PhoneNumber.getCountryCodeOfNumber from phoneNumber.js:

  getCountryCodeOfNumber(number) {
    const dialCode = this.getDialCode(number);
    const numeric = this.getNumeric(dialCode);
    const countryCode = Country.getCountryCodes()[numeric];

    // countryCode[0] can be null -> get first element that is not null
    if (countryCode) {
      return _.first(countryCode.filter(iso2 => iso2));
    }

    return '';
  }

You will notice that the first element (in this case US) gets returned. We should allow for overlapping prefixes.

ujwal-setlur commented 6 years ago

Here is a patch that addresses it:

--- a/node_modules/react-native-phone-input/lib/index.js
+++ b/node_modules/react-native-phone-input/lib/index.js
@@ -149,6 +149,14 @@ export default class PhoneInput extends Component {
         : this.possiblyEliminateZeroAfterCountryCode(phoneNumber);
       iso2 = PhoneNumber.getCountryCodeOfNumber(phoneNumber);
     }
+
+    // some countries share dial prefix, so don't change country if we run into that
+    let oldDialCode = PhoneNumber.getCountryDataByCode(initialCountry).dialCode;
+    let newDialCode = PhoneNumber.getNumeric(PhoneNumber.getDialCode(phoneNumber));
+    if(oldDialCode === newDialCode) {
+        iso2 = initialCountry;
+    }
+
     this.setState({ iso2, formattedNumber: phoneNumber }, actionAfterSetState);
   }