1

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>
          )
    }
}
3
  • Sorry I don't get your question. Do you want that you checkboxes works as radio buttons, where only one at time can be selected? Commented Feb 3, 2019 at 9:16
  • yes i want my checkbox work look like the radio button Commented Feb 3, 2019 at 9:24
  • If I understand you correctly, the Tablerow component should be stateless (i.e. controlled) and the parent component should hold an array of selected rows as its state. Commented Feb 3, 2019 at 12:13

3 Answers 3

3

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>

Sign up to request clarification or add additional context in comments.

Comments

2

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!

1 Comment

tanks for helping, can you edit my code with your answer?!
0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.