React Formik autocomplete='on' on form in nested fields - javascript

I have encountered an issue which does not seem solvable at the moment. I implemented Formik to solve Reacts autocomplete on controlled inputs but it does not work as expected.
The issue is on submit autocomplete values are not saved in the browser.
For example:
name="object.email" does not work (for providing email autocomplete), same as object.name and so on for standard field names
Has anyone encountered this and is there a fix or do I have to live with it?
I have tried adding autocomplete keys to inputs but that does not work either.
My form has autocomplete='on' but that just does not seem to do anything at the moment and submit event does not capture the form values at all
This is how my input component looks like:
const Input: React.FC<IInputProps> = ({
label,
value,
onChange,
id,
name,
placeholder,
className,
onBlur,
type = 'text',
maxLength,
hasAutocomplete
}) => {
return (
<label htmlFor={id} className={clsx('input', className)}>
<div className='input__label'>{label}</div>
<input
id={id}
name={name}
className='input__input'
value={value}
onChange={onChange}
onBlur={onBlur}
placeholder={placeholder}
type={type}
maxLength={maxLength}
max={maxLength}
autoComplete={hasAutocomplete ? name : 'off'}
/>
</label>
)
}

Related

what is the correct way to collect input data WITHOUT LAG on typing in REACT?

so it's been a month i'm working with react.
there is a problem i didn't know what to do with it.
in onChange event handlers EVEN in the smallest page and project there is a delay in typing and specially Delay in Removing text.
why is this happenig ?
i mean react is popular because of Fast UI right? so what we should do to handle Forms without this Perfomance Problem ?
why there is a lag in this form ?
const LoginForm = () => {
// State & Validate Schema
const formik = useFormik({
initialValues: {
email: "",
password: "",
rememberMe: false,
},
validationSchema: Yup.object({
blah blah some validation
}),
onSubmit: (value) => {
console.log(value, "Submitted");
},
});
return (
<>
<Container maxWidth="sm" disableGutters>
<Box>
<h3>Log to the Account</h3>
<form onSubmit={formik.handleSubmit}>
<TextField
error={formik.touched.email && formik.errors.email !== undefined}
name='email'
label='Email'
value={formik.values.name}
onBlur={formik.handleBlur} // If Input is Touched Show Error
onChange={formik.handleChange}
helperText={formik.touched.email && formik.errors.email}
autoComplete="on"
/>
<TextField
error={formik.touched.password && formik.errors.password!== undefined}
name='password'
label='Password'
value={formik.values.password}
onBlur={formik.handleBlur}
onChange={formik.handleChange}
helperText={formik.touched.password&& formik.errors.password}
autoComplete="on"
/>
<Button type="submit" variant="contained" size="medium">
Login
</Button>
<span>Remember Me</span>
<Checkbox
value={formik.values.rememberMe}
name="rememberMe"
onChange={formik.handleChange}
/>
</form>
</Box>
</Container>
</>
);
};
I think this is not a problem of react rather than Formik. In your example you have a variable named formik to pass the current value to your TextField component you define the prop value={formik.values.someName} and to update the field value you specify an onChange={formik.handleChange} handler. To be able to pass the new value after a change to your input field, the formik variable needs to be updated and this causes your whole form component to be rerendered on every key stroke.
To be honest, I switched for similar reasons from Formik to React Hook Form some while ago and hadn't used Formik for a long time. But I think your performance problems are caused by the design of Formik.

How to prevent react-final-form from rendering an specific input

