ExtJS 4 - detecting if the user pressed “Print” on the print dialog that was called programatically

跟風遠走 提交于 2019-12-02 20:26:16

问题


Good day, I am building a web application wherein the user can print a panel and its contents. I found a code as seen here and tweaked it as such:

Ext.define('My_app_name.override.form.Panel', {
    override: 'Ext.form.Panel', 

    print: function(pnl) {

        if (!pnl) {
            pnl = this;
        }

        // instantiate hidden iframe

        var iFrameId = "printerFrame";
        var printFrame = Ext.get(iFrameId);

        if (printFrame === null) {
            printFrame = Ext.getBody().appendChild({
                id: iFrameId,
                tag: 'iframe',
                cls: 'x-hidden',
                style: {
                    display: "none"
                }
            });
        }

        var cw = printFrame.dom.contentWindow;
        var stylesheets = "";
        var markup;
        // instantiate application stylesheets in the hidden iframe

        var printTask = new Ext.util.DelayedTask(function(){
            // print the iframe
            cw.print();

            // destroy the iframe
            Ext.fly(iFrameId).destroy();

        });

        var strTask = new Ext.util.DelayedTask(function(){
            var str = Ext.String.format('<html><head>{0}</head><body>{1}</body></html>',stylesheets,markup);


            // output to the iframe
            cw.document.open();
            cw.document.write(str);
            cw.document.close();

            // remove style attrib that has hardcoded height property
            //             cw.document.getElementsByTagName('DIV')[0].removeAttribute('style');
            printTask.delay(500);

        });

        var markUpTask = new Ext.util.DelayedTask(function(){
            // get the contents of the panel and remove hardcoded overflow properties
            markup = pnl.getEl().dom.innerHTML;
            while (markup.indexOf('overflow: auto;') >= 0) {
                markup = markup.replace('overflow: auto;', '');
            }
            while (markup.indexOf('background: rgb(255, 192, 203) !important;') >= 0) {
                markup = markup.replace('background: rgb(255, 192, 203) !important;', 'background: pink !important;');
            }

            strTask.delay(500);
        });


        var styleSheetConcatTask = new Ext.util.DelayedTask(function(){

            // various style overrides
            stylesheets += ''.concat(
                "<style>", 
                ".x-panel-body {overflow: visible !important;}",
                // experimental - page break after embedded panels
                // .x-panel {page-break-after: always; margin-top: 10px}",
                "</style>"
            );

            markUpTask.delay(500);
        });


        var styleSheetCreateTask = new Ext.util.DelayedTask(function(){


            for (var i = 0; i < document.styleSheets.length; i++) {
                stylesheets += Ext.String.format('<link rel="stylesheet" href="{0}" />', document.styleSheets[i].href);
            }
            styleSheetConcatTask.delay(500);
        });

        styleSheetCreateTask.delay(500);
    }
});

I placed the delays to let the function be more consistent in printing out grids and photos as it takes time to "assemble" from the styles.

After the function "assembles" the data to be printed, it calls the browsers native printing methods. My issue right now is that I don't know if I the user presses "Print" or "Cancel" in their web browsers Print Dialog.

Is there a way to create a callback for this override function so I can know if the user really did push through with printing or cancelled the printing job?

Any help is very much appreciated.

Update

I checked the link in mindparses' comment below which led me to this page. I tried to implement the code by doing such below:

var beforePrint = function() {
    console.log('before print');
    form.print();
};
var afterPrint = function() {
    console.log('after print');
};

if (window.matchMedia) {
    var mediaQueryList = window.matchMedia('print');
    mediaQueryList.addListener(function(mql) {
        if (mql.matches) {
            console.log('mql matches');
            beforePrint();
        } else {
            console.log('mql did NOT match');
            afterPrint();
        }
    });
}

Where form is my form and print is the print override function above.

All of these codes are in a button listener.

However, the issue I have with this solution is that it only seems to work if the user presses Ctrl/Command + P. It does not work if the print dialog is programatically called like in my override function above. A second concern I have is that the function triggers when the user issues the Ctrl/Command + P command. What I want is to know when the user really clicks on the "Print" command in the dialog and not when a Print Dialog box appears.


回答1:


While it is easy to control the print dialog, it is not possible to detect if the document was really printed in a cross browser fashion. What is happening in the print dialog is controlled by the operating system and is not readily accessible by JavaScript.

I found two resources about this issue :

  • Detect print request with JavaScript
  • Print without a print dialog

The second link might be interesting because it could allow you to show your own print dialog that you can fully control.

I'm conscious that this is only a partial answer, and I don't know if this problem does have an answer.



来源:https://stackoverflow.com/questions/28620711/extjs-4-detecting-if-the-user-pressed-print-on-the-print-dialog-that-was-cal

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!