1

I am trying to use a bootstrap popup component as nested component multiple times on a single page. This popup component takes different values as @Input(). The problem is that every popup on the page has the same values as the last popup. So, how can I get multiple instances of the same nested component?

Here is the parent component:

@Component({
  selector: 'my-parent',
  templateUrl: 'app/components/parent/parent.component.html',
  directives: [PopupDirective]
})
export class ParentComponent {
    private doSomething() {
        // do something
    }
}

This is the html of my parent component:

<button class="btn btn-success"
        (click)="popup1.show()">Call Popup 1</button>

<button class="btn btn-success"
        (click)="popup2.show()">Call Popup 2</button>

<my-popup #popup1
          [id]="1"
          [title]="Popup 1"
          [body]="This is my test popup 1"
          (confirmation)="doSomething()"></my-popup>

<my-popup #popup2
          [id]="2"
          [title]="Popup 2"
          [body]="This is my test popup 2"
          (confirmation)="doSomething()"></my-popup>

Here is the popup component:

@Component({
  selector: 'my-popup',
  templateUrl: 'app/directives/popup/popup.directive.html'
})
export class PopupDirective {

    @Input() id: string;

    @Input() title: string;
    @Input() body: any;

    @Output() confirmation: EventEmitter<string> = new EventEmitter<string>();

    private triggerPopup: string;

    constructor() {
        this.triggerPopup = "triggerPopup";
    }

    confirm() {
        this.confirmation.emit('Click from nested component');
    }


    show() {
        document.getElementById(this.triggerPopup).click();
    }
}

And finally the html code of my popup

<a id="{{ triggerPopup }}"
   href="#popup{{ id }}"
   data-toggle="modal"
   [hidden]="true"></a>

<div class="modal fade" id="popup{{ id }}" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h4>{{ title }}</h4>
            </div>
            <div class="modal-body">
                <div>{{ body }}</div>
                <div style="clear: both;"></div>
            </div>
            <div class="modal-footer">
                <a  class="bin ban-default"
                    data-dismiss="modal">
                    Close</a>

                <a  class="bin ban-success"
                    data-dismiss="modal"
                    (click)="confirm()">
                    Confirm</a>
            </div>
        </div>
    </div>
</div>

1 Answer 1

1

You are assigning the same id to each element

constructor() {
    this.triggerPopup = "triggerPopup";
}

and therefore

document.getElementById(this.triggerPopup).click();

always finds the first one because it searches the whole page and doesn't care about component boundaries.

I'd suggest to use template variables and @ViewChild() instead

<a #triggerPopup"
export class PopupDirective {
  @ViewChild('triggerPopup') triggerPopup:ElementRef;

  show() {
    this.triggerPopup.nativeElement.click();
  }
Sign up to request clarification or add additional context in comments.

2 Comments

Okay, thats logical. But it does not fix it at all. I recognized that also href="#popup{{ id }}" always will be just #popup. I could do the same as in your answer above but then how can I trigger the popup through the bootstrap framework? I can't just do href="#popup{{ id }}" because the url would be something like /#popup [Object].
I'd suggest to use a different input property name than id. id is a property of Element.

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.