Conditional Form Fields Example
This example includes an example on how to build a form where the values of certain input fields control the visibility of other fields within that form. In this case, filling out fullName
with make the nickname
field visible. Removing fullName
will make nickname
disappear, as well as remove nickname
from formState
Learn more about RADFish examples at the official documentation
Steps
- Before building out your form, it's a good idea to define which inputs you want to render, and create constant variables for them, so that you can reference these variables, rather than typing out plain text strings. This reduces the possibility of typos and human error when building out reference logic:
const fullName = "fullName";
const nickname = "nickname";
In this example, we will build a form with two inputs. The value from fullName
inputs will control the visiblity of nickname
.
- Next, let's define our
Form
component, and intialize it with an emptyformState
object:
const ConditionalForm = () => {
const [formData, setFormData] = useState({});
return (
// form JSX will go here
);
};
- In the
Form.jsx
component, you can now build out the jsx inputs form yourForm
within thereturn
statement of the component. See the below to see an example of how to build these inputs. Notice how we are referencing the variables defined in step 1, rather than typing out the plain strings to avoid typos, and use the variable to access theformData
state. It's a good idea to wrap these inputs within aFormGroup
component provided from the trussworks library.
<TextInput
id={fullName}
name={fullName}
type="text"
placeholder="Full Name"
value={formData[fullName] || ""}
/>
- Now, for each input, we can create an
onChange
handler, that captures the input's value as it is being typed. We then update state with a copy of the existingformState
, and update only the field value that we want to update (in this casenumberOfFish
). The value of this input will then re-render with the updated value fromformState
<TextInput
id={fullName}
name={fullName}
type="text"
placeholder="Full Name"
value={formData[fullName] || ""}
onChange={(event) => {
const { value } = event.target;
setFormData({
...formData,
[fullName]: value,
});
}}
/>
- Additionally, we want to conditionally render the
nickname
component, depending on whether or not thefullName
value is set informState
. This input field will only render ifformData[fullName]
evaluates totrue
{
formData[fullName] && (
<>
<Label htmlFor={nickname}>Nickname</Label>
<TextInput
id={nickname}
name={nickname}
type="text"
placeholder="Nickname"
onChange={(event) => {
const { value } = event.target;
setFormData({
...formData,
[nickname]: value,
});
}}
/>
</>
);
}
- Lastly, we want to make sure that we remove the value of
nickname
whenever thefullName
component is empty. To do that we can add another form control within theonChange
handler of thefullName
input
<TextInput
id={fullName}
name={fullName}
type="text"
placeholder="Full Name"
value={formData[fullName] || ""}
onChange={(event) => {
const { value } = event.target;
setFormData({
...formData,
[fullName]: value,
[nickname]: value === "" ? "" : formData[nickname],
});
}}
/>