printThis icon indicating copy to clipboard operation
printThis copied to clipboard

Print issue on iPad in Google Chrome and Firefox (Safari works)

Open patrickhrastnik opened this issue 6 years ago • 29 comments

Description of issue:

When the button meant to start a print dialog is clicked, neither Chrome nor Firefox open a print dialog on an iPad. Tested with iPad 3G, iPad Air 2 and iPad Pro Safari opens the dedicated print dialog, so the function basically works. All browsers execute window.print correctly

====================================================================

Code & options:

// TypeScript logic

// detect container id
var printContainerId: string = $j(event.target).data("ho-printthis-containerid");

// print container with id
($j(event.target).parents(printContainerId) as any).printThis({
    debug: true,
    importCSS: true,
    importStyle: false,
    printContainer: false,
    removeInline: true
});

patrickhrastnik avatar May 11 '18 08:05 patrickhrastnik

When debug is set to true the print won't execute. This option is for debugging only.

jasonday avatar May 11 '18 10:05 jasonday

I changed debug to false, and nothing changed. Safari on iPad opens the print dialog, Google Chrome on iPad doesn't.

patrickhrastnik avatar May 14 '18 05:05 patrickhrastnik

I also tested to print the desired container with DoersGuild/jQuery.print - same behavior. Safari opens the print dialog, Google Chrome doesn't. (on iPad Pro)

patrickhrastnik avatar May 16 '18 08:05 patrickhrastnik

I've researched this somewhat, and the answer isn't good.

Non-Safari browsers on iOS do not support the programmatic window.print() function.

You can test this with this basic JSFiddle: https://jsfiddle.net/_sir/jxr7uex6/

This appears to have always been the case.

These browsers would require a manual print action to be performed.

oculus42 avatar May 16 '18 09:05 oculus42

It's true - in your fiddle the window.print is not executed in Chrome on iPad. But in our website the window.print is executed properly - according to your information, I don't understand why this works in our application. I tried to make a fiddle that works on the iPad, but I wasn't able to.

patrickhrastnik avatar May 16 '18 09:05 patrickhrastnik

I made a test page with our framework bundle. It executes window.print, and that works in Chrome on iPad. I don't know why, but it works.

http://www.online.holter.at/ho/js/testprint.html

The script included in this test file was written in TypeScript and compiled to ES5 JavaScript with AMD module definitions, using RequireJS.

patrickhrastnik avatar May 16 '18 09:05 patrickhrastnik

I currently try to find the issue on my own, and here's how far I've come: I tried to perform a window.print instead of the custom logic in printThis.js line 239 - it performed without any doubts. So printing is possible.

document.queryCommandSupported("print") returns true, as well as queryCommandEnabled. That's why it executes line 247 execCommand("print"), but that obviously doesn't execute properly.

Working:

  • window.print
  • window.frames.print

Not working:

  • window.frames["printIframe"].print
  • window.frames[strFrameName].print
  • everything possible with $iframe (execCommand, contentWindow.print)

If you wanna try to use the return value of .execCommand("print") to determine if the print dialog was correctly opened: forget it. It even returns true when no print dialog shows up.

patrickhrastnik avatar May 18 '18 12:05 patrickhrastnik

Also interesting: window.document.execCommand("print") instead of window.print() doesn't work, but window.document.queryCommandSupported("print") returns true

patrickhrastnik avatar May 18 '18 12:05 patrickhrastnik

@patrickhrastnik that's not good news. In the interim/short-term, the ugly hack for MSIE would potentially work everywhere. We'll need to do some research on our side to determine the scale of this issue and figure out a viable approach. Thanks for your research.

jasonday avatar May 18 '18 12:05 jasonday

Spitballing: I wonder if a try/catch approach would work to step through the various methods of printing and trigger the correct one for browser, OS, etc. That said, the issue you presented window.document.queryCommandSupported("print") returning true may still present an issue.

jasonday avatar May 18 '18 12:05 jasonday

Interesting thread: https://stackoverflow.com/a/21336448/335514 for additional research

jasonday avatar May 18 '18 12:05 jasonday

@patrickhrastnik - take a look at this line from another printing plugin:

// Fix for IE11 - printng the whole page instead of the iframe content
if (!frameWindow.document.execCommand('print', false, null)) {
    // document.execCommand returns false if it failed -http://stackoverflow.com/a/21336448/937891
    frameWindow.print();
 }

If that works, that means we can change a few things around line 246.

This might work - worth testing, and then if it does, we can rework that entire section.

} else {
    // proper method
    if (!$iframe[0].contentWindow.document.execCommand("print", false, null);) {
        $iframe[0].print();
    } else {
        $iframe[0].contentWindow.focus();
        $iframe[0].contentWindow.print();
    }
}

jasonday avatar May 18 '18 20:05 jasonday

Thank you for the suggestion @jasonday Unfortunately I don't have access to my testing setup till Tuesday, but I'm gonna try this asap. The only thing I'm not sure about is, if .execCommand on the iframe.contentWindow.document will return false. When I tried this yesterday, it returned true, even though no print dialog was shown. But I'm gonna give it a try anyway.

patrickhrastnik avatar May 19 '18 08:05 patrickhrastnik

@jasonday I tried if $iframe[0].print() is executable in Google Chrome console (desktop device), but this doesn't work. image

