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 :)

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

5 Comments

Cool. Nice solution but, still some issue while deleting some row same as your codesandbox.io/s/xp259q9wvq. Trying to fix that.
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...
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.
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
Sandbox link updated, but you should move the tr in a new component maybe, but this is your choise.
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...})}
/>

Comments

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 Comments

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
Gotcha, then the author should use this link reactjs.org/docs/lifting-state-up.html :)
It stops my row and column display functionality
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>
    )
  }
}

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.