0

I would like to display the modal window with more details when I click on record. I'm using OfficeUI.

My parent component:

public render() {
    {
        return (
            <div>
                {this.props.items
                    .map((item: IListItem, i: number): JSX.Element => <ul className="list-group">
                        <li className="list-group-item">
                            <div className={styles.text}>
                                <p>{item.Id}</p>
                            </div>
                            <DefaultButton onClick={this.showModalEvent} text="Open Modal" />
                            {this.state.showPopup
                                ? <ModalPopUpItem item={item} 
                                        showModalState={this.state.showPopup}
                                        showModal={this.showModalEvent}/> : null
                            }
                        </li>
                    </ul>)}
            </div>
        );
    }



    private showModalEvent = (): void => {
    this.setState({ showPopup: !this.state.showPopup });
}

My child:

export class ModalPopUpItem extends React.Component<IModalProps> {
    public render() {
        return (
            <Modal
                isOpen={this.props.showModalState}
                onDismiss={this.props.showModal}
                isBlocking={false}
                containerClassName="ms-modalExample-container">
                <div className="ms-modalExample-header">
                    <span>{this.props.item.date}</span>
                </div>
            </Modal>
        );
    }
}

When I click my DeafultButton on parent component it invokes and displays Modal for every item, how can I limit this to only one current clicked item. I tried with i: number, but I couldn't figure it out.

J Oderberg
  • 75
  • 2
  • 6

2 Answers2

0

Your parent component only has one flag to store the showPopup. This means that when you click on one of your buttons you set this flag for the whole parent component and that means that the whole list of your child components is evaluated and this.state.showPopup will be true.

You need to find a way to limit the effect of clicking the button to the item the button was clicked on.

You could, for example, not set the showPopup flag on the parent component, but on the item.

This could work, but you would have to revisit the way you include the ModalPopUpItem.

private showModalEvent = (item): void => {
    item.showPopup = !item.showPopup;
}
lyio
  • 1,237
  • 12
  • 13
0

Since you are using single state for every child, so once you change this.state.showPopup to true, every modal will showed up. So you might can change the showModalEvent method.

private showModalEvent = (id: number): void => {
    this.setState({ showPopupId: id });

and the render will be look like

return (
  <div>
    {this.props.items
      .map((item: IListItem, i: number): JSX.Element => <ul className="list-group">
        <li className="list-group-item">
          <div className={styles.text}>
            <p>{item.Id}</p>
          </div>
          <DefaultButton onClick={() => this.showModalEvent(item.Id)} text="Open Modal" />
          {this.state.showPopupId === item.Id
            ? <ModalPopUpItem item={item}
              showModalState={this.state.showPopup}
              showModal={this.showModalEvent} /> : null
          }
        </li>
      </ul>)}
  </div>
);

Since this method only store one id at a time, this mean only one modal will showed up. If you want to show more modal at the time, you could change it to array or something.

Bukhari
  • 492
  • 3
  • 15