Cory
Cory

Reputation: 929

Calling components function from iframe

I have an iframe in my window and I added new buttons to it with jquery. Before migrating to angular2, i was using parent.SampleFunction() to call parent's functions from iframe. Now parent is an angular component and it does not work.

export class AppComponent {

 // use jquery to find the iframe and put a button into it
 addButtonToIFrame() {
     ...
     let buttonHtml = "<button onClick='parent.SampleFunction()'></button>"
     ...
 }

 SampleFunction() {
  ...
 } 

}

How should I change onclick function to access parent?

Upvotes: 10

Views: 7472

Answers (1)

n00dl3
n00dl3

Reputation: 21564

Same Origin Iframe

You can safely access the window.parent object, so you just need to put your SampleFunction in the global window object.

export class AppComponent {

 constructor(){
  (<any>window).SampleFunction= this.SampleFunction.bind(this);
 }

 // use jquery to find the iframe and put a button into it
 addButtonToIFrame() {
     ...
     let buttonHtml = "<button onClick='parent.SampleFunction()'></button>"
     ...
 }

 SampleFunction() {
  ...
 }
} 

If you have multiple instances of same class and your SampleFunction deals with the component state, you might need to create random name for your SampleFunction.

You could also use the PostMessage API which should be a more flexible alternative.

PostMessage API

If you are dealing with iframe from another domain, you can use the PostMessage API :

script inside iframe

window.parent.postMessage({foo:"foo"});

component inside parent

export class AppComponent {

 @HostListener("window:message",["$event"])
 SampleFunction($event:MessageEvent) {
  if (event.origin !== "protocol://my-expected-domain.tdl:port")
    return;
  console.log($event.data)// {foo:"foo"}
 }

} 

Of course you have to check the event.origin against the actual domain of the iframe.

Upvotes: 13

Related Questions