2

I'm using this code, which has stemmed from here and here.

$('#my_button').on('click', function (e) {
    var iframe = document.createElement('iframe');
    iframe.id = "my_iframe";
    iframe.onload = function() {
        var doc = iframe.contentDocument || iframe.contentWindow.document;
        doc.getElementsByTagName('body')[0].innerHTML = "<p>test123</p>";

        iframe.contentWindow.focus(); 
        iframe.contentWindow.print();

        $("#my_iframe", top.document).remove();
    };

    document.getElementsByTagName('body')[0].appendChild(iframe);
});

Without the remove line, it prints fine. However, the remove line removes the iframe before it has a chance to execute the print(). How can I set up some kind of callback so that it prints and only then removes the iframe?

Thanks.

Community
  • 1
  • 1
Nick
  • 5,995
  • 12
  • 54
  • 78

2 Answers2

5

I found this solution when I was searching for print event detection:

http://tjvantoll.com/2012/06/15/detecting-print-requests-with-javascript/

Here I add the JS code as requested by Stano, but it is important to also read the whole linked post as there are limitations to this approach. In general the post is about the onafterprint event that only works in IE and a solution to make that event work in other browsers.

(function() {
    var beforePrint = function() {
        console.log('Functionality to run before printing.');
    };
    var afterPrint = function() {
        console.log('Functionality to run after printing');
    };

    if (window.matchMedia) {
        var mediaQueryList = window.matchMedia('print');
        mediaQueryList.addListener(function(mql) {
            if (mql.matches) {
                beforePrint();
            } else {
                afterPrint();
            }
        });
    }

    window.onbeforeprint = beforePrint;
    window.onafterprint = afterPrint;
}());
m7o
  • 901
  • 5
  • 7
2

create a function like this:

function printIframe(iframe,callback) {
  iframe.contentWindow.print();
  if (callback && typeof(callback) === "function") {
    // execute the callback, passing parameters as necessary
    callback();
  }
}

and call it instead of the other two functions like this. printIframe(iframe,function(){ $("#my_iframe", top.document).remove();})

if you like you can also put in a delay using the setTimeout.

setTimeout(function() {alert('hello');},1250);
Pablo Jomer
  • 9,870
  • 11
  • 54
  • 102
  • This is nice for a callback and I've +1, but it doesn't actually check to see that the print has finished. You just have to trust that it's done by the time the delay finishes (which it probably will be, admittedly). – Nick Aug 15 '12 at 12:11
  • yes that is true Nick. Combined with m7os solution you could get a better solution. – Pablo Jomer Aug 15 '12 at 12:15
  • I've noticed, however, that at least one of the jQuery plugins uses your setTimeout method to get rid of the iframe, so you're in good company :) – Nick Aug 15 '12 at 22:47
  • Thats a little sad. but as a consequence of this thread atleast I learned event handling. Thanks :D – Pablo Jomer Aug 16 '12 at 08:12
  • Sorry for the sadness. I added +1 to a couple of your other answers :) – Nick Aug 16 '12 at 09:54