These commands work on desktop device, but not on the iPad Pro:

  • $iframe[0].contentWindow.print()
  • $iframe[0].contentDocument.execCommand("print")
  • $iframe[0].contentWindow.document.execCommand("print")

patrickhrastnik avatar May 22 '18 05:05 patrickhrastnik

@jasonday Is there something more I can do here? Something I can check out or try? Or some information I could try to get?

patrickhrastnik avatar Jun 05 '18 14:06 patrickhrastnik

Let me do some digging today and come up with a couple of tests. I appreciate your help in this.

jasonday avatar Jun 05 '18 14:06 jasonday

Any updates? I am having the same issue on an iPhone X and iPad.

carlsheehan avatar Aug 07 '18 20:08 carlsheehan

https://stackoverflow.com/questions/52077304/window-print-not-working-in-ipad-chrome-in-popup-windowwindow-open

Is this bug is also related to this issue?

RenukaKalaivani avatar Aug 29 '18 13:08 RenukaKalaivani

Are there any updates to this issue for Chrome on iPad? This is literally the only issue for me for this great work!

benlevydesign avatar Jul 15 '19 23:07 benlevydesign

So, one immediate hack would be to change these lines (https://github.com/jasonday/printThis/blob/master/printThis.js#L278):

if ($iframe.hasClass("MSIE")) {
                    // check if the iframe was created with the ugly hack
                    // and perform another ugly hack out of neccessity
                    window.frames["printIframe"].focus();
                    $head.append("<script>  window.print(); </s" + "cript>");
                } else {
                    // proper method
                    if (document.queryCommandSupported("print")) {
                        $iframe[0].contentWindow.document.execCommand("print", false, null);
                    } else {
                        $iframe[0].contentWindow.focus();
                        $iframe[0].contentWindow.print();
                    }
                }

to:

window.frames["printIframe"].focus();
  $head.append("<script>  window.print(); </s" + "cript>");

It's an ugly hack we utilize for IE, but it may work for this scenario and should work for all scenarios until we figure this out permanently.

jasonday avatar Jul 16 '19 01:07 jasonday

I try it out when I get to my computer today!

benlevydesign avatar Jul 16 '19 17:07 benlevydesign

@jasonday Did this ever get resolved? Any updates?

evanb2 avatar Dec 12 '19 02:12 evanb2

@patrickhrastnik - take a look at this line from another printing plugin:

// Fix for IE11 - printng the whole page instead of the iframe content
if (!frameWindow.document.execCommand('print', false, null)) {
    // document.execCommand returns false if it failed -http://stackoverflow.com/a/21336448/937891
    frameWindow.print();
 }

If that works, that means we can change a few things around line 246.

This might work - worth testing, and then if it does, we can rework that entire section.

} else {
    // proper method
    if (!$iframe[0].contentWindow.document.execCommand("print", false, null);) {
        $iframe[0].print();
    } else {
        $iframe[0].contentWindow.focus();
        $iframe[0].contentWindow.print();
    }
}

@jasonday does it work for you on iPad?

guptanisha avatar Jan 17 '20 20:01 guptanisha

Thanks for the suggestion @guptanisha I'll have a look on your suggested code - I just can't promise when. fyi, we're still interested in fixing this bug, even though it's been around for a while.

edit: maybe I need to give a bit more explanation - due to the current ongoing pandemic I don't have access to my office equipment. That's why I can't give any information on when I'll get a chance to try out the suggested fix.

patrickhrastnik avatar Apr 01 '20 21:04 patrickhrastnik

Having this issue on Chrome iPad too. Safari works fine.

louisluu avatar Oct 13 '20 23:10 louisluu

I think this is similar to the issue in #193

I believe what's happening in each scenario is that the print iframe is being removed before the print executes. On "desktop", javascript halts execution when the print dialog is open, but chrome on iPad the javascript execution events seem to not halt in the expected manner.

I think the quick fix for this is to comment out $iframe.remove(); in this line:

// remove iframe after print
if (!opt.debug) {
  setTimeout(function() {
    // $iframe.remove();
  }, 1000);
}

Can someone please attempt that fix and report back?

jasonday avatar Oct 14 '20 01:10 jasonday

I think this is similar to the issue in #193

I believe what's happening in each scenario is that the print iframe is being removed before the print executes. On "desktop", javascript halts execution when the print dialog is open, but chrome on iPad the javascript execution events seem to not halt in the expected manner.

I think the quick fix for this is to comment out $iframe.remove(); in this line:

// remove iframe after print
if (!opt.debug) {
  setTimeout(function() {
    // $iframe.remove();
  }, 1000);
}

Can someone please attempt that fix and report back?

This was the solution I needed. Thank you

MartinDeBeer avatar Jan 06 '22 10:01 MartinDeBeer

Thanks for the suggestion @guptanisha I'll have a look on your suggested code - I just can't promise when. fyi, we're still interested in fixing this bug, even though it's been around for a while.

edit: maybe I need to give a bit more explanation - due to the current ongoing pandemic I don't have access to my office equipment. That's why I can't give any information on when I'll get a chance to try out the suggested fix.

@patrickhrastnik It doesn't work for me either. It's been 2 yrs almost. Still couldn't resolve the issue. @jasonday Pls suggest if any potential solution.

guptanisha avatar May 17 '22 18:05 guptanisha

Any updates regarding a fix for this issue?

skhilliard avatar Sep 23 '22 19:09 skhilliard