What I am trying to do is a tool in which it will export a pdf file.
There are two cases:
script for case 1
$('body').on("click", '.export-invoice-pdf', function () {
// get id
let id = $(this).closest('tr').data('id');
let newWindow = window.open(
'url' + id,
"_blank"
);
newWindow.onload = function() {
newWindow.close();
};
});
script for case 2:
$('body').on("click", '.export-invoice-pdf', function () {
// get id
let id = $(this).closest('tr').data('id');
let newWindow = window.open(
'',
"_blank"
);
//Ajax call to check if there is an available file
$.ajax({
type: 'POST',
url: 'url',
data: {'orderId': orderId},
dataType: 'json',
encode: true,
}).success(function (data) {
console.log('1');
if (data.hasFile === true) {
//if has file do the samething as case 1
newWindow.location.href = 'url' + orderId;
newWindow.onload = function() {
newWindow.close();
};
} else {
alert('no file to export');
}
}).error(function () {
});
});
Now this is not working. Actually my first problem was it's not making the new window because it treats it as a popup but I got that fixed after an hour of research. Now the closing of the window is my problem.
I have looked it up already in and still currently looking not just in here but sadly I was not able to find an answer about this problem. Any kind of help is appreciated.
Update: The thing that worked for me is by using XMLHttpRequest so that I don't have to open a new blank tab so that my php headers will serve me the PDF file.
Here is the code that I am using:
let xhr = new XMLHttpRequest();
//we use responseType arraybuffer so that the pdf file won't be blank
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status === 200) {
var blob = new Blob([this.response], {type:"application/pdf"});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = "nameofpdf.pdf";
link.click();
}
};
xhr.send();
The url that I used was handled by a controller that gives me the pdf file still with the use of php headers.
Try this?
$('body').on("click", '.export-invoice-pdf', function () {
//Ajax call to check if there is an available file
$.ajax({
type: 'POST',
url: 'url',
data: {'orderId': orderId},
dataType: 'json',
encode: true,
}).success(function (data) {
console.log('1');
if (data.hasFile === true) {
//if has file do the samething as case 1
// get id
const id = $(this).closest('tr').data('id');
Object.assign(document.createElement('a'), {
target: '_blank',
'url' + orderId,
}).click();
// make user close the tab
} else {
alert('no file to export');
}
}).error(function () {
});
});
Popup blockers usually don't allow popups (or programmatically clicking dynamically created hyperlinks etc) if window.open()
is not invoked by a direct user action. Every browser has a slightly different mechanism of blocking popups.
In your case 1, first all code is run on the main thread as a result of user clicking the export button. This works fine.
In case 2 opening a window may not work in all browsers as it is called from another thread. Ajax success handler will be called asynchronously long after your onclick event finished.
To correct this, you can use synchronous requests to execute all code on main thread. You can XMLHttpRequest
or async option $.ajax({async: false})
. It ensure that you code will work in all browsers as they change their popup blocking algorithms.
Implementing above suggestions can help fix your issue with window.onload()
not being triggered, but there is another improvement that can be made - adding onload
handler before navigation:
//if has file do the samething as case 1
newWindow.onload = function() {
newWindow.close();
};
newWindow.location.href = 'url' + orderId;
Or even better add it in the main thread, right after
let newWindow = window.open(
'',
"_blank"
);
newWindow.onload = function() {
newWindow.close();
};
Hope, it helps.
Consider using iframe for this. It's a perfectly valid solution and would prevent the need to listen to another window event, which is bad practice and not needed.
function downloadFile(fileUrl) {
var downloadIframe = $('#download-iframe');
if (downloadIframe) {
downloadIframe.remove();
}
$('<iframe>', {
id: 'download-iframe',
src: fileURL
}).hide().appendTo('body');
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.