How can I create a table with conditionally editable input/cells using React?

寵の児 提交于 2020-01-06 14:35:11

问题


I have a table like this:

When a user clicks on an Edit button, an <input> should appear in its place.

If a user clicks on another Edit button, this one will also be replaced with an <input>, and the previous <input> should disappear and show an Edit button again.

In short, only one field can be in edit mode at a time.

This is my initial state:

state = {
    editnameEnable: false,
    editemailEnable: false,
    editaddressEnable: false,
    edittelephone_noEnable: false,
}

This is my edit() method:

edit = value => {
    var address_element = ['name','address','email','telephone_no']; 
    address_element = address_element.filter(element => element !== value); 
    address_element.map( val => this.setState({[`edit${val}Enable`]: false}));

    this.setState({[`edit${value}Enable`]: true}, ()=>{
        console.log(this.state);
    });
}

This is part of the JSX inside my render method:

<td>{
    this.state[`edit${this.props.item}Enable`] ? ( <input type="text"/> ) : (
        <span
            className="edit"
            onClick={ () => this.edit(this.props.item) }>Edit</span>
    )
}</td>

The issue is that when I click on an Edit button, the <input> appears, but when I click another Edit button, the previous <input> does not disappear.


回答1:


What about using a single editableField property that is initially set to null?

Then, when you click on an Edit button, you set editableField to the name of that field, and inside render you check, for each field, whether editableField matches its name or not to render an Edit button or an input field.

Something like this:

class FieldCell extends React.Component {

  constructor(props) {
    super(props);
  }
  
  focusField = (element) => element && element.focus();
  
  render() {
    const editElement = this.props.isEditable ? (
      <input type="text" ref={ this.focusField }/>
    ) : (
      <button onClick={ () => this.props.onEdit() }>EDIT</button>
    );
    
    return (<td className="textLeft">{ editElement }</td>);
  }
}

class UserData extends React.Component {

  constructor(props) {
    super(props);
    
    this.state = {
      editableField: null,
    };
  }
  
  render() {
    const editableField = this.state.editableField;
    
    const rows = ['Name', 'Address', 'Telephone No.', 'E-Mail'].map((field) => {
      const isEditable = field === editableField;
      
      return (
        <tr key={ field }>
          <td>{ field }</td>
          <FieldCell isEditable={ isEditable } onEdit={ () => this.setState({ editableField: field })}></FieldCell>
        </tr>
      );
    });

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

ReactDOM.render(<UserData />, document.getElementById('app'));
body {
  font-family: monospace;
  font-size: 13px;
}

table {
  border: 2px solid #000;
  border-collapse: collapse;
  text-align: right;
  width: 100%;
}

td {
  border: 2px solid #000;
  padding: 4px;
  width: 50%;
  overflow: hidden;
}

.textLeft {
  text-align: left;
  user-select: none;
}

button,
input {
  border: 2px solid black;
  padding: 4px 8px;
  margin: 0;
  font-family: monospace;
  font-size: 13px;
  box-sizing: border-box;
  background: none;
  outline: none;
}

button:hover,
button:focus,
input:hover,
input:focus {
  border-color: blue;
  color: blue;
}

button {
  font-weight: bold;
}

input {
  width: 50%;
}
<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>


来源:https://stackoverflow.com/questions/51348505/how-can-i-create-a-table-with-conditionally-editable-input-cells-using-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!