Print.js icon indicating copy to clipboard operation
Print.js copied to clipboard

onPrintDialogClose not working with Chrome Version 86.0.4240.75 (Official Build) (64-bit)

Open varshapwalia opened this issue 4 years ago • 21 comments

I use the PrintJS library for pdf print and I used to call the onPrintDialogClose function to reload after I close the dialogue window. But since the latest chrome version, the function is being skipped altogether and not triggering. Although the dialogue window is opening but the onPrintDialogClose functionality is not triggering and skipping.

sample code which was working before:

window.printJS({printable:url, type:'pdf', onPrintDialogClose: function(){ window.location.href = "/"; window.location.reload(); }});

EDIT: Interesting point: If I switch screen or toggle any opened tab or open a new tab and come back. The reload function triggers then.

varshapwalia avatar Oct 19 '20 13:10 varshapwalia

I encounter the same issue.

nelisbraems avatar Oct 19 '20 15:10 nelisbraems

@varshapwalia The issue is probably due to the fact that you are killing the session by redirecting the user to another url. Please try adding a small timeout to your onPrintDialogClose callback fore you redirect the user.

crabbly avatar Oct 19 '20 20:10 crabbly

Actually, I misread your code, sorry. Just tested it in Chrome v86 on both MacOS and Windows. It works fine in MacOS but it seems to have stopped working in Windows, again.

crabbly avatar Oct 19 '20 21:10 crabbly

It stopped working in ubuntu as well.

varshapwalia avatar Oct 20 '20 03:10 varshapwalia

We have the same problem . And it is not just chrome . It is in Edge as well. Funny part is if you move to some other window and then come back then the popup appears again. Any workaround suggestion until this is fixed?

animeshrajurkar avatar Oct 23 '20 08:10 animeshrajurkar

I have the same problem... What i do? :)

natilopesv avatar Oct 26 '20 11:10 natilopesv

any solution so far?

ermarkar avatar Oct 26 '20 14:10 ermarkar

I had a production problem and spent almost one week looking for a solution, but I'm not satisfied with it.

I tried to edit the Print.js library to write an HTML and use the embed or the object tag inside it to embed the PDF document. I don't know why but both didn't work. I couldn't find if there is a new security rule or if is just a bug, but when the pdf is loaded inside the iframe, the print callback isn't fired correctly. It doesn't happen with custom HTML.

