Open boriswinner opened 4 years ago
Facing a similar problem
I am also facing the same problem here. I think that it could be nice to have an optional name
props
Thank you @boriswinner for the hack!
For the name issue I have used the inputProps option and I've just taken your code to solve the handleChange issue too:
<PhoneInput ... inputProps={{name:"phoneNumber"}} onChange={(phoneNumber, country, e)=>{handleChange(e)}} />
Seems to work for me without a wrapper class!
I ended up with:
<Formik>
{({ errors, touched, values, handleChange, handleBlur }) => (
<Form>
<label htmlFor="phone">Phone Number</label>
<PhoneInput
inputProps={{name:"phone"}}
onChange={(phoneNumber, country, e)=>{handleChange(e)}}
onBlur={handleBlur}
/>
</Form>
)}
</Formik>
{ handleChange, handleBlur, className, type, placeholder, name, ...restProps }
Thx men, simple and easy solution, it worked for me.
const validationSchema = Yup.object().shape(
{
phone: Yup.string()
.nullable()
.notRequired()
.when(['phone'], (value, schema) => {
if (Number(value) > Number(phoneCode)) {
return schema
.required()
.min(MIN_PHONE_NUMBER_LENGTH_WITH_PHONE_CODE, 'Should not be less than 8 digits')
.max(MAX_PHONE_NUMBER_LENGTH_WITH_PHONE_CODE, 'Should not exceed 13 digits');
}
return schema;
}),
},
[['phone', 'phone']]
);
const formik = useFormik({
initialValues: {
phone: '',
},
validationSchema,
validateOnChange: true,
});
const { errors, handleBlur, isValid, values } = formik;
const onValueChange = (phoneNumber) => {
formik.setFieldValue('phone', phoneNumber);
};
return (
<StyledPhoneInput
inputProps={{
name: 'phone', // should match with the schema and initialValues
}}
disableDropdown
onBlur={handleBlur} // 👈
onChange={onValueChange} // 👈
countryCodeEditable={false}
preferredCountries={['gb', 'us']}
country={userCountryCode?.toLowerCase() || 'gb'}
containerClass={`react-phone-number ${errors.phone ? 'error' : ''}`}
onlyCountries={countriesList.map((o) => o.countryCode.toLowerCase())}
/>
);
Styled with error for css material ui
const StyledPhoneInput = styled(PhoneInput)(({ theme }) => ({
'&.react-phone-number': {
fontFamily: 'inherit',
},
'&.react-phone-number input.form-control': {
fontFamily: 'inherit',
width: '100%',
paddingTop: theme.spacing(1),
paddingBottom: theme.spacing(1),
borderRadius: '8px',
borderColor: 'rgba(145, 158, 171, 0.32)',
paddingLeft: theme.spacing(2.5),
'&:focus': {
borderColor: theme.palette.primary.main,
boxShadow: `0 0 0 1px ${theme.palette.primary.main}`,
},
},
'&.react-phone-number.error': {
'& input': {
borderColor: theme.palette.error.main,
'&:focus': {
borderColor: theme.palette.error.main,
boxShadow: `0 0 0 1px ${theme.palette.error.main}`,
},
},
'& .special-label': {
color: theme.palette.error.main,
},
},
}));
There are two issues when trying to use the component with Formik:
Formik emits a name attribute, which has to be passed to the input element. When trying to use your component, Formik logs:
The right solution will be to add a 'name' prop to the component which will correspond to the name attribute in HTML input element. My solution is a bad hot-fix: I add a class to the element, find the input element by class and add the name attribute to it.
onChange emits the event as the third parameter. We need to write a wrapper that calls Formik's handleChange with the event as the parameter.
Here's my React component that 'solves' these issues: