tetar
tetar

Reputation: 872

multiple modal in .map

i am in a .map an i want to creat on modal in each div generate by the .map

 return ( 
 {this.state.DataBook.map(function (item, i) {
     return ( <div>
          <Button color="danger" onClick={this.toggleModal}>test Modal</Button>
           <Modal isOpen={this.state.modal} toggle={this.toggleModal} className={this.props.className} external={externalCloseBtn}>
             <ModalHeader>Modal title</ModalHeader>
               <ModalBody>
                  <b>{item.nom}</b><br />
                     Lorem ipsum 
                </ModalBody>
               <ModalFooter>
         <Button color="primary" onClick={this.toggleModal}>Do Something</Button>{' '}
               </ModalFooter>
             </Modal>
           </div>)},this)}

In order to do that i call toggleModal

 toggleModal() {
    this.setState({
        modal: !this.state.modal
    });
}

with this i have all my modal with the same content i don't know how to fix it. Any idea?

Upvotes: 1

Views: 1210

Answers (2)

Dev
Dev

Reputation: 3932

You can have activeModalIndex in your state which can be used to show the actual modal. Check the activeModalIndex when you open your modal.

this.state.DataBook.map(function (item, index) {
 return ( 
   <div>
      <Button color="danger" onClick={() => this.toggleModal(index)}>test Modal</Button>
      <Modal isOpen={(this.state.activeModalIndex === index) && this.state.modal} toggle={()=> this.toggleModal(index)} className={this.props.className} external={externalCloseBtn}>
      ...
      </Modal>
   </div>

You can toggle modal

toggleModal(activeIndex) {
  this.setState({
    modal: !this.state.modal,
    activeModalIndex: activeIndex
  });
}

Hope this helps.

Upvotes: 0

Dyo
Dyo

Reputation: 4464

Here's a working codeSandbox running this : https://codesandbox.io/s/rmxp8nxm74

To be able to individually identify events coming from JSX made by mapping an array, you have to pass an identifier to the called openModal method :

  openModal = id => {
    this.setState({ openedModal: id });
  };
  closeModal = () => {
    this.setState({ openedModal: null });
  };

  render() {
    return this.state.DataBook.map((item, i) => (
      <div key={item.id}>
        <Button color="danger" onClick={() => this.openModal(item.id)}>
          test Modal
        </Button>
        <Modal
          isOpen={this.state.openedModal === item.id}
          toggle={this.closeModal}
        >
          <ModalHeader>Modal title</ModalHeader>
          <ModalBody>
            <b>{item.nom}</b>
            <br />
            Lorem ipsum
          </ModalBody>
          <ModalFooter>
            <Button color="primary" onClick={this.closeModal}>
              Do Something
            </Button>
          </ModalFooter>
        </Modal>
      </div>
    ));
  }

Edit : I created distinct open/close methods so you'll be able to easily close the active modal with an external call (no param to pass).

Edit 2 : You have also an alternative option : having a single dynamic Modal passing it a state set onClick (could be better in performance but harder to manage different click events in modal)

Upvotes: 3

Related Questions