I am trying to make use of bootstrap's toggle button group to select an option of platform. But the onChange event is not getting called.
class Hello extends React.Component {
constructor(props) {
super(props);
this.handlePlatformChange = this.handlePlatformChange.bind(this);
}
handlePlatformChange(event) {
/* THIS DOES NOT GET CALLED */
console.log(event.target.value);
}
render() {
return (<div className="container">
<div className="btn-group btn-group-toggle" data-toggle="buttons" onChange={this.handlePlatformChange} >
<label className="btn btn-info active">
<input type="radio" name="platform" value="web" autoComplete="off" /> Web
</label>
<label className="btn btn-info">
<input type="radio" name="platform" value="android" autoComplete="off" /> Android
</label>
<label className="btn btn-info">
<input type="radio" name="platform" value="ios" autoComplete="off" /> iOS
</label>
</div>
</div>
);
}
}
My application is using webpack and below dependencies
"dependencies": {
"axios": "^0.18.0",
"bootstrap": "^4.1.3",
"express": "^4.16.3",
"jquery": "^3.3.1",
"moment": "^2.22.2",
"popper.js": "^1.14.3",
"query-string": "^6.1.0",
"react": "^16.4.2",
"react-bootstrap": "^0.32.1",
"react-dom": "^16.4.2",
"react-router-dom": "^4.3.1"
},
I created a jsfiddle (by only including related libraries) to reproduce the issue.
"bootstrap": "^4.1.3",
"jquery": "^3.3.1",
"popper.js": "^1.14.3",
"react": "^16.4.2",
"react-dom": "^16.4.2",
Update-1:
With the help from comments, I got the jsfiddle to work by using [email protected] instead of 1.14.4. I Also discovered that I had to import libraries in a specific order only. Working sample - https://codepen.io/hussaintamboli/pen/PdoVvG?editors=1111
How do I fix the order with webpack?
Update-2:
I created this github repository to reproduce the issue with react+bootstrap4+webpack4
From the Bootstrap docs...
"The checked state for these buttons is only updated via click event on the button. "
Therefore, the only way to track (from Bootstrap JS) the changed button state is by clicking a button...
handlePlatformChange(event) {
var val = event.currentTarget.querySelector("input").value;
this.setState({ currValue: val });
}
render() {
return (
<div>
<div>{this.state.currValue}</div>
<div className="btn-group btn-group-toggle" data-toggle="buttons">
<label className="btn btn-info active" onClick={this.handlePlatformChange}>
<input
type="radio"
name="platform"
value="web"
autoComplete="off"
/>{" "}
Web
</label>
<label className="btn btn-info" onClick={this.handlePlatformChange}>
<input
type="radio"
name="platform"
value="android"
autoComplete="off"
/>{" "}
Android
</label>
<label className="btn btn-info" onClick={this.handlePlatformChange}>
<input
type="radio"
name="platform"
value="ios"
autoComplete="off"
/>{" "}
iOS
</label>
</div>
</div>
);
}
Working demo: https://codesandbox.io/s/7kkqjy3lqx
Of course, once you get the relevant value (from the clicked button) you can always pass that off to some other handling logic.
I thought at first that maybe the div element having the onChange on it was the issue since there wouldn't be any change event fired from the div no matter what components you click inside it, but even putting it onto the input elements wasn't fixing it.
I know it's not ideal, but putting an onClick event onto the label elements does work.
return (
<div className="container">
<div className="btn-group btn-group-toggle" data-toggle="buttons" >
<label className="btn btn-info active" onClick={this.handlePlatformChange} >
<input type="radio" name="platform" value="web" autoComplete="off" /> Web
</label>
<label className="btn btn-info" onClick={this.handlePlatformChange}>
<input type="radio" name="platform" value="android" autoComplete="off" /> Android
</label>
<label className="btn btn-info" onClick={this.handlePlatformChange}>
<input type="radio" name="platform" value="ios" autoComplete="off" /> iOS
</label>
</div>
</div>
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With