Open kickbk opened 4 years ago
I got parsePhoneNumber working from libphonenumber-js https://gitlab.com/catamphetamine/libphonenumber-js which is a similar formatter to AsYouType
`import PhoneInput from 'react-native-phone-number-input'; import { parsePhoneNumber} from 'libphonenumber-js'
onChange = (text) => { const phoneInput = this.mRef const countryCode = phoneInput.current.getCountryCode() console.log('country code ===>', countryCode)
console.log("PHONE INPUT===>", phoneInput);
if(text.length > 5){
const phoneNumber = parsePhoneNumber(text)
this.setState({
setFormattedMobile:
phoneNumber.format("INTERNATIONAL").replace(/\s/g, '')
})
}
}
render() {
return(
<PhoneInput
ref={this.mRef}
onChangeText={text =>
this.setState({mNumber:text})}
onChangeFormattedText={this.onChange}
placeholder="Mobile Number"
defaultValue={this.state.mNumber}
/>
)
}`
@KerrySng99 thanks for sharing your code, but this is not "as you type" solution. You only parse when the length is 5. Also, it doesn't account for pasting a whole number from the phone. For instance, with textContentType="telephoneNumber"
option passed to the TextInput, it will allow for a quick one-click pasting of your phone number. That number may contain non-numeric characters as well, as in (555) 555-5555.
Still hoping @garganurag893 will drop a word on this. Not sure if this library is maintained though.
Hey all. i was able to do that using libphonenumber-js.
You need: 1 - import { AsYouType } from "libphonenumber-js"; 2 - const phoneFormatAsYouType = new AsYouType(phoneInput.current.getCountryCode()); 3- onChangeText={(text) => { setPhoneValue(phoneFormatAsYouType.input(text)); }}
@theodelebarre I haven't tested it thoroughly and on different devices, but it seems to work. thanks for sharing
It working nicely, however, once I set the default value to a formatted value, it gets all messed up when you start editing the number.
What I mean is this: Say I have a user phone number as 5555555555. when the user loads the update your phone number screen, I want to show the phone number already formatted, so I do this:
<PhoneInput
ref={phoneInput}
defaultValue={phoneFormatAsYouType.input(value)}
defaultCode="US"
onChangeText={(text) => {
setValue(phoneFormatAsYouType.input(text));
}}
onChangeFormattedText={(text) => {
setFormattedValue(text);
}}
textInputProps={{
maxLength: 14,
}}
/>
I'm passing a formatted value with defaultValue={phoneFormatAsYouType.input(value)}
. It shows up nicely, but once you start typing it gets screwed up.
What works is passing defaultValue={value} - It will not show the formatted value right away, but once the user starts editing, it will function correctly. But that's not so nice.
Any ideas how to fix this?
@theodelebarre His solution works excellently for me, however when I go over the max length it jumps to being un-formatted. Is there a way to dynamically set the maxLength of the text input (based on country) so that this can't happen?
@kickbk @ajlamarc Hey, sorry I haven't seen those comments before, I think you retrieved a value that was previously sent unformatted, I had that issue before, but then I cleared my test users, started again with that input set everywhere I needed it, the phone number saved is formatted, and when returned it perfectly displays itself.
For the other issue where it gets unformatted if too long, I think libphonenumber.js does that by itself, maybe it is just a visual feedback saying here you're phone number's wrong, we can't format it, but I'm sure you can play around with this library to detect the country of the phone number typed in and format it differently.
Have fun coding! :P
Merci Théo. That definitely helped. It now mostly works. So far, what doesn't work, while testing on the simulator, is deleting a digit in the middle of the phone number using the "Delete to end of line" with Ctrl-D
, or the "delete ->" button on a Mac keyboard. It removes a digit, adds an additional bracket in the beginning of the line instead of trimming the number.
However, I may be able to live with this since on a mobile device you cannot delete in such a way. If you can think of why it does it and if there's a solution, that would be much better of course.
@kickbk Yeah I found out as well.. I'm still trying to enhance it from time to time until I won't have any issue. I will share asap if I'm able to find something :P
I got it working with google-libphonenumber
by patching the library code:
onChangeText = (text) => {
const originalNumber = (text.match(/\d/g) ?? []).join("");
const { onChangeText, onChangeFormattedText } = this.props;
const formatter = new AsYouTypeFormatter(this.state.countryCode || 'US');
let formatted = '';
formatter.clear();
for (let c of originalNumber) {
formatted = formatter.inputDigit(c);
}
this.setState({ number: formatted });
if (onChangeText) {
onChangeText(originalNumber);
}
if (onChangeFormattedText) {
const { code } = this.state;
if (code) {
onChangeFormattedText(originalNumber.length > 0 ? `+${code}${originalNumber}` : originalNumber);
} else {
onChangeFormattedText(originalNumber);
}
}
};
I submitted a PR: #51
works like a charm ;)
Thanks @WangHansen, worked like a charm
here's a patch for patch-package
until PR is merged:
filename: react-native-phone-number-input+2.1.0.patch
diff --git a/node_modules/react-native-phone-number-input/lib/index.js b/node_modules/react-native-phone-number-input/lib/index.js
index b89c388..3bb557b 100644
--- a/node_modules/react-native-phone-number-input/lib/index.js
+++ b/node_modules/react-native-phone-number-input/lib/index.js
@@ -7,7 +7,7 @@ import CountryPicker, {
CountryModalProvider,
Flag,
} from "react-native-country-picker-modal";
-import { PhoneNumberUtil } from "google-libphonenumber";
+import { PhoneNumberUtil, AsYouTypeFormatter } from "google-libphonenumber";
import styles from "./styles";
const dropDown =
@@ -92,17 +92,24 @@ export default class PhoneInput extends PureComponent {
};
onChangeText = (text) => {
- this.setState({ number: text });
+ const originalNumber = (text.match(/\d/g) ?? []).join("");
const { onChangeText, onChangeFormattedText } = this.props;
+ const formatter = new AsYouTypeFormatter(this.state.countryCode || 'US');
+ let formatted = '';
+ formatter.clear();
+ for (let c of originalNumber) {
+ formatted = formatter.inputDigit(c);
+ }
+ this.setState({ number: formatted });
if (onChangeText) {
- onChangeText(text);
+ onChangeText(originalNumber);
}
if (onChangeFormattedText) {
const { code } = this.state;
if (code) {
- onChangeFormattedText(text.length > 0 ? `+${code}${text}` : text);
+ onChangeFormattedText(originalNumber.length > 0 ? `+${code}${originalNumber}` : originalNumber);
} else {
- onChangeFormattedText(text);
+ onChangeFormattedText(originalNumber);
}
}
};
Thanks for the work you put in this! Nice utility.
Formatting How would you incorporate
AsYouTypeFormatter
fromgoogle-libphonenumber
into it? I have:And it will indeed format the number as we type if we change to
But it gets screwed up once we type delete. It's probably due to saving the number in state. How would you recommend handling this?
Pasting This is less important, but could be nice to have. I'm passing
textContentType: 'telephoneNumber',
viatextInputProps
.textContentType
(on iOS) allows one click number paste. Any suggestions on handling pasting of numbers and then formatting if needed? Maybe some type of paste(it's probably the same as type) > strip > format ?