19

I have a page with a list of links and a div which serves as a placeholder for the pages the links lead to. Everytime user clicks on a link an iframe is created in the div and its src attribute gets the value of the link href attribute - simple and clear, sort of external web pages gallery. What i do have a problem with is printing the contents of the iframe. To do this i use this code:

function PrintIframe()  
{  
frames["name"].focus();  
frames["name"].print();  
}

The issue seems to be that iframe is created dynamically by JQuery - when I insert an iframe right into the html code, the browser prints the external page all right. But with the same code injected by JavaScript nothing happens. I tried to use JQ 1.3 'live' event on "Print" link, no success. Is there a way to overcome this?

certainlyakey
  • 492
  • 1
  • 6
  • 13

9 Answers9

37

Suppose that this is what your iframe looks like:

<iframe id='print-iframe' name='print-frame-name'></iframe>

This is how you do it using jQuery:

$("#print-iframe").get(0).contentWindow.print();

and this is how you do it using native JavaScript:

document.getElementById("print-iframe").contentWindow.print();
rybo111
  • 12,240
  • 4
  • 61
  • 70
Fareed Alnamrouti
  • 30,771
  • 4
  • 85
  • 76
9

I've had an issue with printing iframe's content. In order to achive this, use code below:

For example you have iframe:

<iframe id='print-iframe' name='print-iframe'></iframe>

Then js to print iframe's content call this function (works both in ie and other browsers):

printIframe('print-iframe');

Function's code:

function printIframe(iFrameId) {
    var ua = window.navigator.userAgent;
    var msie = ua.indexOf ("MSIE ");
    var iframe = document.getElementById(printFrameId);

    if (msie !== 0) {
        iframe.contentWindow.document.execCommand('print', false, null);
    } else {
        iframe.contentWindow.print();
    }
}
cchamberlain
  • 17,444
  • 7
  • 59
  • 72
Yuri
  • 1,748
  • 2
  • 23
  • 26
  • This seems to work fine. However, I think it's better to check for (msie>-1). – Valdez V. Nov 29 '13 at 19:15
  • This is simple check only :) The source is: http://support.microsoft.com/kb/167820 – Yuri Dec 15 '13 at 11:54
  • It works for only once. If I click the button again i get a " JavaScript runtime error: Access is denied.". I'm trying to silently print a pdf document. I have a table with with multiple entries and each entry can be "printed". When the entry's print button is clicked, the iframe's src is updated with the new url and the above code is executed to silently print it. Like I said, it works once but subsequent clicks, it fails with the above javascript error. – Paul Jan 28 '18 at 21:52
9

I tried this and was able to replicate the issue. What i noticed was that when calling the print function the iframe hadn't completed loaded. i tested this by checking the value of innerHTML when calling PrintIFrame(). To overcome this, you can use setTimeOut to call the function again x milliseconds later:

function PrintIframe() { 

        if (window.frames['myname'].innerHTML != "") {
            window.frames['myname'].focus();
            window.frames['myname'].print();
        } else {
            setTimeout(PrintIframe,1000);
        }    
    }

This worked for me

EDIT Strange - i had an alert in my test code which seems to make it work. When i took it out, it didn't work. Sorry :(

Anyway, this should do it using jQuery to attach a load event handler to the iframe. I have tested on IE8 and it works:

<html>
<head>
    <script language="javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
    <script type="text/javascript">
    function loadiFrame(src)
    {
        $("#iframeplaceholder").html("<iframe id='myiframe' name='myname' src='" + src + "' />");
    }

    $(function()
    {
        $("#printbutton").bind("click", 
            function() { 
                loadiFrame('test.aspx'); 
                $("#myiframe").load( 
                    function() {
                        window.frames['myname'].focus();
                        window.frames['myname'].print();
                    }
                 );
            }
        );
    });
    </script>    
</head>
<body>
    <input type="button" id="printbutton" value="Load iFrame" />
    <div id="iframeplaceholder"></div>
</body>
</html>
Temple
  • 1,079
  • 1
  • 10
  • 22
0
var ifrm = document.createElement("iframe");
// ifrm.style.display = "none";
document.body.appendChild(ifrm);
setTimeout(function() {
    $(ifrm).contents().find("body").html("my html content");
}, 1);
ifrm.onload = function() {
    ifrm.contentWindow.print();
}
Igor Parra
  • 10,214
  • 10
  • 69
  • 101
0

I found this searching the web

$('#preview-iframe').contents().find('html').html(data); 

and changed it to

$('#preview-iframe').contents().find('html').html(data).after(function() {
    document.getElementById("preview-iframe").contentWindow.print();
});

twigstechtips

mbauer
  • 348
  • 1
  • 6
  • 25
blomman9
  • 1,594
  • 2
  • 9
  • 7
0

I know this is a pretty old thread but I have a more rubust solution for this.

It's based on https://stackoverflow.com/a/9648159/3183069 and https://stackoverflow.com/a/831547/3183069

I added .one() function so it doesnt loop infinitely if you cancel the print! I also load the iframe once. Enjoy

var $body = $("body"),
  $iframe,
  loadiFrame = function(src) {
    if ($body.children('#full-prog').length == 0) {
      $body.append("<iframe id='full-prog' src='" + src + "' />");
      $iframe = $("#full-prog");
      $iframe.one('load', function() {
        $iframe.get(0).contentWindow.print();
      });
    } else {
      $iframe.get(0).contentWindow.print();
    }
  };

$("#printbutton").click(function() {
  loadiFrame('iframe source here');
});
#full-prog {
  overflow: hidden;
  position: absolute;
  width: 0;
  height: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" id="printbutton" value="Load iFrame" />
JFC
  • 575
  • 11
  • 25
0

This is a pretty old thread but I found one working solution for this.

I added sleep in jquery so it doesn't print empty window, it requires few second to reload the newly replaced content.

$('#printiframe').attr('src', pdf_file_path);
setTimeout(function () {
     $("#printiframe").get(0).contentWindow.print();
}, 500);
Amit Gupta
  • 91
  • 1
  • 2
0

Hmm do I get this right? You only need to change the source of where the IFrame leads to?

$("#iframe").attr("src", "http://www.example.com");
Ólafur Waage
  • 68,817
  • 22
  • 142
  • 198
  • no, the problem is that i cannot print the page in the iframe - there're 2 options: 1) it's possible to print it like a part of the page (with PrintArea plugin) - but then it prints only one page and the content of the iframed page is not formatted on the paper as it should be. 2)it's possible to print it as a normal page but ONLY if iframe tag is not inserted dynamically, via JS but statically presents in HTML. – certainlyakey May 06 '09 at 19:28
0

Maybe the same-domain restriction prevents your JavaScript from executing. The same-domain restriction allows JavaScript in frame A (or the main window) to interact (such as .print()) with frame B if A and B are from the same domain. Check your JavaScript error console. If you get something like a security exception / permission error, then it is most probably because of the same-domain restriction.

pts
  • 80,836
  • 20
  • 110
  • 183