ExecuteJavaScript("print();") does not work with Chrome

I have a “Print” button on a webpage with its action set to: ExecuteJavaScript(“print();”)

This work fine when the app is viewed with Explorer 11, but when viewed with Google Chrome Version 34.0.1847.116 m, the following occurs:

Clicking the print button appears to have no effect, however, if the App executable is terminated manually, Chrome then displays its print dialog.
I am compiling with Xojo 2014 r1

If I create an HTML page with a print button on it, whose onclick code is set to: “javascript: window.print()” this works fine in both browsers.
I have linked to a small demo web app which demonstrates the issue.link text

Anyone got any ideas?

See <https://xojo.com/issue/22705> in which the same issue was reported with Safari and was closed as “not a bug”. Perhaps it should be revisited?

It’s still not a bug. The problem is that printing is one of those actions that browsers like to have in the same event loop as a user action. The round-trip nature of our framework makes that not work on the browsers that enforce this rule.

You probably could, however, create a WebSDK button control that calls “print();” directly and have it work.

Not familiar with WebSDK, but thinking of other workarounds… could I render the page into an HTMLviewer control, then use that control’s .Print method??

If my theory is correct then no, that won’t work either because it still won’t be coming as a result of a user event.

In the original report I made, the problem was not that Print() didn’t work at all, but that it was queued up until the WebApp exited, at which point it did work. Any idea why?

I recently built a printable confirmation page where I used the .Print of the HTMLViewer. I called the method from the mouseup of a label, so I’m not sure if that fits into Greg’s theory or would work the way you want it to, but it seems to work fine for me.

I did manage to waste a good bit of time fiddling with other solutions prior to arriving at that method. Fighting the browser is pretty much a losing battle.

I just tried out the Xojo example web app “HTMLViewerPrinting” and it prints fine in Chrome, so that looks like a way to go. Just need to find a way to render my web page in the HTML Viewer…

I would say that printing from a web app is a pretty basic functionality that most folk would expect. I can print statements from my bank’s web site, I can print airplane tickets from the travel web site, I can print a shopping list from my local grocery store.

Maybe this is not a Xojo “bug”, but it sure is a fundamental “feature” that is missing.

Time to place a feature request, methinks! Anyone else agree?

This seems to be a WebKit issue that also affects Blink (Chrome’s fork of WebKit). The issue is not that the JavaScript is running on the wrong thread or in the wrong event loop. Rather the WebKit window.print() command freezes if there is open communication with the server. A good guess is that some where under the hood the print() command is waiting for the page to finish loading.

Other AJAX sites and sites that have open video streams experience the same issue. The suggested work around in various forums is to reload the page in the same JavaScript that issues the print() command. For obvious reasons that will not work in Xojo.

Unfortunately I think this means that we can’t work around the issue by rolling a custom print button in the WebSDK. I tried using Chrome’s developer tools console to insert a div with an onclick function that calls window.print(). Same thing even though the div has nothing to do with Xojo and the code is entirely client side.

The only work around seems to be to load a normal page (i.e. not a Xojo web app page) into a WebHTMLViewer and use its Print method. (Or this method if you need to work around the issue where IE prints the whole window instead of just the viewer’s contents.)

If you have a really complex Xojo page layout that you absolutely have to print as is, then Web Custom Controls has a control, WebGetHtmlTD, which will take an HTML “snapshot” of your page or a container on your page. From there you could load a WebHTMLViewer or open and print a new page/tab with the static snapshot. If your printing needs are simple then it’s not too much trouble to output static HTML yourself.

I have no idea if a work around would be easy or difficult for Xojo. In theory all they have to do is provide a WebPage.Print command that temporarily disconnects the client, prints, then reconnects. In practice that might be impossible, i.e. code all over the server and client might freak if there’s a disconnect, especially if the disconnect has to wait for the user to clear the print dialog. I have no idea.

Really this is a WebKit issue and a true fix belongs there.

Hi Daniel,
many thanks for taking the time for the detailed explanation. I certainly helps me to plan a work-around, now that I can see exactly the issues facing us. It would seem that feeding a WebHTMLViewer with vanilla HTML and then invoking its print method could be the easiest solution.
Thanks again!

For future reference :

ShowURL("javascript:print();")

Has the same effect over here… Still no print dialog.

Am I missing something?

Why not put a handler on a link via JavaScript to print when user clicks on the item?
Without the Xojo round trip.

[quote=393863:@Christian Schmitz]Why not put a handler on a link via JavaScript to print when user clicks on the item?
Without the Xojo round trip.[/quote]

Do you mean in something like MouseUp when clicking the link? That doesn’t work either (testing Safari now).

run some javascript to install event handler in the website, so user triggers print command right there.

Not through an action event in Xojo, but directly in the browser.

Thanks @Christian Schmitz! When I try this…

self.ExecuteJavaScript("document.getElementById('"+Button1.ControlID+"').addEventListener('click', function() { window.print(); }, false); ")

It has the exact same effect. Or am I still misunderstanding you?

[quote=329099:@Michel Bujardet]For future reference :

ShowURL("javascript:print();")

I have no idea what you could be doing, besides not reading what I posted, but that code in the action event of a button triggers the print dialog just fine in Chrome:

ShowURL("javascript:print();")[

It should work with pretty much any browser since it is not using executejavascript, but it works as an applet.

It can also be used from a link, with URL

javascript:print();

Thanks guys. It does work on Chrome, but Safari won’t show the dialog until I stop running the app…