Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
patrickhrastnik opened this issue May 11, 2018 · 29 comments
Open

Comments

@patrickhrastnik
Copy link

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
});
@jasonday
Copy link
Owner

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

@patrickhrastnik
Copy link
Author

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

@patrickhrastnik
Copy link
Author

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)

@oculus42
Copy link
Collaborator

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.

@patrickhrastnik
Copy link
Author

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
Copy link
Author

patrickhrastnik commented May 16, 2018

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
Copy link
Author

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
Copy link
Author

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

@jasonday
Copy link
Owner

@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
Copy link
Owner

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
Copy link
Owner

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

@jasonday
Copy link
Owner

@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();
    }
}

@patrickhrastnik
Copy link
Author

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
Copy link
Author

@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
Copy link
Author

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

@jasonday
Copy link
Owner

jasonday commented Jun 5, 2018

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

@carlsheehan
Copy link

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

@RenukaKalaivani
Copy link

@benlevydesign
Copy link

benlevydesign commented Jul 15, 2019

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

@jasonday
Copy link
Owner

jasonday commented Jul 16, 2019

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.

@benlevydesign
Copy link

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

@evanb2
Copy link

evanb2 commented Dec 12, 2019

@jasonday Did this ever get resolved? Any updates?

@guptanisha
Copy link

@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?

@patrickhrastnik
Copy link
Author

patrickhrastnik commented Apr 1, 2020

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.

@louisluu
Copy link

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

@jasonday
Copy link
Owner

jasonday commented Oct 14, 2020

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?

@MartinDeBeer
Copy link

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

@guptanisha
Copy link

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.

@skhilliard
Copy link

Any updates regarding a fix for this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests