"@ionic/react": "^0.0.5",
It is common for component libraries to expect form elements to take 'value' and 'onChange' properties. For example using rc-form you cannot wrap the IonInput since it doesnt use onChange as expected.
When piping the onIonChange to rc-form. I tried piping the onIonChange to onChange, and that caused an unexpected blur on key press.
This seems to go against the (semi) standard for form elements
({onChange, ...props}) => <IonInput onIonChange={onChange} {...props} />)
Having the same issue when working with formik. onBlur, onIonBlur, and onIonChange are all dispatched correctly
Same issue. Fallback is to use onInput.
See #18452 for working examples of this issue. I'm on the fence about whether Ionic should support the usual React event properties.
Having the same issue when working with formik.
onBlur,onIonBlur, andonIonChangeare all dispatched correctly
@obedm503 How did you get formik to work for you? its a nightmare to make it work with ioninputs.
@tirthaguha this is what I did
function TextField ({ name }) {
const { setFieldTouched, setFieldValue, values } = useFormikContext<any>();
// use custom handlers to use ionic's events
const onBlur = React.useCallback(
(e: CustomEvent) => {
const ionInput = e.currentTarget;
if (!ionInput) {
return;
}
setFieldTouched(name, true);
},
[setFieldTouched, name],
);
const onChange = React.useCallback(
async (e: CustomEvent<InputChangeEventDetail>) => {
const ionInput = e.currentTarget;
if (!ionInput) {
return;
}
const input = await ionInput.getInputElement();
setFieldValue(name, input.value);
},
[setFieldValue, name],
);
return (
<Field name={name}>
{() => (
<IonInput
value={values[name]}
name={name}
onIonBlur={onBlur}
onIonChange={onChange}
/>
)}
</Field>
);
};
well i am not sure but how about this,
this way i dont have to write the wrapper, I just have to bind it with the correct formik object value and it works and displays the content correctly.
my formik object looks like this,
const formik = useFormik({
initialValues: {
firstName: '',
lastName: '',
email: '',
},
validate,
onSubmit: values => {
alert(JSON.stringify(values, null, 2));
},
});
I am a noob formik user however as i understand ionChange sends custom events and formik accepts synthetic event from react ecosystem. So not all things would be straight forward, but this could be a way out
<label htmlFor="ionemail">Email Address</label>
<IonInput
id="ionemail"
name="ionemail"
type="email"
//onIonChange={inputFunction}
onIonChange={(e:any)=>{
console.log(e);
formik.values.email = e.detail.value;
formik.handleChange(e);
}}
value={formik.values.email}
/>
@deepakjha14 the way you're working, it becomes a bit of hardcoding, where we are hardcoding formik values to it.
<IonInput
id="ionemail"
name="ionemail"
type="email"
//onIonChange={inputFunction}
onIonChange={(e:any)=>{
console.log(e);
formik.values.email = e.detail.value; // we are forcing it to pick formiks values
formik.handleChange(e); // and manually triggering formik's event.
}}
value={formik.values.email}
/>
It would be difficult to generalise it. I'll have rewrite the ionChange event if my input type changes from email to password.
formik.values.password = e.detail.value, and then set manually to value={formik.values.password}
So probably not a preferred method
where as @obedm503 has a way where he's retaining the properties of ionInput but just mapping normal textinput events to ionEvents.
<IonInput
value={values[name]}
name={name}
onIonBlur={onBlur}
onIonChange={onChange}
/>
Now, if the type changes from email to password, it doesn't matter. in fact, I would have proposed wrapping the ionInput in the following way
const CustomInput = ({
onChange,
onBlur,
onFocus,
onInput,
...extraProps
}: PropTypes) => {
const ionEventList = {
// Without the following, we need defaultProps for IonEvents
...(onChange && { onIonChange: onChange }),
...(onBlur && { onIonBlur: onBlur }),
...(onFocus && { onIonFocus: onFocus }),
...(onInput && { onIonInput: onInput }),
};
// MaxLength may not work, refer https://stackoverflow.com/questions/18510845/maxlength-ignored-for-input-type-number-in-chrome
return (
<IonInput
{...ionEventList}
{...extraProps}
/>
);
};
and use it as
<Field>
<CustomInput type='email' />
</Field>
<Field>
<CustomInput type='password' />
</Field>
@obedm503 First of all thanks for the solution above. Saved me a lot of frustration and helped me a lot. I just wondered if you are having an issue with the tab behaviour of your forms now?
I've implemented what you did and now the setFieldTouched seems to override the default tabbing between inputs. Wondering if it's expected or not?
@k3b0 just tested using tab navigation in my login page. everything seems to work as expected. Can you give more detail on "setFieldTouched seems to override the default tabbing between inputs"?
It's quite a pain to work with the custom made Ionic directly, where onIonInput is not always fired for all types, while you need onIonChange for others.
After numerous trial and error, here's an opinionated implementation tested with text, number and date input type.
Most helpful comment
Same issue. Fallback is to use
onInput.