Looks that it happens only on Windows (on Mac is fine, but I don't know about Linux), and Chromium should have the same behaviour regardless the platform. This is why I think that is a bug.

I did a workaround using Mozilla's PDF.js to print PDF files and now I'm using Print.js only for HTML templates. PDF.js creates one canvas for each PDF page, save these canvas into images and then prints the output using the viewer. Is a really heavy solution, but is the best I could do so far.

To Angular guys, there is a library that help us to work with PDF.js: ngx-extended-pdf-viewer

I'm still looking for a better solution.

ricmello avatar Oct 27 '20 02:10 ricmello

Hey guys!

Any news about this defect?

kruzzze avatar Nov 17 '20 13:11 kruzzze

I found a workaround. Not sure if its very good solution cause I'm really new to js and typescript language but so far the behavior is stable and I dont need to click outside the window and refocus it for onPrintDialogClose to be executed I tested only for my case printing html and only on Chrome. At my component calling printJS I add and eventListener on iframe. setTimeout(() => { const height = document.getElementById('print-section').getBoundingClientRect().height; const size = margin:4px;size: 280px ${height + 50}px; printJS({ printable: "print-section", type: 'html', targetStyle: 'font-weight: 900;line-height: 2em;font-size: 2em;', pageStyle: size }); iframe = document.getElementById('printJS'); if (iframe) { iframe.contentWindow!.addEventListener('afterprint', () => { //a function after the browser print dialog is closed }); } }, 1000)

EvaggelosWolfksin avatar Nov 21 '20 19:11 EvaggelosWolfksin

I'm having problems with this as well - onPrintDialogClose will not fire unless I change tabs back and forth. Using print-js 1.5.0 and the latest version of Chrome - 87.0.4280.66

permagne avatar Nov 23 '20 07:11 permagne

Ok, I found the problem and maybe a solution.

The thing is, in the new chrome update, the windows.focus event no longer fired after the print window appeared. While moseover got on with it. This means that for the Chrome browser it is necessary to return a reaction to mouseover. True, you need to delay the execution of the cleanUp method after contentWindow.print ()

kruzzze avatar Nov 24 '20 13:11 kruzzze

you mean a solution that will be fixed soon in the code or you mean a workaround that we can use ?

animeshrajurkar avatar Nov 24 '20 13:11 animeshrajurkar

I opened a pull request.

What workround can I suggest:

After calling printJS ()

add the following code:

  const handler = () => {
    // Make sure the event only happens once.
    window.removeEventListener ('mouseover', handler)

---------- your callback function here--------------

    // Remove iframe from the DOM, by default 'printJS'
    const iframe = document.getElementById (frameId)

    if (iframe) {
      iframe.remove ()
    }
  }

  setTimeout (() => {window.addEventListener ('mouseover', handler)}, 1000)

It may still need to be checked for specific browsers, I checked it only for Chrome.

Tell me, if it doesn't work, I'll try to find something else.

kruzzze avatar Nov 24 '20 15:11 kruzzze

I opened a pull request.

What workround can I suggest:

After calling printJS ()

add the following code:

  const handler = () => {
    // Make sure the event only happens once.
    window.removeEventListener ('moseover', handler)

---------- your callback function here--------------

    // Remove iframe from the DOM, by default 'printJS'
    const iframe = document.getElementById (frameId)

    if (iframe) {
      iframe.remove ()
    }
  }

  setTimeout (() => {window.addEventListener ('mouseover', handler)}, 1000)

It may still need to be checked for specific browsers, I checked it only for Chrome.

Tell me, if it doesn't work, I'll try to find something else.

this is working but there is spelling mistake for mouseover event

ermarkar avatar Nov 25 '20 05:11 ermarkar

this is working but there is spelling mistake for mouseover event

Oh really you are right thank you! I will fix the error in the code

and in some cases I would advise changing the event to mousemove because there is not always an element on the form.

kruzzze avatar Nov 25 '20 06:11 kruzzze

Hi,

I just started to have this problem.

Is there a problem that prevents @kruzzze's PR from being merged?

Is there anything I can do to help?

Ldoppea avatar Apr 09 '21 16:04 Ldoppea

I am experiencing the same issue in Firefox 88.01(64 bit) running on macOS BigSur 11.4

splinecl avatar May 31 '21 09:05 splinecl

I opened a pull request.

What workround can I suggest:

After calling printJS ()

add the following code:

  const handler = () => {
    // Make sure the event only happens once.
    window.removeEventListener ('mouseover', handler)

---------- your callback function here--------------

    // Remove iframe from the DOM, by default 'printJS'
    const iframe = document.getElementById (frameId)

    if (iframe) {
      iframe.remove ()
    }
  }

  setTimeout (() => {window.addEventListener ('mouseover', handler)}, 1000)

It may still need to be checked for specific browsers, I checked it only for Chrome.

Tell me, if it doesn't work, I'll try to find something else.

It seems to be not deterministic, worked 2 times on many attempts, not sure what made it work in my case.

My case was to print multiple documents. I've tried using printjs recursively like that:

const print = (dataArr) => {
   if (!dataArr.length) {
      return;
   }
   printJS({
      ...dataArr[0],
      onPrintDialogClose: () => {
         if (dataArr.length > 1) {
            printJS(dataArr.slice(1, dataArr.length));
         }
      },
   });
};

but onPrintDialogClose didn't work. It's not exact my code, so may have glitches. I finally managed to make printjs display multiple print dialogs by setting dynamic frameId

const print = (dataArr) => {
   dataArr.forEach((document, index) => {
      printJS({
         ...document,
         frameId: `printJS-${index}`,
      })
   })
}

I hope it'll help someone

c0dester avatar Mar 18 '22 10:03 c0dester

I was facing a similar issue where I wanted to trigger printing of more than one PDF file.

I opened a pull request. What workround can I suggest: After calling printJS () add the following code:

  const handler = () => {
    // Make sure the event only happens once.
    window.removeEventListener ('mouseover', handler)

---------- your callback function here--------------

    // Remove iframe from the DOM, by default 'printJS'
    const iframe = document.getElementById (frameId)

    if (iframe) {
      iframe.remove ()
    }
  }

  setTimeout (() => {window.addEventListener ('mouseover', handler)}, 1000)

It may still need to be checked for specific browsers, I checked it only for Chrome. Tell me, if it doesn't work, I'll try to find something else.

It seems to be not deterministic, worked 2 times on many attempts, not sure what made it work in my case.

My case was to print multiple documents. I've tried using printjs recursively like that:

const print = (dataArr) => {
   if (!dataArr.length) {
      return;
   }
   printJS({
      ...dataArr[0],
      onPrintDialogClose: () => {
         if (dataArr.length > 1) {
            printJS(dataArr.slice(1, dataArr.length));
         }
      },
   });
};

but onPrintDialogClose didn't work. It's not exact my code, so may have glitches. I finally managed to make printjs display multiple print dialogs by setting dynamic frameId

const print = (dataArr) => {
   dataArr.forEach((document, index) => {
      printJS({
         ...document,
         frameId: `printJS-${index}`,
      })
   })
}

I hope it'll help someone

This was the answer for me. I needed to add:

frameId: `printJS-${index}`,

Then multiple print dialogues open at the same time.

Thanks!

c2oJon avatar May 15 '23 13:05 c2oJon

I was facing a similar issue where I wanted to trigger printing of more than one PDF file.

I opened a pull request. What workround can I suggest: After calling printJS () add the following code:

  const handler = () => {
    // Make sure the event only happens once.
    window.removeEventListener ('mouseover', handler)

---------- your callback function here--------------

    // Remove iframe from the DOM, by default 'printJS'
    const iframe = document.getElementById (frameId)

    if (iframe) {
      iframe.remove ()
    }
  }

  setTimeout (() => {window.addEventListener ('mouseover', handler)}, 1000)

It may still need to be checked for specific browsers, I checked it only for Chrome. Tell me, if it doesn't work, I'll try to find something else.

It seems to be not deterministic, worked 2 times on many attempts, not sure what made it work in my case. My case was to print multiple documents. I've tried using printjs recursively like that:

const print = (dataArr) => {
   if (!dataArr.length) {
      return;
   }
   printJS({
      ...dataArr[0],
      onPrintDialogClose: () => {
         if (dataArr.length > 1) {
            printJS(dataArr.slice(1, dataArr.length));
         }
      },
   });
};

but onPrintDialogClose didn't work. It's not exact my code, so may have glitches. I finally managed to make printjs display multiple print dialogs by setting dynamic frameId

const print = (dataArr) => {
   dataArr.forEach((document, index) => {
      printJS({
         ...document,
         frameId: `printJS-${index}`,
      })
   })
}

I hope it'll help someone

This was the answer for me. I needed to add:

frameId: `printJS-${index}`,

Then multiple print dialogues open at the same time.

Thanks!

it works for me,Thanks!

xiaoxu9156 avatar Sep 06 '23 09:09 xiaoxu9156