-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Dependent Dropdowns and Dynamic Fields #751
Comments
I am looking into the exact same thing right now. Still haven't found any answer. |
Okay @parlays I have solved the issue. It's not a pretty solution but it's a workaround. To update the dynamic field's value, I am also calling I'm sorry, I know my explanation is poor and hard to follow. My code and form are quite complex so it's difficult to give you a simple explanation. But basically, what you want to do is to handle it through a callback I guess. |
@SimpleCookie Can you give an example to show this? |
@pavanmehta91 I'm sorry I don't have the possibility of creating an example for you right now. When you change A, you want to update the options of B accordingly. |
Found this issue while trying to solve a similar problem. The pattern I've ended up using is to pass in the field and form as props to the child component, and use the componentDidUpdate lifecycle method to detect changes in the parent value. E.g.: class ChildInput extends React.Component {
componentDidUpdate(prevProps) {
const { field, form: { values, setFieldValue } } = this.props;
if (values.parent !== prevProps.form.values.parent) {
setFieldValue(field.name, `some function of ${values.parent}`);
}
}
render() {
const { field } = this.props;
return <input {...field}/>;
}
}
...
<Field name="child">
{({ field, form }) => (
<ChildInput field={field} form={form}/>
)}
</Field> |
@jaredpalmer Do you have any recommendations for dynamic and dependent fields? |
Hola! So here's the deal, between open source and my day job and life and what not, I have a lot to manage, so I use a GitHub bot to automate a few things here and there. This particular GitHub bot is going to mark this as stale because it has not had recent activity for a while. It will be closed if no further activity occurs in a few days. Do not take this personally--seriously--this is a completely automated action. If this is a mistake, just make a comment, DM me, send a carrier pidgeon, or a smoke signal. |
ProBot automatically closed this due to inactivity. Holler if this is a mistake, and we'll re-open it. |
Could you please provide an example on codesandbox for the above case? |
Any word on this? What's the most elegant way to solve? |
I came across this looking for a way to set default fields in Formik's const ConditionalFields = (props) => {
const { handleChange, setFieldValue, values } = props;
useEffect(() => {
// If my values are undefined, set them in Formik
if (!values.myValue) {
setFieldValue('myValue', 'default');
}
});
// myValue is not defined so stop rendering, useEffect above will cause a re-render if necessary
if (!values.myValue) return null;
return (
<div>
<input type="text" value={values.myValue} onChange={handleChange} />
</div>
);
}; The premise of this solution is that you halt rendering when you encounter uninitialized fields, set field values in Formik's store, which then triggers a re-render. Not elegant, but could get you out of a bind. |
@goldenshun Thanks for tip, I updated your solution a bit and here is my approach...
Component code: import { connect, Field, getIn } from "formik";
import { any, object, string } from "prop-types";
import React, { useEffect } from "react";
const OptionalField = ({
formik: { values, setFieldValue },
name,
defaultValue,
...props
}) => {
useEffect(() => {
// set value if not defined
if (getIn(values, name) === undefined) {
setFieldValue(name, defaultValue);
}
});
const value = getIn(values, name);
// stop rendering, effect above will rerender
if (value === undefined) return null;
return <Field name={name} {...props} />;
};
OptionalField.propTypes = {
formik: object.isRequired,
name: string.isRequired,
defaultValue: any,
};
OptionalField.defaultProps = {
defaultValue: null,
};
export default connect(OptionalField); Example usage: <OptionalField name="foo" defaultValue="bar" />
<OptionalField name="a.b" defaultValue={1} />
<OptionalField name="list" defaultValue={[1, 2, 3]} />
<OptionalField name="set[0]" defaultValue={true} />
<OptionalField name="set[1].value" defaultValue={{ a: 1, b: 2 }} /> Enjoy! |
Super cool @malyzeli! I was unaware of the |
@goldenshun Yep, they are not documented well.. I found it by accident while browsing through the source code! :-D @jaredpalmer Can you add page to API Reference listing available helpers? Also what about using GitHub wiki for sharing various community snippets like this OptionalField, or for example Checkbox/Radio components, which are discussed in other issue threads? Then publish link on the website so people could find custom components, examples, tutorials and tips easier. |
I've made a solution inspired on @SimpleCookie: I created a component called FieldSpy: import { Field, FieldProps } from 'formik';
import * as React from 'react';
import { useRef } from 'react';
interface FieldSpyProps {
name: string;
onChange: (value: any) => void;
}
const empty = Symbol('empty');
export const FieldSpy = ({ name, onChange }: FieldSpyProps) => {
const value = useRef<any>(empty);
return (
<Field name={name}>
{({ field }: FieldProps) => {
if (value.current !== empty && value.current !== field.value) {
onChange(field.value);
}
value.current = field.value;
return null;
}}
</Field>
);
}; So now, whenever I want to "listen" to changes on a particular field in my form container, I can just: <Formik initialValues={defaultValue} onSubmit={onSubmit}>
<Form>
<TextField name="username" />
<FieldSpy name="username" onChange={onUsernameChange} />
</Form>
</Formik> What's your opinion on this? Does this look right? I'm quite new to Formik and I haven't fully tried this, but it seems like it should cover most of the use cases. |
I'd like to share how I solved a similar situation. I had two selection box fields A and B using Formik.
|
Found a solution here The code sandbox in the solution |
Is name the field to which it is connected? trying to piece this together. Thanks! |
Hello! I have read through many of the issues and online examples but I have not found an example of using dynamic fields.
I would like to add or remove form fields based on the value of one of the dropdowns. If the dropdown has "option A" selected, I would like to add two more dropdowns and populate them via an AJAX call. If "option B" is selected, I would like to add an input box and remove the dropdowns displayed for "option A".
I tried using a custom react component but it is not clear how to add or remove form elements based on the value of another form element. Thanks!
The text was updated successfully, but these errors were encountered: