7

Our website has a feature whereby a member profile can be printed. The way that it works is that a javascript function is attached to a button via an onsubmit. The javascript function uses a window.open to reopen the page in a special mode, which redisplays a printer-friendly version of the page.

This functionality has been in place since about 2008, and works in all browsers. Except about a week or so ago it has stopped working in Chrome. With Chrome, what happens is that the opened window does open, but then another blank window briefly opens, and then the all of them close.

In searching for discussion of this issue I was unable to find the exact issue, but did find something that said that a "return false" should be added to the onsubmit. I tried adding that but it did not help.

Here is what the onsubmit looks like:

<button onclick="PrintEmailSubmit('print');">Print Profile</button>

Here is what the code that opens the window looks like:

window.open('print-email-profile.php?mode=' + mode,'','width=' + width + ',height=' + height + ',scrollbars=yes,location=0,menubar=1,status=0,toolbar=0')

While it should not be necessary to see, here is the entire function PrintEmailSubmit():

/*
 *  called by view-profile.php
 */
function PrintEmailSubmit(mode)
{
    var width;
    var height;
    switch(mode)
    {
        case 'print':
            width = 850;
            height = 1000;
            break;

        case 'email':
            width = 400;
            height = 120;
            break;

        default:
            alert('Error: invalid calling sequence -- should not happen!');
            exit;
    }
    window.open('print-email-profile.php?mode=' + mode,'','width=' + width + ',height=' + height + ',scrollbars=yes,location=0,menubar=1,status=0,toolbar=0');
}

And finally, what makes this work is that the special version of the page has the following added to the body tag:

<body onload="window.print();window.close();">

As stated above, the function continues to work in IE and Firefox. Just Chrome is having this issue.

Any ideas?

Jeffrey Simon
  • 918
  • 3
  • 11
  • 25
  • Could it be Chrome's pop up blocker that is blocking it? You should get a notification then, does the console say any errors? – Badr Hari Aug 14 '13 at 18:59
  • If it's not too long, please include the JS for PrintEmailSubmit – Diodeus - James MacFarlane Aug 14 '13 at 18:59
  • Does it work without window.close? If does, then set timeout for closing window or use button instead. – Badr Hari Aug 14 '13 at 19:46
  • 1
    Badr Hari: The odd thing is that it has worked fine for 6 years in all browsers, but now just does not work for Chrome. Taking out the window.close from the body onload does in fact allow the print function to work for Chrome, but then it leaves the print-friendly window open. So this points in the direction of a solution. I would just have to get the the window.close to be there, yet not triggered prematurely – Jeffrey Simon Aug 16 '13 at 22:04
  • Diodeus: I did not present it because it would not be too helpful. But since you asked, I will add it to the original question. – Jeffrey Simon Aug 16 '13 at 22:05

6 Answers6

8

The button and the window.open really have nothing to do with your problem.

The problem is, Chrome is looking for user input before it prints. Window.print() opens the print dialog window, but Chrome isn't waiting for you to finish printing. The window.close() is closing the print dialog window and everything else in the parent.

In an effort to save you time, be aware that the OnAfterPrint hook isn't used by Chrome at all. I also tried putting window.close() in the onLoad and window.print() in the onBeforeUnload, but the print dialog cancels the window.close(). The next best thing would be to do something like:

//In your profile print page
<html>
<head>
<script>
var is_chrome = function () { return Boolean(window.chrome); }
if(is_chrome) 
{
   window.print();
   setTimeout(function(){window.close();}, 10000); 
   //give them 10 seconds to print, then close
}
else
{
   window.print();
   window.close();
}
</script>

<body onLoad="loadHandler();">

I haven't tested this, but I think it demonstrates the idea fairly effectively.

