0

I am having a problem of how to have a key so that when I click the edit button, Input field must show on row depending on what row I clicked.

The output is when I click edit button, All input fields of the row are showing.

Here is my code:

constructor(props) {
    super(props);
    this.state = { 
        editable: false,
};

Here is the function that is executing when I click the click button:

  edit = () => {
    this.setState({
      editable: true,
    })
  }

Here is my loop where I want to put the key

for (let i = 0; i < data.length; i++){
    withKeys = {
     ...data[i],
     key: i,
     actionIndex: (
     <>
     {this.state.editable ? (
      <span>
        <EditableContext.Consumer>
           {form => (
             <a
               onClick={() => this.save(form, data[i])}
               style={{ marginRight: 8 }}
             >
               Save
             </a>
     )}
     </EditableContext.Consumer>
       <Popconfirm title="Sure to cancel?" onConfirm={this.cancel}>
         <a>Cancel</a>
       </Popconfirm>
     </span>
      ):
     <Button 
      onClick={this.edit}
      ghost
      type="primary"
      >
        Edit
    </Button> }

How can I add key so that when I click the edit button, input field must show depending on the row where I select the edit button. By the way I am using ant design

2 Answers 2

1

Use an edit index

constructor(props) {
  super(props);
  this.state = { 
    editIndex: null, // null == no edit
  };
};

Update the edit handler to take an index and return the callback function (this is a Higher Order Function)

edit = editIndex => () => {
  this.setState({ editIndex });
}

Then in your render function check the current index to the edit index

for (let i = 0; i < data.length; i++){
  withKeys = {
   ...data[i],
   key: i,
   actionIndex: (
   <>
     {this.state.editIndex === i ? ( // if editIndex matches current index show edit form
     <span>
     <EditableContext.Consumer>
       {form => (
         <a
           onClick={() => this.save(form, data[i])}
           style={{ marginRight: 8 }}
         >
           Save
         </a>
   )}
   </EditableContext.Consumer>
     <Popconfirm title="Sure to cancel?" onConfirm={this.cancel}>
       <a>Cancel</a>
     </Popconfirm>
   </span>
  ):
  <Button 
   onClick={this.edit(i)} // set callback to enclose index
   ghost
   type="primary"
  >
    Edit
  </Button> }

Be sure to set the editIndex back to null when finished editing.

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

3 Comments

It didn't work, the output is when I click the edit button the input fields are not showing
@Euph I'm not familiar with your forLoop snippet way of rendering/constructing react components, but let's first check that the edit handler is correctly setting state to the index you want to edit. Can you try that?
It now works but for the Save and Cancel text only, So when I click the edit button what is happening is all Input fields are showing but the save and cancel text is now ok and showing depending on which row i clicked. The only problem is the input fields which are all showing when edit button was clicked
0

If you have a list of items, you have to keep editable state for each of them. In your code, there is only one editable state that controls every element. One way to do it: You can give an id to every element that is being iterated over. Then keep your state like this: { editable: <id here> } When you are reading your data, if the editable state matches the current element, then you show the edit form.

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.