I have a radio button using pure css, but it doesn't work on first click, it only work on the second click onward, not sure it has to do with my react prop or not:
const Radio = ({ id, name, value, checked, children }) => (
<div className="radioBtn">
<input type="radio" value={value} id={id} name={name} checked={checked} />
<label className={"radio"} htmlFor={id}>
<span className={"big"}>
<span className={"small"} />
</span>
<span>{children}</span>
</label>
</div>
);
https://codesandbox.io/s/react-sass-34b8w
Use defaultChecked instead of checked={checked}.
Related
I am new to react and I got a scenario where I have multiple checkboxes on my form. I want the user to check all the checkboxes only then enable the submit button on the form. On Load, the submit button will be disabled. How to do this?
Here is the code that I have written so far:
const MultipleCheckboxes = () => {
const handleChange = () => {
}
const allChecked = () => {
}
return (
<div>
<form>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value="Java"
id="languageChkDefault"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Javascript
</label>
</div>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value="Angular"
id="languageChkDefault"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Angular
</label>
</div>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value="Python"
id="languageChkDefault"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Python
</label>
</div> <br />
<button disabled={!allChecked}>Submit</button>
</form>
</div>
);
};
export default MultipleCheckboxes;
Can anybody help me on this? thank you
This is my solution, I hope it helps you
import { useState, useEffect } from "react";
const MultipleCheckboxes = () => {
const [allChecked, setAllChecked] = useState(false);
const [checkboxes, setCheckboxes] = useState({
javaCheckbox: false,
angularCheckbox: false,
pythonCheckbox: false
});
function handleChange(e) {
setCheckboxes({
...checkboxes,
[e.target.id]: e.target.checked
})
}
useEffect(() => {
const result = Object.values(checkboxes).every(v => v);
console.log(result);
setAllChecked(result);
}, [checkboxes]);
return (
<div>
<form>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value={checkboxes.javaCheckbox}
id="javaCheckbox"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Javascript
</label>
</div>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value={checkboxes.angularCheckbox}
id="angularCheckbox"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Angular
</label>
</div>
<div className="form-check">
<input
type="checkbox"
className="some-class-name-chk"
name="someName"
value={checkboxes.pythonCheckbox}
id="pythonCheckbox"
onChange={handleChange}
/>
<label
className="form-check-label"
htmlFor="languageChkDefault"
>
Python
</label>
</div> <br />
<button disabled={!allChecked}>Submit</button>
</form>
</div>
);
};
export default MultipleCheckboxes;
You can use react useState hook and set its default value to false.
const [state, setstate] = useState(false)
When the user clicks on an input box set the state to true. You may encounter some problems when the user unchecks the box, so you can use an if statement to handle state change
For example:
if (state === true){
setstate(false)
}else{
setstate(true)
}
or you can just use this code inside the handleChange function:
!state
It inverses the state to true/false accordingly.
After that you can use a ternary operator inside the component to check whether the user has checked all the boxes, if the user hasn't checked all the boxes, disable the button or else do otherwise.
For example, if the state is true (or in other words, if the user has checked the box), render the normal styled button, else render the disabled button:
{state? <button className = "styled"/>: <button disabled className="styled"/>}
Of course, I have only checked the state of one input box. Now you can simply check for multiple conditions by declaring multiple states for each box.
{state1 && state2 && state3 ? <button className = "styled"/>: <button disabled className="styled"/>}
If you are not yet familiar with ternary operators, you should go through this doc Ternary operators.
If you haven't heard of useState and react hooks yet, feel free to look the React's documentation. Welcome to the React ecosystem!
Created the multiple radio options, but it is allowing me to select more then one option.
{item.responseType === "radio" && (
<div className="form-control-wrap">
{item.options.split(",").map((list, index) => (
<Form.Check
key={index}
label={list}
name={list}
type="radio"
id={list}
/>
))}
</div>
)}
What changes need to be done to select only one option ?
If you want only one of them to be selectable. You must set the value of the name props to the same value for all of them. like this
name="radio-name" // use filed name
like this
{item.responseType === "radio" && (
<div className="form-control-wrap">
{item.options.split(",").map((list, index) => (
<Form.Check
key={index}
label={list}
name="radio-name"
type="radio"
id={list}
/>
))}
</div>
)}
Link to sandbox replecating the behavior
sand box demo
I have a hook in a React component that I am using as a countdown for time to answer a question.
React.useEffect(() => {
const timer = setInterval(() => {
setTimeLeft((newTimeLeft) => newTimeLeft <= 0 ? 0 : newTimeLeft - 1);
}, 50);
return () => {
if(timeLeft <= 0){
clearInterval(timer);
}
};
}, []);
My form is very simple
<form>
<FormControl>
<RadioGroup aria-label="trivia" name="trivia" value={choice} onChange={handleUserChoice}>
{radioOptions}
</RadioGroup>
<Button variant="outlined" color="secondary" onClick={checkAnswer}>Check Choice</Button>
</FormControl>
</form>
radioOptions is a list of Radio Components making up the choices of answer.
radioOptions = currentQuestion.questionInfo.choices.map((option) => {
return (
<FormControlLabel key={option} value={option} control={<Radio />} label={option} />
)
})
The form is not interactive until after the countdown finishes and clearInterval is called.
I can't click to select any of the radio options in choices. The button works and triggers its function. But the radio options arent interactive until the interval is done.
So, the React.useEffect is just re-rendering the entire choices as the choices reside in the same class, so the choices are getting selected but as soon as the state changes (which is the counter running), the component re-renders the counter and the choices and it looks as if nothing is getting selected. Running the choices directly from the main component helped and it worked like you intended
<div className="App">
{timeLeft}
<form>
<p>Select a maintenance drone:</p>
{/* <Choices /> */}
<div>
<input type="radio" id="huey" name="drone" value="huey" />
<label htmlFor="huey">Huey</label>
</div>
<div>
<input type="radio" id="dewey" name="drone" value="dewey" />
<label htmlFor="dewey">Dewey</label>
</div>
<div>
<input type="radio" id="louie" name="drone" value="louie" />
<label htmlFor="louie">Louie</label>
</div>
<button disabled={timeLeft <= 0 ? true : false} onClick={checkChoice}>
Check Choice
</button>
</form>
</div>
I am trying to use defaultChecked in reactjs when using map function to only one radio button. But How can I acomplish it?
{colors.map((color, index) => {
return (
<label className="color-checkmark" key={index}>
<input
type="radio"
checked="checked"
name="color"
value={color}
// defaultChecked
/>
</label>
);
})}
If I use defaultChecked there it will be set to every radio button.
You need to remove the checked="checked" attribute as it conflicts with the defaultChecked attribute. And then add defaultChecked={index === 0}
If you want the first item checked
{colors.map((color, index) => {
return (
<label className="color-checkmark" key={index}>
<input
type="radio"
name="color"
value={color}
defaultChecked={!(!!index)}
/>
</label>
);
})}
what does !! do?
the !! ensures that the value will always be a boolean or converted to a boolean.
You need to add a condition to your defaultChecked, and remove the checked property:
const colors = ['blue', 'green', 'red']
function App() {
return colors.map((color, index) => (
<label key={index}>
<input
type="radio"
name="color"
value={color}
defaultChecked={index === 0}
/>
<span style={{color}}>{color}</span>
</label>
))
}
ReactDOM.render(<App />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app">euoeu</div>
I'm new to react and redux and i want to create component which contain two radio buttons so i write something like this:
import React, { PropTypes } from 'react';
const renderCashRadioButtons = currentCashSelector => (
<form onClick={currentCashSelector}>
<input
type="radio"
name="cash-transaction"
value="Transcation"
onChange={value => currentCashSelector(value)}
/>
<input
type="radio"
name="cash-transfer"
value="Transfer"
onChange={value => currentCashSelector(value)}
/>
</form>
);
const CashRadioButtons = ({ currentCashSelector }) => (
<div className="container">
{renderCashRadioButtons(currentCashSelector)}
</div>
);
CashRadioButtons.propTypes = {
currentCashSelector: PropTypes.func.isRequired
};
export default CashRadioButtons;
currentCashSelector is a function. When i render this it does not seem to work. The value does not change and i'm not seeing the state to be updated. Do you have any ideas?
You probably want your radio buttons to have the same name, so that when one is selected, the other is deselected.
It looks like your onChange functions are expecting the value, but they're actually receiving the event.
You likely have unwanted duplication between the onChange on your form, and the ones on your radio buttons.
Possible Solution
<form onClick={event => currentCashSelector(event.target.value)}>
<input
type="radio"
name="cash-type"
value="Transaction"
/>
<input
type="radio"
name="cash-type"
value="Transfer"
/>
</form>