How to set radio button 'checked' based on value from database? - React - reactjs

I have a radio button group in a component. I want to set which radio is selected based on it's value taken from the database in an Update/Edit scenario.
export default function updateRadioSelection(){
const [radioValue, setRadiovalue] = useState("");
useState(()=>{
setRadiovalue("pick"); // <-- Assume this value is taken from database, value may be either "delivery" or "pick"
}, [])
const changeSelection = (e)=>{
setRadiovalue(e.target.value);
}
return(
<div>
<input type="radio" id="delivery" name="orderType" value="delivery" required onChange={changeSelection} />
<label htmlFor="delivery">Delivery</label>
<input type="radio" id="pick" name="orderType" value="pick" onChange={changeSelection} />
<label htmlFor="pick">Pick Up</label>
</div>
)
}

To make a checkbox or radio checked you must use the checked prop for the input element, it receives a boolean value. And you can do something like this
export default function updateRadioSelection(){
const [radioValue, setRadiovalue] = useState("");
// useState will not execute any kind of callback function, for this case you need to use useEffect
useEffect(() => {
const dbResult = getRadioFromDb();
setRadiovalue(dbResult);
}, [])
const changeSelection = (e)=>{
setRadiovalue(e.target.value);
}
return(
<div>
<input type="radio" id="delivery" name="orderType" value="delivery" required onChange={changeSelection} checked={radioValue === 'delivery'} />
<label htmlFor="delivery">Delivery</label>
<input type="radio" id="pick" name="orderType" value="pick" onChange={changeSelection} checked={radioValue === 'pick'} />
<label htmlFor="pick">Pick Up</label>
</div>
)
}
You can read more about radio input in its documentation

Just a few minutes after posting this question I found the answer I was searching for. Turns out it's pretty easy.
Just add checked={radioValue === "pick"} for the Pick Up radio button & the same for other radio button by replacing "pick" with "delivery"
reference - react.tips/radio-buttons-in-reactjs

Related

How can I collect data by sending the register as props to the child component using React Hook Form?

