Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix to make autofill work as expected #632

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
},
"dependencies": {
"classnames": "^2.2.6",
"libphonenumber-js": "^1.10.30",
"lodash.debounce": "^4.0.8",
"lodash.memoize": "^4.1.2",
"lodash.reduce": "^4.6.0",
Expand Down
42 changes: 30 additions & 12 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import reduce from 'lodash.reduce';
import startsWith from 'lodash.startswith';
import classNames from 'classnames';
import './utils/prototypes'
import { parsePhoneNumberFromString } from 'libphonenumber-js';

import CountryData from './CountryData.js';

Expand Down Expand Up @@ -272,19 +273,19 @@ class PhoneInput extends React.Component {
// then search and insert main country which has this area code
// https://github.com/bl00mber/react-phone-input-2/issues/201
if (this.props.enableAreaCodes === false) {
let mainCode;
let countryCode;
hiddenAreaCodes.some(country => {
if (startsWith(inputNumber, country.dialCode)) {
onlyCountries.some(o => {
if (country.iso2 === o.iso2 && o.mainCode) {
mainCode = o;
if (country.iso2 === o.iso2 && o.countryCode) {
countryCode = o;
return true;
}
})
return true;
}
})
if (mainCode) return mainCode;
if (countryCode) return countryCode;
}

const secondBestGuess = onlyCountries.find(o => o.iso2 == country);
Expand Down Expand Up @@ -338,8 +339,7 @@ class PhoneInput extends React.Component {
if (selectedCountry && startsWith(value, prefix + selectedCountry.dialCode)) {
formattedNumber = this.formatNumber(inputNumber, selectedCountry);
this.setState({ formattedNumber });
}
else {
} else {
if (this.props.disableCountryGuess) {newSelectedCountry = selectedCountry;}
else {
newSelectedCountry = this.guessSelectedCountry(inputNumber.substring(0, 6), country, onlyCountries, hiddenAreaCodes) || selectedCountry;
Expand Down Expand Up @@ -410,6 +410,23 @@ class PhoneInput extends React.Component {
pattern.shift();
pattern = pattern.join(' ');
} else {

// Add country code to the beginning of the number when not present
const rawNumber = text.toString();
// Try to parse the number as an international number first
let phoneNumber = parsePhoneNumberFromString(rawNumber)
if (!phoneNumber || !phoneNumber.isValid()) {
// If it's not a valid international number, try parsing it as a national number
phoneNumber = parsePhoneNumberFromString(rawNumber, country.iso2.toUpperCase())
}
if (phoneNumber && phoneNumber.isValid()) {
let formattedNumber = phoneNumber.formatNational();
let digitsOnly = formattedNumber.replace(/\D/g, ''); // remove all non-digit characters
text = phoneNumber.countryCallingCode + digitsOnly;
} else {
console.log('Invalid number');
}

if (enableAreaCodeStretch && country.isAreaCode) {
pattern = format.split(' ');
pattern[1] = pattern[1].replace(/\.+/, ''.padEnd(country.areaCodeLength, '.'))
Expand Down Expand Up @@ -518,13 +535,13 @@ class PhoneInput extends React.Component {
let newSelectedCountry = this.state.selectedCountry;
let freezeSelection = this.state.freezeSelection;

// If countryCodeEditable is false we should avoid the user to be able to delete the country code
if (!this.props.countryCodeEditable) {
const mainCode = newSelectedCountry.hasAreaCodes ?
this.state.onlyCountries.find(o => o.iso2 === newSelectedCountry.iso2 && o.mainCode).dialCode :
const countryCode = newSelectedCountry.hasAreaCodes ?
this.state.onlyCountries.find(o => o.iso2 === newSelectedCountry.iso2 && o.countryCode).dialCode :
newSelectedCountry.dialCode;

const updatedInput = prefix+mainCode;
if (value.slice(0, updatedInput.length) !== updatedInput) return;
if (value === prefix+countryCode.slice(0, countryCode.length-1)) return;
}

if (value === prefix) {
Expand Down Expand Up @@ -809,7 +826,7 @@ class PhoneInput extends React.Component {
getCountryDropdownList = () => {
const { preferredCountries, highlightCountryIndex, showDropdown, searchValue } = this.state;
const { disableDropdown, prefix } = this.props
const { enableSearch, searchNotFound, disableSearchIcon, searchClass, searchStyle, searchPlaceholder, autocompleteSearch } = this.props;
const { enableSearch, searchNotFound, disableSearchIcon, searchClass, searchStyle, searchPlaceholder } = this.props;

const searchedCountries = this.getSearchFilteredCountries()

Expand Down Expand Up @@ -912,7 +929,7 @@ class PhoneInput extends React.Component {

render() {
const { onlyCountries, selectedCountry, showDropdown, formattedNumber, hiddenAreaCodes } = this.state;
const { disableDropdown, renderStringAsFlag, isValid, defaultErrorMessage, specialLabel } = this.props;
const { disableDropdown, renderStringAsFlag, isValid, defaultErrorMessage, specialLabel, autocompleteSearch } = this.props;

let isValidValue, errorMessage;
if (typeof isValid === 'boolean') {
Expand Down Expand Up @@ -971,6 +988,7 @@ class PhoneInput extends React.Component {
onKeyDown={this.handleInputKeyDown}
placeholder={this.props.placeholder}
disabled={this.props.disabled}
autoComplete={autocompleteSearch ? 'on' : 'off'}
type='tel'
{...this.props.inputProps}
ref={el => {
Expand Down
26 changes: 22 additions & 4 deletions test/dev_js/demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ class Demo extends React.Component {
`}} />
<p style={{fontWeight: '500'}}>Created by <a style={{color: '#000'}}
href="https://github.com/bl00mber/react-phone-input-2">Nick Reiley</a></p>
<div style={{display: 'inline-block', verticalAlign: 'top'}}>
<div style={{display: "flex", flexWrap: "wrap", gap: "20px"}}>
<div>
<p>Exclude countries (usa, canada)</p>
<PhoneInput
country='no'
Expand All @@ -62,9 +63,24 @@ class Demo extends React.Component {
country='it'
preferredCountries={['it', 'se']}
/>
<p>Autocomplete</p>
<div>
<input autoComplete="street-address" type="text" placeholder="Street" />
<PhoneInput
onlyCountries={['us']}
country='us'
placeholder='(702) 123-4567'
disableDropdown
autocompleteSearch={true}
inputProps={{
id: "phone", // Needed for autocomplete to work properly
}}
countryCodeEditable={false}
/>
</div>
</div>

<div style={{display: 'inline-block', marginLeft: '40px'}}>
<div>
<p>Auto country detect by value</p>
<PhoneInput
value='+3802343252'
Expand Down Expand Up @@ -105,7 +121,7 @@ class Demo extends React.Component {
/>
</div>

<div style={{display: 'inline-block', marginLeft: '40px', verticalAlign: 'top'}}>
<div>
<p>Custom region selected: {`{'europe'}`}</p>
<PhoneInput
country='it'
Expand Down Expand Up @@ -147,7 +163,8 @@ class Demo extends React.Component {
country='au'
/>
</div>
<div style={{display: 'inline-block', marginLeft: '40px', verticalAlign: 'top'}}>

<div>
<p>Search using iso2 or country name</p>
<PhoneInput
country='nl'
Expand Down Expand Up @@ -211,6 +228,7 @@ class Demo extends React.Component {
else {this.setState({country: 'br'})}
}}>Change default country</button>
</div>
</div>

<div>
<br/><br/>
Expand Down