I have a react-final-form form, which has 2 inputs. Let's call them from and to.
What I want to do is that whenever input from changes, I set a value for input to based on input from's value.
I do that in validate function because i don't know where else i can do that. And it causes re-rendering the component in a loop.
Since I change the value of to in validate, it causes validate function to run again and again and again. How can I avoid that?
The actual code is much more complex than this but this is where i run into problems.
Thanks
const validate = (v) => {
const calculateFrom = calculate(v.from);
window.setTo(calculateFrom);
};
<Form
onSubmit={onSubmit}
validate={validate}
mutators={{
setTo: (a, s, u) => {
u.changeValue(s, 'to', () => a[0]);
},
setMax: (a, s, u) => {
u.changeValue(s, 'from', () => getMaxBalance(selectedAsset1));
},
}}
subscription={{ submitting: true, pristine: true }}
render={({
form,
pristine,
invalid,
handleSubmit,
}) => {
if (!window.setTo) {
window.setTo = form.mutators.setTo;
}
return (
<form onSubmit={handleSubmit}>
<Field name="from">
{({ input, meta }) => (
<Input
type="number"
placeholder="123"
size="input-medium"
input={input}
meta={meta}
/>
)}
</Field>
<Field name="to">
{({ input, meta }) => (
<Input
type="number"
placeholder="123"
size="input-medium"
input={input}
meta={meta}
/>
)}
</Field>
/>
First of all you could use an existing decorator
https://codesandbox.io/s/oq52p6v96y
I'm not really sure why it is re-rendering infinitely. Might have something to do with reusing the function setTo that you put on the window.
If you don't want to add that mutator library I'd try the following solutions.
use parse prop on the the Field where you can get the value and compare it with the other value that you need and return exactly what is should be check attached example parse prop
Final form allows to nest Fields inside custom components so you could just handle everything there by using useForm hook

ant design - Update checked value of a checkbox inside a Form.Item using Form.setFieldsValue

I have a React Form component that receives a state object. The Form contains a couple of Form.Item components, one antd Input & one antd Checkbox. I have the following code in my Form component:
const RecordsForm = ({ selectedRecord, recordComponentForm }) => {
useEffect(() => {
debugger;
recordComponentForm.setFieldsValue({
Title: selectedRecord ? selectedRecord.Title : null,
IsCurrentRecord: selectedRecord ? selectedRecord.IsCurrentRecord : true,
});
}, [recordComponentForm, selectedRecord]);
return (
<Form
name="seasonForm"
autoComplete="off"
layout={"inline"}
form={recordComponentForm}
>
<Form.Item
label="Title"
name="Title"
rules={[{ required: true, message: "Add a Title" }]}
>
<Input
name="Title"
placeholder="Season Title"
/>
</Form.Item>
<Form.Item
label="Is Active Record"
name="IsCurrentRecord"
valuePropName="checked"
>
<Checkbox name="IsCurrentRecord" />
</Form.Item>
</Form>
);
};
export default RecordsForm;
where the supplied prop recordComponentForm is instantiated in the parent component: const [recordComponentForm] = Form.useForm();
When I run the application and force this component to reload with a new selectedRecord, I want the Form.Item Input value to change to the Title from the object and the Checkbox to reflect the IsCurrentRecord boolean value of the object. The object passed in looks like this:
The Title Input value changes to show the Title of the object, however the checkbox remains unchanged:
I would like the checkbox to change it's checked value depending on what comes in on the selectedRecord.IsCurrentRecord object in the same way the Title does. Any advice would be greatly appreciated.
Maybe.. just simply remove name from Checkbox.
<Form.Item
label="Is Active Record"
name="IsCurrentRecord"
valuePropName="checked"
>
<Checkbox />
</Form.Item>
Checkbox usually return a value of choices (not boolean), so you perhaps should use Switch component instead.
But by using valuePropName="checked", we could get boolean from Checkbox.
This was simply a case of the Form.Items sharing the same name and the child component it contains. Once I renamed the Form.Item for the Checkbox to something like IsCurrentRecord_FI and referred to it as such, it started working.

React setState side effects with Form Data

Sorry for the general title but I don't know what else to call it at this point. I have a form that uses widgets. Im using the react-jsonschema-form package. Id use the github for the project but I don't think this is bug so I want to check here first. I think it's just how to use this React thing question. Possibly Redux as well.
So...
I have these widgets for some of the form elements in my component.
dropdownWidget = (props, type, id) => {
return (
<div>
<input id={id} type="text" className="form-control" list={type} placeholder="Select one..." onChange={(event) => { props.onChange(event.target.value); this.hideResultTables(event.target.id) }} />
<datalist id={type}>
{this.props.actionsObj.filterJsonData(type, this.props.convertDropDownDataObj).map((value, index) => { return <option key={index} value={value}>{value}</option> })}
</datalist>
</div>
)
}
multiFileWidget = (props) => {
return (
<div>
<OverlayTrigger trigger={['hover', 'focus']} placement="right" overlay={fileWidgetPopup}>
<input type="file" id="multiFileName" required={props.required} onChange={(event) => { props.onChange(event.target.value); this.getFileNames(); this.hideResultTables(event.target.id) }} multiple />
</OverlayTrigger>
<textarea id="multiFileNameList" className="form-control" rows="4" style={{ marginTop: "2%" }} readOnly />
</div>
)
}
dropdownTooltipWidget = (props, type, id, tooltip) => {
return (
<div>
<OverlayTrigger trigger={['hover', 'focus']} placement="right" overlay={tooltip} hidden>
<input id={id} type="text" className="form-control" list={type} placeholder="Select one..." onChange={(event) => { props.onChange(event.target.value); this.hideResultTables(event.target.id) }} />
</OverlayTrigger>
<datalist id={type}>
{this.props.actionsObj.filterJsonData(type, this.props.convertDropDownDataObj).map((value, index) => { return <option key={index} value={value}>{value}</option> })}
</datalist>
</div>
)
}
They are stuffed in a object like so:
multiUISchema = {
file: {
'ui:widget': this.multiFileWidget,
classNames: "uiSchema",
},
convertTo: {
'ui:widget': (props) => this.dropdownWidget(props, "ConvertToTypes", "multiConvertTo"),
classNames: "uiSchema"
},
notification: {
'ui:widget': (props) => this.dropdownTooltipWidget(props, "NotificationType", "notification", websNotificationPopup),
classNames: "uiSchema"
}
}
Where things go bad!! This function is injected in the widgets onChange handler.
hideResultTables(targetId) {
debugger;
//disable Retrieve button
if (targetId === 'multiFileName' || targetId === 'multiConvertTo') {
console.log("BEFORE::", this.state.formData)
selectedFiles = [];
document.getElementById("convertResultTable").setAttribute("hidden", true);
document.getElementById("retrieveResultTable").setAttribute("hidden", true);
this.setState({ disabled: true });
}
//leave Retrieve Button enabled
else if (targetId !== 'appIDs') {
console.log("BEFORE::", this.state.formData)
selectedFiles = [];
document.getElementById("convertResultTable").setAttribute("hidden", true);
document.getElementById("retrieveResultTable").setAttribute("hidden", true);
}
}
Basically if I hit the first if statement which has the setState for disabled to True, my onChange doesn't seem to retain the selected dropdown data to the Form Data object. It's like setState for Disabled true, which is for a button unrelated to the field does something to in the reconciliation tree possibly and/or my form data never retains the selected field in the formdata object at all?? idk. The field just stays undefined in all console logs if it's a field that hits that first if statement with the setState in it. But that setState has nothing to do with the fields being selected. It's disabling a button further down the page is all. Im sure im missing some React lifecycle, reconciliation async something or other. Im thinking of just reduxing this all but this simple bool value seems like it should stay as local state to the component. Any thoughts on things I should be checking before i redux this simple bool for my form?
To Further clarify my question, why does setState in the injected function in onChange seem to disrupt the onChange value update for the field on the form in my Widget when I select a field. That's really what this is all about. We cannot figure out why this is happening.
footnote** The dropdown data in the form is redux store data. So im selecting store data in my onchange in the widgets. Not sure if that's relevant.

redux-form and react-select onChange doesn't update redux value

So I'm having issues using redux-form with react-select, this is what I have so far:
<Field
name="objective"
type="text"
component={prop => <FormSelect {...prop} options={options} />}
label="Objective"
/>
And then:
const FormSelect = ({ options, label, input: { value, onChange, onBlur } }) =>
<ControlGroup title={label} styleId={label}>
<Select
options={options}
simpleValue
onChange={onChange}
value={value}
onBlur={() => onBlur(value)}
id={label}
/>
</ControlGroup>;
But then the select value does not change..
I get a redux-form/CHANGE with a action.payload of awareness (which is the value I want to select), but right after there is another redux-form action redux-form/BLUR with an action.payload of "".
I've read a bunch of github issues about this, tried a lot of them but nothing seems to be working..
example:
https://github.com/JedWatson/react-select/issues/1129
https://github.com/erikras/redux-form/issues/82
I also tried: onBlur={() => onBlur('awareness')} and it did not change the value on the select, even both payloads were had the same value..
I forgot to add redux-form reducer to my reducers.. Thanks anyway

Categories