I want to be able to disable a checkbox once I check on the checkbox and execute the onChange method.
I was able to find a way to do this, but once multiple items are checked only the recently checked checkbox is disabled.
The disable method is inside a component class before the render method
Disable = id => {
document.getElementById(id).disabled = true;
//another method to execute onchange
};
<span>
<input
type="checkbox"
className="form-check-input"
onChange={this.Disable}
value=""
/>
</span>;
The checkbox is inside the render method.
One the user checks the checkbox the checkbox needs to check and disable it self
Some notice points:
use camelCase for function name
use props value to make the checkbox fully controlled
use props disabled to disable input element
set the related state inside the handler function
no need for document.getElementById in your current situation
handler event is not id, if you just need id, pass it as a param this.handler(id)
Demo:
const App = () => {
const [checked, setChecked] = React.useState(false);
const [status, setStatus] = React.useState(true);
const onChangeHandler = () => {
setChecked(!checked);
setStatus(false);
};
return (
<div className="App">
<input
type="checkbox"
value={checked}
disabled={!status}
onChange={onChangeHandler}
/>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
you should have to attach id on element .
let Disable=(id)=>{
if(id){
document.getElementById(id).disabled = true
}
}
<span>
<input type="checkbox" className="form-check-input" onChange="Disable(this.id)" id="one" value=""/>
<input type="checkbox" className="form-check-input" onChange="Disable(this.id)" id="two" value=""/>
<input type="checkbox" className="form-check-input" onChange="Disable(this.id)" id="three" value=""/>
</span>
passing the event in an anonymous arrow function and accepting it as an argument in the eventHandler(component method) and using the event.target there is the appropriate way of doing this in such situations that you need to access the caller.
class Stack extends Component {
Disable = event => {
event.target.disabled = true;
//another method to execute onChange
};
render() {
return (
<span>
<input
type="checkbox"
className="form-check-input"
onChange={event => this.Disable(event)}
value=""
/>
<input
type="checkbox"
className="form-check-input"
onChange={event => this.Disable(event)}
value=""
/>
<input
type="checkbox"
className="form-check-input"
onChange={event => this.Disable(event)}
value=""
/>
</span>
);
}
}
Related
I have two inputs, first phone second code and you can toggle between those. if you click on toggle button it works good, but there is problem, if you type something in first input, this value show on second input too! any idea how to fix this??
function Example() {
const [confirm, setConfirm] = useState(false);
return (
<div>
{!confirm ? <input placeholder="phone" type="number" name="phone"/>
:
<input placeholder="code" type="number" name="confirm"/>}
<button onClick={() => setConfirm(!confirm)}>
Click me
</button>
</div>
);
}
Demo
You need to set key for each input. to make the inputs totally replaced.
function Example() {
const [confirm, setConfirm] = useState(false);
return (
<div>
{!confirm ? <input key="1" placeholder="phone" type="number" name="phone"/>
:
<input key="2" placeholder="code" type="number" name="confirm"/>}
<button onClick={() => setConfirm(!confirm)}>
Click me
</button>
</div>
);
}
I am new to react. I have got a scenario where I have multiple radio button and few of the radio buttons have an input box associated with it. Like in the below image:
What I want is:
If the user checked any radio button which has an input box
associated with it, then that input box will become required field.
(display validation message "input is required" on button click.
otherwise display data on the console).
If everything is okay then On click of save button show data on the
console.
I have written some code. This code validates if none of the radio button is checked on button click (obvious case). But I am not understanding how to achieve the above requirement.
import React from "react";
const ContactUsForm = () => {
const isFormValid = () => {
var radios = document.getElementsByName("myRadio");
var isValid = false;
var i = 0;
while (!isValid && i < radios.length) {
if (radios[i].checked) isValid = true;
i++;
}
return isValid;
};
const handleButtonClick = () => {
if (!isFormValid()) {
alert("Select atleast one radio button");
} else {
alert("Success");
}
};
return (
<div>
{" "}
<br />
<label>
<input type="radio" name="myRadio" value="Graduate" /> I am graduate
</label>{" "}
<br />
<label>
<input type="radio" name="myRadio" value="Something" /> Some radio button
</label>{" "}
<br />
<label>
<input type="radio" name="myRadio" />I am graduate from university name
</label>{" "}
<input type="text" id="other" />
<br />
<label>
<input type="radio" name="myRadio" />
Other
</label>
<input type="text" id="other2" />
<br />
<button onClick={handleButtonClick} type="submit">
Save
</button>{" "}
<br />
</div>
);
};
export default ContactUsForm;
Can anybody help me in achieving the above requirement in react? Thank You
So you should use React State hook.
For every input, you need to add onClick event.
Declare state:
const [radioBtn, setRadioBtn] = useState(null);
Change state for each button click:
<input type="radio" name="myRadio" value="Graduate" onClick={() => setRadioBtn('Graduate')}/> I am graduate
In the end, all you need to do is to click Save and you can manage all the stuff you need in handleButtonClick
<button onClick={handleButtonClick} type="submit">
Save
</button>
Here you can validate all you need. Instead of alert you can use console.log(radioBtn) so you would get output to console.
const handleButtonClick = () => {
if (radioBtn) {
alert(radioBtn);
} else {
alert(radioBtn + ' fail');
}
}
I am developing a React app with a checkbox. I would like to include a checkbox that sends true when checked and false when unchecked. my onChange is:
handleChange = (e) => {
this.setState({
[e.target.id]: e.target.value
})
}
And the input is:
<label>
<input type="checkbox" class="filled-in" value="true" id="My Value"
onChange={this.handleChange} />
<span>My Value</span>
</label>
My State has:
state = {
My Value = ''
}
When I submit with the checkbox checked, it works fine. The problem is when I check and uncheck, The value remains true instead of changing to false. How can I fix this. Please help.
Thanks.
Update handler to consume checked value from event
handleChange = e => {
this.setState({
[e.target.id]: e.target.checked
});
};
And don't hardcode checked value of input
<label>
<input
type="checkbox"
className="filled-in"
value={this.state['My Value']}
id="My Value"
onChange={this.handleChange}
/>
<span>My Value</span>
</label>
Change value="true" to value={this.state["My Value"]}
I have a child component that receives props from a parent. In the child component it renders a couple radio buttons like this:
<div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={this._handleInputChange}
value="1"
checked={this.props.value === "1"}
/>
True
</label>
</div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={this._handleInputChange}
value="0"
checked={this.props.value === "0"}
/>
False
</label>
</div>
</div>
handleInputChange just calls a parent method like so:
_handleInputChange(e) {
this.props.handleChange(e);
}
that will set the state of the parent component to the value selected in the radio buttons (i.e. "1" or "0"). The issue im having is that the checked conditionals return the correct props, but they function strangely. It almost seems like when the radio input receives a new prop value, it doesn't re render with checked. When the component first renders, the props.value is an empty string. When a user selects a radio button it changes the state of the parent component with _handleInputChange and then sends that value back down for the conditionals.
Thanks to some of the help here and on IRC I figured out it was a preventDefault in my event handler. After removing that it worked perfectly!
You must use state for checked property if you want react re-render radio button.
Example:
<div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={this._handleInputChange}
value="1"
checked={this.state.radioButton1}
/>
True
</label>
</div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={this._handleInputChange}
value="0"
checked={this.state.radioButton2}
/>
False
</label>
</div>
</div>
You also set value for state like this (alternatively, you can initialize it with getInitialState):
this.setState({
radioButton1 : props.value ==="1",
radioButton2 :props.value ==="0"
});
And in _handleInputChange function you're able to know that radio button is checked or unchecked by checking it's state.
_handleInputChange(e) {
var isChecked = e.target.value ==="1" ? this.state.radioButton1 : this.state.radioButton2;
this.props.handleChange(e);
}
use bind method to bind context this._handleInputChange.bind(this) in the constructor,or use (e)=>this._handleInputChange(e) on click ,when the event handler executed normally has no context.
or declared as this below,it can bind this automatically:
class ButtonGroup extends Component{
....
_handleInputChange= (e)=>{
...
}
sample below:
class ButtonGroup extends Component {
render() {
return (
<div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={(e) => this._handleInputChange(e)}
value="1"
checked={this.props.value === "1"}
/>
True
</label>
</div>
<div className="radio">
<label>
<input
type="radio"
name="value"
onChange={(e) => this._handleInputChange(e)}
value="0"
checked={this.props.value === "0"}
/>
False
</label>
</div>
</div>
);
}
_handleInputChange(e) {
this.props.handleChange(e);
}
}
class Form extends Component {
constructor(props) {
super(props);
this.state = {value: '1'};
}
render() {
var value = this.state.value;
return <ButtonGroup value={value} handleChange={(e) => this.valueChanged(e)}/>
}
valueChanged(e) {
this.setState({value: e.target.value});
}
}
ReactDOM.render(
<Form />,
document.getElementById('container')
);
_toggleValue: function(state) {
//?? how to do it
//this.setState(???);
},
render() {
<div>
<form>
<input type="checkbox" onChange={this._toggleValue.bind(null, this.state.a)} />
<input type="checkbox" onChange={this._toggleValue.bind(null, this.state.b)} />
<input type="checkbox" onChange={this._toggleValue.bind(null, this.state.c)} />
</form>
</div>
}
There are quite lot checkboxes in the form, currently, what I am doing is to define one method for each checkbox. How can I define one method which can be used by all the checkboxes.
Many thanks in advance
You could use the LinkedStateMixin.
Your checkboxes would look something like this:
<input type='checkbox' checkedLink={this.linkState('a')}/>
<input type='checkbox' checkedLink={this.linkState('b')}/>
<input type='checkbox' checkedLink={this.linkState('c')}/>
This will automatically keep the values of the checkboxes a, b and c up to date with the state variables.
You can use an id on your checkboxes and retrieve it from event.target.id that is passed to onChange handler as below:
_toggleValue: function(event) {
var state = this.state[event.target.id];
},
render: function() {
return (
<div>
<form>
<input type="checkbox" id={1} onChange={this._toggleValue}/>
<input type="checkbox" id={2} onChange={this._toggleValue}/>
<input type="checkbox" id={3} onChange={this._toggleValue}/>
</form>
</div>
)
}
I did it this way:
toggleCheckbox(name, event) {
let change = !this.state[name];
this.setState({name: change});
}
<input type="checkbox" name="active" defaultChecked={this.state.active} onChange={this.toggleCheckbox.bind(this, 'active')} />
<input type="checkbox" name="shared" defaultChecked={this.state.shared} onChange={this.toggleCheckbox.bind(this, 'shared')} />
Note the "defaultChecked" and that I'm not using the preventDefault() statement.