Using React Hook Form, when I want to collect data by sending register as props to child component to take input value from child component, it shows 'register is not a function' error.
How can I solve this?
const { register, formState: { errors }, handleSubmit } = useForm();
const onSubmit = (data) => console.log(data);
<form onSubmit={handleSubmit(onSubmit)}>
<fieldset>
<legend className='text-[#666666]' >Status</legend>
{
statusData.map(status => <CheckboxFilter register={register} key={status._id} status={status}/>)
}
</fieldset>
</form>
here child
//CheckboxFilter component
const CheckboxFilter = ({ status, register }) => {
return (
<>
<p className='text-[#858585] mt-2 text-[14px]' >
<label htmlFor={status?.name} className='cursor-pointer' >
<input {...register("checkBoxData")} type="checkbox" name="status" id={status?.name} value={"status?.name"} /> {status?.name}
</label>
</p>
</>
);
};
I created a sandbox here codesandbox and it works perfectly.
I took your code and only changed the CheckboxFilter component:
Removed the name property (register function returns the name of the input based in the string you pass to it as a parameter, you should not override it)
Removed the value property (that was making the value of the checkbox constant, because there wasn't onChange handler that was modifying it)
Changed ...register("checkBoxData") to ...register(checkBoxData${name}) so this way you can have every checkbox value individually in the form.
Anyway, if you want to have a different behaviour than what I have assumed, let me know and I will help.
-Ado

Multiple value / onChange values in a React form

I must be missing something very simple, but I can't figure out how to deal with having 2 value / onChange to pass to my component.
I tried changing the names, and that gets rid of errors and renders the app, but of course event.target.value does not work as if I change the second value to, for example to numval or something. event.target.numval doesn't recognize anything is happening.
Thank you so much in advance! And if this has been asked before I apologize, but I couldn't find it... which makes me think I'm overlooking a very simple solution.
return (
...
<PersonForm
onSubmit={addName}
value={newName}
onChange={handleName}
value={newNumber}
onChange={handleNumber}
/>
)
Here is the original code that worked fine before I tried to put the component into its own file:
return (
...
<form onSubmit={addName}>
<div>
name: <input value={newName} onChange={handleName} />
</div>
<div>
number: <input value={newNumber} onChange={handleNumber} />
</div>
<div>
<button type="submit">add</button>
</div>
</form>
your code sample is not clear but it seems you want to retrieve value from event.target object through event handler function triggered by onChange event on
an element. And you want to call event handler function available in a parent component from a child component.
You can try the following:
const App () => {
const [newNameValue, setName] = useState('');
const [newNumberValue, setNumber] = useState('');
const nameChangeHandler = (event) => {
setName(event.target.value);
};
const numberChangeHandler = (event) => {
setNumber(event.target.value);
};
const submitFormHandler = () => {
your code on form submit
};
return (
<PersonForm
submitForm={submitFormHandler}
newName={newNameValue}
handleName={nameChangeHandler}
newNumber={newNumberValue}
handleNumber={numberChangeHandler}
/>
);
}
const PersonForm (props) => {
return (
<form onSubmit={props.submitForm}>
<div>
name: <input value={props.newName} onChange={props.handleName} />
</div>
<div>
number: <input value={props.newNumber} onChange={props.handleNumber} />
</div>
<div>
<button type="submit">add</button>
</div>
</form>
);
}
onChange is a reserved attribute name which is available on few html elements
such as <input> and <select>. You should ideally not use it on other elements, like in your case custom html component <PersonForm>.
Since you're keeping form in separate component then you can trigger a function call received through attributes on props object.
You may call two different onChange event handler functions on two input elements.
I hope you got your answer, feel free to ask in case of any more doubts.
You may refer:
https://reactjs.org/docs/forms.html

Radio ref on react

I have radio input use want to use ref to show the result on console.
I always get second value even when I have choose the first one.
This is the constructor
this.inputKelamin = React.createRef();
and rendered like this
<div>
Jenis Kelamin :
<input name="kelamin" type="radio" value="laki - laki" ref={this.inputKelamin}/>
Laki - laki
<input name="kelamin" type="radio" value="perempuan" ref={this.inputKelamin}/>
Perempuan
</div>
onSubmit, I put it like this via console :
alamat : ${this.inputAlamat.current.value}
the result is always "perempuan"
This is not for production, just a learning purpose, thank you
You're using same ref for both the element, second ref={this.inputKelamin} overrides the first one and it always points to the second radio button.
From official docs
Refs provide a way to access DOM nodes or React elements created in the render method.
You should create 2 different refs for both inputs.
And you're checking the wrong property here
this.inputAlamat.current.value
value will always be the attribute value you gave value="perempuan".
In case of radio you should look at the checked property, which tells you whether it was selected
this.inputKelamin.current.checked
Also, you might want to look at controlled and un-conntrolled components
In order to get just one data from multiple radio you cam simply do this :
Example with typescript :
import React, { useRef } from "react";
function Form() {
const inputKelamin = useRef() as React.MutableRefObject<HTMLInputElement>;
const inputLaki = useRef() as React.MutableRefObject<HTMLInputElement>;
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const selectedRadio = inputKelamin.current.checked ? inputKelamin.current.value : inputLaki.current.value
console.log(selectedRadio);
}
return (
<form className="form" onSubmit={handleSubmit}>
Jenis Kelamin :
Laki - laki <input type="radio" value="laki - laki" ref={inputKelamin} /> <br />
Perempuan <input type="radio" value="perempuan" ref={inputLaki} /> <br />
<button type="submit">Submit</button>
</form>
);
}
export default Form;

Giving Options to the User and then Displaying the chosen option

So, i have just started working on React and i have a doubt. So, i want to create two different forms and then allow user to fill one form by selecting that form. So, i have created both the forms now how do i create a page where i give options to the user to choose one and after the user chooses first option, then the first option form displays. How do i do that? I have created both the forms, now i just need help with how to link those two forms to the pages where i am giving option to the user.
So, do i need to create a third component like the other two containers. Those forms are basically are two different containers. So, how do i work on the third container?
Thanks
Firs you need two radio inputs that user will select them and a variable that will hold the selected value and will change on onChange:
const [selected, setSelected] = useState("first");
function onChange({ target }) {
setSelected(target.value);
}
return {
<label>
<input value="first" onChange={onChange} type="radio" name="forms" checked={selected === "first"} />
First Form
</label>
<label>
<input value="second" onChange={onChange} type="radio" name="forms" checked={selected === "second"} />
Second Form
</label>
}
Then you need to show forms based on what the selected value is:
{selected === "first" && <FirstForm />}
{selected === "second" && <SecondForm />}
So when selected is 'first' it will show FirstForm component otherwise when its 'second' it will show 'SecondForm'.
So the final MainComponent will be like this:
import React, { useState } from 'react';
import FirstForm from './first-form.js';
imprt SecondForm from './second-form.js';
function MainComponent() {
const [selected, setSelected] = useState("first");
function onChange({ target }) {
setSelected(target.value);
}
return (
<div className="App">
<h1>Select Form</h1>
<label>
<input value="first" onChange={onChange} type="radio" name="forms" checked={selected === "first"} />
First Form
</label>
<label>
<input value="second" onChange={onChange} type="radio" name="forms" checked={selected === "second"} />
Second Form
</label>
{selected === "first" && <FirstForm />}
{selected === "second" && <SecondForm />}
</div>
);
}

Testing tabaility with enzyme

I have a simple checkbox input I want to test it when user wants to tab into the checkbox and expect something to happen.
const CheckBox = () => (
<input type="checkbox">
)
Test case:
describe("tabability", ()=> {
it("tab into the input",()=>{
const testForm = mount(
<div>
<input type="text" id="textInput" />
<CheckBox id="checkBox" />
</div>
);
const textInput = testForm.find("textInput");
textInput.simulate("keypress", {key: "Tab"});
})
})
But It seems to fail to find the text input. my textInput variable is pointing to testForm. What can I do to assigned input text to a variable and assign checkbox to a variable?
it should be
...
const textInput = testForm.find("#textInput");
...
same goes for the checkbox

Resources