I have an issue, I need to show and hide Input/Text field based on Checkbox's state. Means when checkbox state is checked I need to show TextField and when I uncheck it should hide. I have attached a code of this component below. As you can see I have TextFields created already, but I need to hide/show them. When I check/uncheck checkbox2 show/hide TextField2. Thank you for any tip or advice!
import React, { useState } from "react";
import { Button } from "../../components/Button";
import { Checkbox } from "../../components/Checkbox";
import { FormBuilder } from "../../components/FormBuilder";
import { Grid, GridCell, GridRow } from "../../components/Grid";
import { LinearProgress } from "../../components/LinearProgress";
import { Select } from "../../components/Select";
import { TextField } from "../../components/TextField";
import { Name } from "../../models/Name";
import { Option } from "../../models/Option";
import { DynamicForm } from "../../models/DynamicForm";
import "./index.css";
import { Organization } from "../../models/Organization";
//let checkboxChecked = showDropDown;
const FormDetails = ({ dynamicForm }: { dynamicForm: DynamicForm }) => {
return (
<div>
<h4 style={{ margin: 16 }}>asd</h4>
<Grid>
<GridRow>
<GridCell span={4}>
<TextField
maxLength={512}
textarea
label="TextField1"
onChange={(value) => (dynamicForm.description.kk = value)}
defaultValue={dynamicForm.description?.ru}
/>
</GridCell>
<GridCell span={4}>
<TextField
maxLength={512}
textarea
label="TextField2"
onChange={(value) => (dynamicForm.description.en = value)}
defaultValue={dynamicForm.description?.en}
/>
</GridCell>
</GridRow>
<GridCell span={4}>
<Checkbox
label="Checkbox1"
onChange={(value) => (dynamicForm.needApprove = value)}
defaultChecked={dynamicForm.needApprove}
/>
</GridCell>
<GridCell span={5}>
<Checkbox
label="Checkbox2" //
onChange={(value) => (dynamicForm.needExtraApprove = value)}
defaultChecked={dynamicForm.needExtraApprove}
/>
</GridCell>
</GridRow>
</Grid>
</div>
);
};
export default () => {
const [step, setStep] = useState(1);
const [dynamicForm, setDynamicForm] = useState<DynamicForm>(
new DynamicForm()
);
let progress = parseFloat(((step - 1) * (1 / NUMBER_OF_STEPS)).toFixed(2));
const onBackButtonPress = () => {
if (step > 0) {
setStep((prev) => prev - 1);
}
};
const onNextButtonPress = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (step < screen.third) {
setStep((prev) => prev + 1);
} else {
console.log("submit!");
//submit
}
};
let content = <SubDivision dynamicForm={dynamicForm} />;
if (step === screen.second) {
content = <FormDetails dynamicForm={dynamicForm} />;
} else if (step === screen.third) {
content = <FormFields dynamicForm={dynamicForm} />;
}
return (
<form onSubmit={onNextButtonPress} noValidate={step === screen.third}>
<LinearProgress progress={progress} determinate />
{content}
<div className="request-btn-container">
<Button label="Previous step" onClick={onBackButtonPress} />
<Button label="Next step" type="submit" />
</div>
</form>
);
};
Will appreciate any tip or advice.
There are 2 inputs in React wolrd, first is controlled and the other is uncontrolled.
If you choose to use controlled way, you probably holding the value in your own form state and you can use this value to display textfield. In uncontrolled way, you are to select the DOM element first before you manipulate it.
It seems like that you want to do this thing with uncontrolled way judging by your code.
import { useRef } from 'react'
.
.
.
const FormDetails = ({ dynamicForm }: { dynamicForm: DynamicForm }) => {
const text1 = useRef()
const check1 = useRef()
const text2 = useRef()
const check2 = useRef()
useEffect(() =>{
text1.current.style.display = check1.current.checked ? 'none' : 'block'
}, [ check1.current.checked ])
useEffect(() =>{
text2.current.style.display = check2.current.checked ? 'none' : 'block'
}, [ check2.current.checked ])
return (
<div>
<h4 style={{ margin: 16 }}>asd</h4>
<Grid>
<GridRow>
<GridCell span={4}>
<TextField
maxLength={512}
textarea
label="TextField1"
onChange={(value) => (dynamicForm.description.kk = value)}
defaultValue={dynamicForm.description?.ru}
ref={text1}
/>
</GridCell>
<GridCell span={4}>
<TextField
maxLength={512}
textarea
label="TextField2"
onChange={(value) => (dynamicForm.description.en = value)}
defaultValue={dynamicForm.description?.en}
ref={text2}
/>
</GridCell>
</GridRow>
<GridCell span={4}>
<Checkbox
label="Checkbox1"
onChange={(value) => (dynamicForm.needApprove = value)}
defaultChecked={dynamicForm.needApprove}
ref={check1}
/>
</GridCell>
<GridCell span={5}>
<Checkbox
label="Checkbox2" //
onChange={(value) => (dynamicForm.needExtraApprove = value)}
defaultChecked={dynamicForm.needExtraApprove}
ref={check2}
/>
</GridCell>
</GridRow>
</Grid>
</div>
);
};
import { useRef } from 'react'
.
.
.
const FormDetails = ({ dynamicForm }: { dynamicForm: DynamicForm }) => {
const check1 = useRef()
const check2 = useRef()
return (
<div>
<h4 style={{ margin: 16 }}>asd</h4>
<Grid>
<GridRow>
<GridCell span={4}>
{
!check1.current.checked &&
<TextField
maxLength={512}
textarea
label="TextField1"
onChange={(value) => (dynamicForm.description.kk = value)}
defaultValue={dynamicForm.description?.ru}
/>
}
</GridCell>
<GridCell span={4}>
{
!check2.current.checked &&
<TextField
maxLength={512}
textarea
label="TextField2"
onChange={(value) => (dynamicForm.description.kk = value)}
defaultValue={dynamicForm.description?.ru}
/>
}
</GridCell>
</GridRow>
<GridCell span={4}>
<Checkbox
label="Checkbox1"
onChange={(value) => (dynamicForm.needApprove = value)}
defaultChecked={dynamicForm.needApprove}
ref={check1}
/>
</GridCell>
<GridCell span={5}>
<Checkbox
label="Checkbox2" //
onChange={(value) => (dynamicForm.needExtraApprove = value)}
defaultChecked={dynamicForm.needExtraApprove}
ref={check2}
/>
</GridCell>
</GridRow>
</Grid>
</div>
);
};
If you'are keeping the value of form as a state, you can replace the ref.current.checked to your own boolean state.
If you are using framework with your components, there gotta be the API to forward you ref to input element. (ex > In material UI, inputRef={YOUR_REF}).