Lumberjack
  • 488
  • 4
  • 13
  • I am adding an additional part to the original description which is an important part of the problem regarding the special version of the page also having – Jeffrey Simon Aug 14 '13 at 19:14
  • From your description, it sounds like everything is working but the window.print(); I'll test that locally as well. – Lumberjack Aug 14 '13 at 19:23
  • I think your revised answer probably is taking the right approach, although I have not tried it yet either. But the idea of adding the setTimeout for Chrome seems like it could work. Again -- I am wondering why this has worked for 6 years without the setTimeout. Has something changed in Chrome in the last week? – Jeffrey Simon Aug 16 '13 at 22:10
  • I am getting it to work, but there are strange results. For architectural reasons, rather than the script as you have suggested, I wrapped the javascript inside a function printLoadHandler, the call that function in the . It seems to work, with the following oddity: the 10 second timeout starts running after the user completes the printing. Before that, it does not matter how long the user waits; the dialog just remains open. So the 10 seconds can be arbitrarily reduced. – Jeffrey Simon Aug 16 '13 at 23:03
  • 2
    Next, why not just put in a window.close without the setTimeout? However, that does not work. The setTimeout has to be there, but can be very short. I have 200 now, or .2 of a second, and it works fine. That is, it allows the function to work for Chrome as it did in the past, the print dialog just waits indefintitely for the user input, and there is no delay to close the window. I don't understand it, but it works. In fact, the same code works on other browsers too, allowing a very simplified final form. Just adding the setTimeout to the original code seems to sufficient to fix the problem. – Jeffrey Simon Aug 16 '13 at 23:04
  • 3
    Final solution: use the following in place of the original body onload: – Jeffrey Simon Aug 16 '13 at 23:06
  • 1
    I had a similar problem calling window.print() then setting location.href to a new page. The print window never appeared (it seemed). This answer solved my problem. Thanks very much, Lumberjack! – rogdawg Apr 15 '14 at 13:47
  • 1
    To be totally correct you have to put both print() and close() into a settimeout function like so: setTimeout(function(){window.print(); window.close();}, 200); This way worked for me. – Otvazhnii May 15 '17 at 08:51
  • 1
    @JeffreySimon you are right, i had have also the same problem.. the timeout doesn't needs to be long, in matter of fact with zero (0) works! It seems that while the print dialog is active there is no possibility to execute javascript on the parent window of that dialog. Really really weird this... but anyway thanks you all for the solution! – Victor Nov 14 '19 at 18:35
2

I found this solution and it really works:

<body onload="window.print();window.onmouseover = function() { self.close(); } ">
Mari
  • 208
  • 2
  • 7
2

I use Mr.bresleveloper solution with some changes:

var is_chrome = Boolean(window.chrome);
if (is_chrome) {
    winPrint.onload = function () {
        setTimeout(function () { // wait until all resources loaded 
            winPrint.print();  // change window to winPrint
            winPrint.close();// change window to winPrint
        }, 200);
    };
}
else {
    winPrint.print();
    winPrint.close();
}
Alaa.Kh
  • 151
  • 3
1

The Chrome is so fast that it actually call the print before the document is loaded. That's why the best thing to do is just moving the print function to onload, either like Mari or like this:

winPrint = window.open("", "winPrint", "width=1,height=1");
winPrint.document.write(html);
winPrint.onload = function () {
    window.print();
    window.close();
};

And o.c. it's not working in IE so full code should look like this

var is_chrome = Boolean(window.chrome);
if (is_chrome) {
    winPrint.onload = function () {
        window.print();
        window.close();
    };
}
else {
    winPrint.print();
    winPrint.close();
}
Entwickler
  • 255
  • 2
  • 12
bresleveloper
  • 5,940
  • 3
  • 33
  • 47
1
//In your profile print page
<html>
<head>
<script>
var is_chrome = function () { return Boolean(window.chrome); }
if(is_chrome) 
{
   window.print();
   setTimeout(function(){window.close();}, 10000); 
   //give them 10 seconds to print, then close
}
else
{
   window.print();
   window.close();
}
</script>

<body onLoad="loadHandler();">

This works fine.

Thanks.

1

I also get the same problem with this methods

   window.print();
   window.close();

even recognizing the browser and then executing the code accordingly is good. But this is a very handy and short cut solution to fix this issue only by two line.

   document.execCommand('print');
   window.close();

working perfectly fine in chrome and IE

Yasen
  • 4,241
  • 1
  • 16
  • 25
Jimmy
  • 995
  • 9
  • 18
  • Welcome to SO! When you post a reply to a question and there are a few more, try to expose the benefits of yours. In this case, there are a few similar ones... – David García Bodego Dec 23 '19 at 07:32