57

I have this iframe working with basic JavaScript:

<iframe id="upload_iframe" name="upload_iframe" onLoad="uploadDone();"></iframe>

Which triggers the method uploadDone(); when the content of the iframe has been loaded.

How do I do the same thing in Angular?. I want to call a function on the controller when the iframe loads, but I haven't seen a ng-onload so far.

Daniel
  • 21,933
  • 14
  • 72
  • 101
Jerome Ansia
  • 6,854
  • 11
  • 53
  • 99

5 Answers5

121

Commenting on a year old question. For cases where there are more than 1 iframes, I needed to bind "onload" events on to. I did this approach.

Directive

APP.directive('iframeOnload', [function(){
return {
    scope: {
        callBack: '&iframeOnload'
    },
    link: function(scope, element, attrs){
        element.on('load', function(){
            return scope.callBack();
        })
    }
}}])

Controller

APP.controller('MyController', ['$scope', function($scope){

    $scope.iframeLoadedCallBack = function(){
        // do stuff
    }
}]);

DOM

<div ng-controller="MyController">
    <iframe iframe-onload="iframeLoadedCallBack()" src="..."></iframe>
</div>
34

For anyone using Angular 2+, It's simply:

<iframe (load)="uploadDone()"></iframe>

No global function, works with multiple iframe.

Haijin
  • 2,561
  • 2
  • 17
  • 30
29

try defining the function within controller as:

window.uploadDone=function(){
  /* have access to $scope here*/
}
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • 1
    is there an option to pass angular params as well? such as `code`
    – Leon Jul 02 '13 at 09:10
  • 4
    The downside to this is that it mixes a global function with Angular code. It works, but it could be confusing. Eg. "Would someone else reading the code expect to find it in the controller? Will it conflict with anything else?" – Adam Zerner Nov 26 '14 at 21:16
4

For anyone ending up here, the ng-onload plugin is the perfect solution to this issue. It doesn't pollute the global namespace and doesn't require you to create one-off directives when all you want is to call a simple scope function.

fisch2
  • 2,574
  • 2
  • 26
  • 29
  • ngOnload only appears to return undefined with respect to the contentWindow for Angular 1.5.x. Have you used it on this version of AngularJS and had it work? – mtpultz Jul 26 '16 at 21:41
1

for those that inject the iframe dynamically, you could do the following

html...

<div #iframeContainer></div>

ts...

@Component({
  selector: 'app-iframe-onload',
  templateUrl: './iframe-onload.component.html'
})
export class IframeOnload implements AfterViewInit {

@ViewChild('iframeContainer') iframeContainer: ElementRef;

ngAfterViewInit(): void {
  this.injectIframe();
}

private injectIframe(): void {
  const container = this.iframeContainer.nativeElement;
  const iframe = document.createElement('iframe');
  iframe.setAttribute('width', '100%');
  iframe.setAttribute('src', 'https://example.com/');
  iframe.setAttribute('height', 'auto');
  iframe.setAttribute('frameBorder', '0');
  iframe.addEventListener('load', this.iframeOnLoadtwo);
  container.appendChild(iframe);

}

public iframeOnLoadtwo(): void {
  console.log('iframe loaded...');
}

}

Craig Wayne
  • 4,499
  • 4
  • 35
  • 50