printThis
printThis copied to clipboard
Print issue on iPad in Google Chrome and Firefox (Safari works)
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
});
When debug
is set to true
the print won't execute. This option is for debugging only.
I changed debug to false, and nothing changed. Safari on iPad opens the print dialog, Google Chrome on iPad doesn't.
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)
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.
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.
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.
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.
Also interesting: window.document.execCommand("print")
instead of window.print()
doesn't work, but window.document.queryCommandSupported("print")
returns true
@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.
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.
Interesting thread: https://stackoverflow.com/a/21336448/335514 for additional research
@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();
}
}
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.
@jasonday I tried if $iframe[0].print()
is executable in Google Chrome console (desktop device), but this doesn't work.
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")
@jasonday Is there something more I can do here? Something I can check out or try? Or some information I could try to get?
Let me do some digging today and come up with a couple of tests. I appreciate your help in this.
Any updates? I am having the same issue on an iPhone X and iPad.
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?
Are there any updates to this issue for Chrome on iPad? This is literally the only issue for me for this great work!
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.
I try it out when I get to my computer today!
@jasonday Did this ever get resolved? Any updates?
@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?
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.
Having this issue on Chrome iPad too. Safari works fine.
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?
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
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.
Any updates regarding a fix for this issue?