@@ -81,7 +81,11 @@ class PhoneInput extends React.Component {
8181 onBlur : PropTypes . func ,
8282 onClick : PropTypes . func ,
8383 onKeyDown : PropTypes . func ,
84- isValid : PropTypes . func ,
84+ isValid : PropTypes . oneOfType ( [
85+ PropTypes . bool ,
86+ PropTypes . func ,
87+ ] ) ,
88+ defaultErrorMessage : PropTypes . string ,
8589 }
8690
8791 static defaultProps = {
@@ -113,7 +117,6 @@ class PhoneInput extends React.Component {
113117 autoFormat : true ,
114118 enableAreaCodes : false ,
115119 enableTerritories : false ,
116- isValid : ( inputNumber , onlyCountries ) => true ,
117120 disableCountryCode : false ,
118121 disableDropdown : false ,
119122 enableLongNumbers : false ,
@@ -143,6 +146,9 @@ class PhoneInput extends React.Component {
143146 enableClickOutside : true ,
144147 showDropdown : false ,
145148
149+ isValid : true , // (value, selectedCountry, onlyCountries, hiddenAreaCodes) => true | false | 'Message'
150+ defaultErrorMessage : '' ,
151+
146152 onEnterKeyPress : null , // null or function
147153
148154 keys : {
@@ -279,16 +285,17 @@ class PhoneInput extends React.Component {
279285
280286 // Hooks for updated props
281287 updateCountry = ( country ) => {
288+ const { onlyCountries } = this . state
282289 let newSelectedCountry ;
283- if ( country . indexOf ( 0 ) >= '0' && country . indexOf ( 0 ) <= '9' ) {
284- newSelectedCountry = this . state . onlyCountries . find ( o => o . dialCode == + country ) ;
290+ if ( country . indexOf ( 0 ) >= '0' && country . indexOf ( 0 ) <= '9' ) { // digit
291+ newSelectedCountry = onlyCountries . find ( o => o . dialCode == + country ) ;
285292 } else {
286- newSelectedCountry = this . state . onlyCountries . find ( o => o . iso2 == country ) ;
293+ newSelectedCountry = onlyCountries . find ( o => o . iso2 == country ) ;
287294 }
288295 if ( newSelectedCountry && newSelectedCountry . dialCode ) {
289296 this . setState ( {
290297 selectedCountry : newSelectedCountry ,
291- formattedNumber : this . props . disableCountryCode ? '' : this . props . prefix + newSelectedCountry . dialCode
298+ formattedNumber : this . props . disableCountryCode ? '' : this . formatNumber ( newSelectedCountry . dialCode , newSelectedCountry ) ,
292299 } ) ;
293300 }
294301 }
@@ -301,9 +308,8 @@ class PhoneInput extends React.Component {
301308
302309 if ( value === '' ) return this . setState ( { selectedCountry, formattedNumber : '' } ) ;
303310
304- let newSelectedCountry ;
305311 let inputNumber = value . replace ( / \D / g, '' ) ;
306- let formattedNumber = value ;
312+ let newSelectedCountry , formattedNumber ;
307313
308314 // if new value start with selectedCountry.dialCode, format number, otherwise find newSelectedCountry
309315 if ( selectedCountry && startsWith ( value , selectedCountry . dialCode ) ) {
@@ -844,8 +850,22 @@ class PhoneInput extends React.Component {
844850 }
845851
846852 render ( ) {
847- const { onlyCountries, selectedCountry, showDropdown, formattedNumber } = this . state ;
848- const { disableDropdown, renderStringAsFlag } = this . props ;
853+ const { onlyCountries, selectedCountry, showDropdown, formattedNumber, hiddenAreaCodes } = this . state ;
854+ const { disableDropdown, renderStringAsFlag, isValid, defaultErrorMessage } = this . props ;
855+
856+ let isValidValue , errorMessage ;
857+ if ( typeof isValid === 'boolean' ) {
858+ isValidValue = isValid ;
859+ } else {
860+ const isValidProcessed = isValid ( formattedNumber . replace ( / \D / g, '' ) , selectedCountry , onlyCountries , hiddenAreaCodes )
861+ if ( typeof isValidProcessed === 'boolean' ) {
862+ isValidValue = isValidProcessed ;
863+ if ( isValidValue === false ) errorMessage = defaultErrorMessage
864+ } else { // typeof === 'string'
865+ isValidValue = false ;
866+ errorMessage = isValidProcessed ;
867+ }
868+ }
849869
850870 const containerClasses = classNames ( {
851871 [ this . props . containerClass ] : true ,
@@ -855,7 +875,7 @@ class PhoneInput extends React.Component {
855875 const inputClasses = classNames ( {
856876 [ this . props . inputClass ] : true ,
857877 'form-control' : true ,
858- 'invalid-number' : ! this . props . isValid ( formattedNumber . replace ( / \D / g , '' ) , onlyCountries ) ,
878+ 'invalid-number' : ! isValidValue ,
859879 'open' : showDropdown ,
860880 } ) ;
861881 const selectedFlagClasses = classNames ( {
@@ -865,6 +885,7 @@ class PhoneInput extends React.Component {
865885 const flagViewClasses = classNames ( {
866886 [ this . props . buttonClass ] : true ,
867887 'flag-dropdown' : true ,
888+ 'invalid-number' : ! isValidValue ,
868889 'open' : showDropdown ,
869890 } ) ;
870891 const inputFlagClasses = `flag ${ selectedCountry && selectedCountry . iso2 } ` ;
@@ -874,6 +895,7 @@ class PhoneInput extends React.Component {
874895 className = { containerClasses }
875896 style = { this . props . style || this . props . containerStyle }
876897 onKeyDown = { this . handleKeydown } >
898+ { errorMessage && < div className = 'invalid-number-message' > { errorMessage } </ div > }
877899 < input
878900 className = { inputClasses }
879901 style = { this . props . inputStyle }
0 commit comments