0

I have a unique issue that--while I've seen similar questions and answers--none quite address my challenge.

Currently, I provide a "print" button that loads the print dialog on a browser based on an embedded and hidden iframe. This works just fine, but I don't want to slow down page loading by pulling in the iframe for a large PDF.

So, I want to load an iframe without the source, then write the proper source url if the user clicks the print icon, then reload the iframe, and finally, show the dialog box.

Unfortunately, the print dialog pops up before I can reload the iframe so loads a blank page in the dialog box. On subsequent clicks, the PDF is loaded and ready for print.

<a href='#' id='load_pdf' ><i class='fa fa-2 fa-print'></i></a>
<iframe id="iFramePdf" src="" style="display:none;"></iframe>

<script type="text/javascript">
  jQuery(document).ready(function() {
    $("#load_pdf").click(loadPDF);

    function loadPDF() {
      $('#iFramePdf').attr('src', "my.pdf");
      // Attempt to reload iframe
      $('#iFramePdf').load("my.pdf");
      sendPrint('iFramePdf')
    }

    function sendPrint(elementId) {
      var iframe = $(element_id)[0]; 
      iframe.contentWindow.focus(); 
      iframe.contentWindow.print();
    }

});
</script>    

I've tried the following various methods to reload:

// Attempt 1
$('#iFramePdf').attr('src', function () { return     
$(this).contents().get(0).location.href });

// Attempt 2
$('#iFramePdf').attr("src", $('#iFramePdf').attr("src"));
$('#iFramePdf').attr('src', function () { return $(this).contents().get(0).location.href });

// Attempt 3
$('#iFramePdf')[0].contentWindow.location.reload(true);

// Attempt 4
var getMyFrame = document.getElementById(elementId);
getMyFrame.contentWindow.location.reload(true);

I've even tried using jQuery's defer method, but had no luck with that (possibly because I'm lacking knowledge). If I could get any guidance, I'd appreciate it.

Dawn Green
  • 483
  • 4
  • 16
  • See http://stackoverflow.com/questions/23766086/detect-when-an-iframe-is-loaded – guest271314 Sep 03 '15 at 04:55
  • iFrame is a rather brutal solution. Typically, [CSS @media](https://developer.mozilla.org/en-US/docs/Web/CSS/@media) rules can be exploited to maintain a display format and a print format on the same page with very little effort. – Roamer-1888 Sep 03 '15 at 13:07
  • I tried the suggestions to no avail. I decided to add a hover method that loaded the iframe source first, and then have the click event handle the printing. While it wasn't the answer I was looking for, it provided a solution that works. – Dawn Green Sep 03 '15 at 15:24

2 Answers2

1

try to change this:

function loadPDF() {
  $('#iFramePdf').attr('src', "my.pdf");
  // Attempt to reload iframe
  $('#iFramePdf').load("my.pdf");
  sendPrint('iFramePdf')
}

to something like this:

function loadPDF() {
  $('#iFramePdf').attr('src', "my.pdf");
}

  $('#iFramePdf').load(function(){
  sendPrint('iFramePdf')
})

it should work

dFine
  • 21
  • 3
0

You can try .promise(). For obvious reasons I can't test it out, but I think 3 seconds should be adequate for the iframe to load. Be aware that this is as syntactically correct as I can get it without testing it out. Adjust the fadeIn(1800) and the delay(1200) accordingly.

HTML

<a href='#' id='load_pdf' ><i class='fa fa-2 fa-print'></i></a>
<p id="msg" style="display: none;">Printing Document...</p>
<div id="printPort" style="opacity: 0; width: 1px; height: 1px;"></div>

jQuery

   $(function() {

        $("#load_pdf").on('click', loadPDF('my.pdf'));

        // Create the iframe, and put it inside #printPort
        // Change it's src to the file argument
        // Animate the #msg for 3 seconds

        var loadPDF = function(file) {
          $('<iframe id="iFramePdf" src="blank.html"></iframe>').appendTo("#printPort");
          $("#iFramePdf").att('src', file);
          return $('#msg').fadeIn(1800).delay(1200).fadeOut();
        }

        var sendPrint = function(elementId) {
          var iframe = $(element_id)[0]; 
          iframe.contentWindow.focus(); 
          iframe.contentWindow.print();
        }

        // Once the animation is done the promise will resolve and sendPrint will execute on callback.

        $.when(loadPDF).done(sendPrint('iFramePdf'));
    });
zer00ne
  • 41,936
  • 6
  • 41
  • 68