Ben Walker
Ben Walker

Reputation: 2137

react table row show column on button click

I have a table being built dynamically by mapping over an array. Each item in the array gets a row. One of the columns in each of these rows is a select. I only want that column's content to show when a button in the same row's next column is clicked.

My plan was to add some sort of a toggle bool property to each object in my array, but then when I try to toggle it in my button's onclick, my eslint is complaining because I'm trying to modify a property of the parameter I sent into the function called by the onclick.

What is the appropriate way to do this?

Here's the code for the table:

<table>
  <tbody>
    {myArray.map(row => (
      <tr key={`test-${row.name}`}>
        <td>
          <div className="testClass">{row.id}</div>
        </td>
        <td>{row.name}</td>
        <td>
          <Select
            options={this.getOptions(row.id)}
            onSelect={this.onOptionSelect}
            placeholder="Select something"
          />
        </td>
        <td><button onClick={() => { changeStuff(row); }}>{ row.myToggle ? 'Save' : 'Change something' }</button></td>
      </tr>
    ))}
  </tbody>
</table>

Upvotes: 1

Views: 11549

Answers (1)

Dev
Dev

Reputation: 3932

In click handler, you can update your array altogether to show/hide the select option.

Based on my understanding, I have tried creating below snippet. This is the way i could come up with, as per my understanding. I have maintained 'hidden' field in the array of objects. Instead of 'Select' I have used a simple button. You can change accordingly. Hope this helps.

const list = [
  {
    name: "Person 1",
    phone: "123-4567",
    id: 11,
    hidden:true
  },
  {
    name: "Person 2",
    phone: "123-4567",
    id: 12,
    hidden:true
  },
  {
    name: "Person 3",
    phone: "123-4567",
    id: 23,
    hidden:true
  },
  {
    name: "Person 4",
    phone: "123-4567",
    id: 34,
    hidden:true
  },
  {
    name: "Person 5",
    phone: "123-4567",
    id: 45,
    hidden:true
  }
];

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      list: list
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(item) {
    let updatedList = this.state.list.map(obj => {
       if(obj.id === item.id) {
         return Object.assign({}, obj, {
            hidden:!item.hidden
         });
       }
       return obj;
    });
    this.setState({
      list : updatedList
    });
  }

  render() {
    return (
      <div>
        <table>
          <tbody>
            {this.state.list.map(item =>
              <tr key={item.itemId}>
                <td>
                  {item.name}
                </td>
                <td>
                  {item.phone}
                </td>
                <td >
                  <button hidden={item.hidden}> Action </button>
                </td>
                <td>
                  <button
                    className="delete"
                    onClick={() => this.handleClick(item)}
                  >
                    Change
                  </button>
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById("app"));
table td {
     font-size: 14px;
     font-weight: normal;
     padding: 10px;
     border: 1px solid #eee;
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>

Upvotes: 2

Related Questions