1

Need your help with regards to enabling button when click INSIDE .map

Here's the data from backend:

file :[ { id: 1 color: orange, shape: triangle
} { id: 2 color: blue, shape: circle
} { id: 3 color: red, shape: rectangle
} ]

And this is the file rendered in .map way:

{file.map(file => (
  `<div>
      <a
        onClick={() => this.downloadFile(file)}
        href="javascript:void(0);"
      >
        {file.fileName}
      </a>

</div>

        <Button
          onClick={() => this.submit()}
          disabled={should be enabled when click}
        >
          submit
      </Button>

))}

In UI, it looks like this:

LINK--------------Button (this is disabled)
LINK--------------Button (this is disabled)
LINK--------------Button (this is disabled)

What i need is a function that when i click the first LINK, it only enable the first button beside it, what i have now is when i click the first LINK, it enables all the button

Please help. Thanks

1
  • Please fix your formatting Commented Sep 15, 2020 at 8:09

3 Answers 3

1

Add an active button index to your state

this.state = {
  // ... any other state
  activeButtonIndex: null,
};

When a button is clicked set the activeButtonIndex to the mapped index of the button. Also use the activeButtonIndex to compare against the current mapping index and disable the button when they match.

{file.map((file, index) => (
  <div>
    <a
      onClick={() => this.downloadFile(file)}
      href="javascript:void(0);"
    >
      {file.fileName}
    </a>
    <Button
      onClick={() => {
        this.submit();
        this.setState({ activeButtonIndex: index }); // <-- set active index
      }}
      disabled={index === this.state.activeButtonIndex} // <-- check active index
    >
      submit
    </Button>
  </div> 
))}

Edit to allow multiple active

Add an active button index object to your state

this.state = {
  // ... any other state
  activeButtonIndex: {},
};

When a button is clicked add the mapped index to the activeButtonIndex object. Also use the activeButtonIndex object to compare against the current mapping index and disable the button when that index is in the activeButtonIndex object.

{file.map((file, index) => (
  <div>
    <a
      onClick={() => this.downloadFile(file)}
      href="javascript:void(0);"
    >
      {file.fileName}
    </a>
    <Button
      onClick={() => {
        this.submit();
        this.setState(prevState => ({
          activeButtonIndex: {
            ...prevState.activeButtonIndex, // <-- copy existing state
            [index]: true, // <-- set active index
          },
        }));
      }}
      disabled={this.state.activeButtonIndex[index]} // <-- check active index
    >
      submit
    </Button>
  </div> 
))}
Sign up to request clarification or add additional context in comments.

6 Comments

Close! it enables the first LINK. but when you click the seconde LINK, the first LINK is disabled again.
@ZachDLR So you want these buttons to essentially be toggles? or just allow more than 1 active at a time?
yes, when i click the first LINK, it only enables the first, and for the second LINK, the second button, but the first button should be enabled as well since we already click the first one. thanks
@ZachDLR Use a map/object to store active indices. I updated my answer with changes.
thanks Drew, working now, just that, i put the "this.setState(prevState => ({" from Button to <a> tag, that's what i needed. thanks
|
0

You should store the state when the first link is clicked. It can be stored in localStorage or cookie. Then you'll have to retrieve it in your component.

Or, if your link is not redirecting users to another page, then you can simply store the state in your component. For example,

this.state = {
  isClicked = true
}

2 Comments

Already used that, the problem is all of the three buttons go enable,
Tried disabled={this.state.isClicked}?
0

Hopefully you are storing your loaded data in state. You should need an individual toggle for each button

state = {
    data : []
}
this.apiCallToGetData().then(res => {
    //set all buttons to disabled by default
   res.map(r => {r.disabled = true;})
  this.setState({data: res})
});

In your HTML, make the disabled property dynamic and pass the index to the downloadFile function:

{file.map((file, index) => (
  <div>
    <a
      onClick={() => this.downloadFile(file, index)}
      href="javascript:void(0);"
    >
      {file.fileName}
    </a>
    <Button
        onClick={() => this.submit()}
        disabled={file.disabled}
      >
              submit
     </Button>
  </div> 
))}

And finally, modify the downloadFile function to update the button's disabled state on click

downloadFile = (file, index) => {
 let freshFiles = this.state.data;
 freshFiles[index].disabled = false;
 this.setState({data : freshFiles});

   //the rest of your code
}

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.