Reputation: 21
How can I create the method when I click on one checkbox other checkbox unselceted and just can select one of them.
import React, { Component } from 'react';
export default class Tablerow extends Component {
constructor(props){
super(props);
let {listwebsites} = this.props;
listwebsites.checked = false;
this.state = {
fields : {
id: listwebsites.id
}
}
this.click = this.click.bind(this);
this.selectOnlyThis = this.selectOnlyThis.bind(this);
}
click(value){
this.props.handleChangess(this.state, value);
};
render() {
const {listwebsites} = this.props;
return (
<tr>
<td><input id={`checkbox_${listwebsites.id}`} value={listwebsites.checked} onChange={e => this.click(e.target.checked)} type="checkbox" name="record"/></td>
<td>{listwebsites.name}</td>
<td>{listwebsites.url}</td>
</tr>
)
}
}
Upvotes: 1
Views: 11423
Reputation: 66
You should add "checked={}" on checkbox and return true for the time you want it checked.
<input checked={selectedId && selectedId!==listwebsites.id} id={`checkbox_${listwebsites.id}`} value={listwebsites.checked} onChange={e => this.click(e.target.checked)} type="checkbox" name="record" />
This will check your checkbox when only this condition (selectedId && selectedId!==listwebsites.id)
Upvotes: 0
Reputation: 171
Basically, move the selection state one level up. You must be looping over Table row, in a Table component one level up. Put a state field there, say, 'selectedId', and pass it as prop to all the Table row components. Later, onChange will propagate from Table row with 'id' to Table onChangeHandler, for 'selectedId' update. In the render function for Table row, simply add say checked = id === selectedId
thus, making only one of the Table rows selected at any given time. To make it more generic, you can later add say 'multiple' true/ false flag, where the component can switch between allowing multiple vs single checkbox selection.
Working example https://codesandbox.io/s/zn9l7qpn83
By default, first one would be selected. As you select another one, it would deselect the other one; thus allowing only one to be selected at any given time.
Hope it helps!
Upvotes: 2
Reputation: 946
Here's how you do it, in TableRow's parent which is App.js in this snippet, use selectedId
state which store the id or TableRow's listwebsite's id if checked and will be null if not checked.
Inside your TableRow render, use disabled
attr in your<input/>
element. The disabled
will check the selectedId
props passed down from <App/>
, if selectedId
not null and selectedId
value !== current <TableRow/>
listwebsite's id, then disable the <input/>
.
const listwebsitesData = [
{ id: 1, name: 'name-1', url: 'Url-1' },
{ id: 2, name: 'name-2', url: 'Url-2' },
{ id: 3, name: 'name-3', url: 'Url-3' }
]
class App extends React.Component {
constructor(props){
super(props);
this.state = {
selectedId: null,
}
this.handleChangess = this.handleChangess.bind(this);
}
handleChangess(id, value) {
this.setState({selectedId: value===true?id:null})
}
render(){
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{
listwebsitesData.map((data)=>{
return <Tablerow selectedId={this.state.selectedId} listwebsites={data} handleChangess={this.handleChangess} />
})
}
</div>
)
}
}
class Tablerow extends React.Component {
constructor(props) {
super(props);
let { listwebsites } = this.props;
listwebsites.checked = false;
this.state = {
fields: {
id: listwebsites.id
}
}
this.click = this.click.bind(this);
this.selectOnlyThis = this.selectOnlyThis.bind(this);
}
click(value) {
this.props.handleChangess(this.state.fields.id, value);
};
selectOnlyThis(){
}
render() {
const { listwebsites, selectedId } = this.props;
return (
<tr>
<td><input disabled={selectedId && selectedId!==listwebsites.id} id={`checkbox_${listwebsites.id}`} value={listwebsites.checked} onChange={e => this.click(e.target.checked)} type="checkbox" name="record" /></td>
<td>{listwebsites.name}</td>
<td>{listwebsites.url}</td>
</tr>
)
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<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="root"></div>
Upvotes: 3