0

I have following code where i am adding dynamic row and column. I want to delete row which on click.

But, getting difficulty figure it out.

class TableCells extends Component {

  onDeleteEvent = event => {
    // Delete row 
  };

  render() {

      var numberOfRow = this.props.numberOfRow; // user input
      var numberOfColumn = this.props.numberOfColumn; // user input

      var rows = Array.from({length: numberOfRow}).map((_, rowIdx) => (

        <tr key={rowIdx}>{
          Array.from({length: numberOfColumn}).map((_, colIdx) => (
            <EditableCell key={colIdx}/>
          ))
        }

        <td>
          <input type="button" onClick={this.onDeleteEvent} value="X" />
        </td>
        </tr>
      ))

      return (<tbody>{rows}</tbody>);
  }
}

Any help would be greatly appreciated.

4 Answers 4

3

Check this sandbox. A little simplified, but works for you. https://codesandbox.io/s/9l9wnonyp

Basically, move your object in the state, and when you delete the item send his ID as parameter, and just set the new state, and it will rerender.

<input
   type="button"
   onClick={() => this.onDeleteEvent(rowIdx)}
   value="X"
/>

And onDeleteFunction:

onDeleteEvent = id => {
    // Delete row
    let rows = this.state.rows;
    rows.splice(id, 1);

    this.setState({
      rows
    });
  };

For any other question just comment here, and I will help you :)

5
  • Cool. Nice solution but, still some issue while deleting some row same as your codesandbox.io/s/xp259q9wvq. Trying to fix that.
    – ketan
    Commented Oct 24, 2018 at 17:09
  • What problem? I create the sandbox as a direction where you have to go :) you can adjust it as you want. And pls mark it as ok, if helped you, maybe other people will need the same stuff...
    – oma
    Commented Oct 24, 2018 at 18:47
  • Problem is if delete first and then try to delete last it won't allow, again you delete first and try to delete any of last 2 won't allowed, again first then last 3 and so.... Yes. will mark correct.
    – ketan
    Commented Oct 24, 2018 at 18:52
  • I got the issue, I delete the id from the array, but then the rowIdx is not updated, and he tries to delete the last position which doesn't exist after the first delete. If you need I can update the answer
    – oma
    Commented Oct 24, 2018 at 18:57
  • Sandbox link updated, but you should move the tr in a new component maybe, but this is your choise.
    – oma
    Commented Oct 24, 2018 at 18:58
1

The right way to do this would be to:

class TableCells extends Component {

  render() {
      const onDeleteEvent = (id) => () => this.props.onDeleteEvent(id);
      var numberOfRow = this.props.numberOfRow; // user input
      var numberOfColumn = this.props.numberOfColumn; // user input

      var rows = Array.from({length: numberOfRow}).map((_, rowIdx) => (

        <tr key={rowIdx}>{
          Array.from({length: numberOfColumn}).map((_, colIdx) => (
            <EditableCell key={colIdx}/>
          ))
        }

        <td>
          <input type="button" onClick={onDeleteEvent(colIdx)} value="X" />
        </td>
        </tr>
      ))

      return (<tbody>{rows}</tbody>);
  }
}

And wherever you use TableCellsand presumably store the number of rows you are passing as a prop to TableCells, you would have a function that reduces the number of rows passed, thus affecting the numberOfRow prop.

I'm guessing you are using TableCells something like this:

<TableCells numberOfRow={this.state.numberOfRow} numberOfColumn={this.state.numberOfColumn} />

You should change it like this:

<TableCells
    numberOfRow={this.state.numberOfRow} 
    numberOfColumn={this.state.numberOfColumn} 
    onDeleteEvent={(idOfColumnToDelete) => {//Modify state here...})}
/>
0
0

You can try this one

class TableCells extends Component {
  state = {
    numRows = this.props.numberOfRow  // I know it is considered as an antipattern :) But in this case that's ok!!!
  }

  onDeleteEvent = () => {
    // also you should add the check if it's not zero :)
    this.setState({ numRows: this.state.numRows - 1 });
  };

  render() {

      const { numberOfColumn } = this.props; // user input
      const { numRows } = this.state;

      const rows = Array.from({length: numRows }).map((_, rowIdx) => (

        <tr key={rowIdx}>
          {
            Array.from({length: numberOfColumn}).map((_, colIdx) => (
              <EditableCell key={colIdx}/>
            ))
          }

          <td>
            <input type="button" onClick={this.onDeleteEvent} value="X" />
          </td>
        </tr>
      ));

      return (<tbody>{rows}</tbody>);
  }
}
3
  • The problem with the answer is the question supposes the user receives the number of rows as a prop, so presumably it would like that state to remain in a component above in the hierarchy, as the prop is not called "initialNumberOfRow" for example Commented Oct 24, 2018 at 14:11
  • Gotcha, then the author should use this link reactjs.org/docs/lifting-state-up.html :) Commented Oct 24, 2018 at 14:14
  • It stops my row and column display functionality
    – ketan
    Commented Oct 24, 2018 at 14:18
0
  class TableCells extends Component {
    constructor () {
    super()
    this.state = {
      numberOfRow: Array.from({length: this.props.numberOfRow}),
      numberOfColumn: Array.from({length: this.props.numberOfColumn})
    }
  }
  onDeleteEvent (index) {
    this.state.numberOfRow.splice(index, 1)
  };

  render () {
    var rows = this.state.numberOfRow.map((elem, index) => (<tr>
      {this.state.numberOfColumn.map((_, colIdx) => {<EditableCell key={colIdx}/>})}
      <td>
        <input type='button' onClick={() => this.onDeleteEvent(index)} value='X' />
      </td>
    </tr>))
    return (
      <tbody>{rows}</tbody>
    )
  }
}

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.