The problem is very simple: i have to download a file when i submit a form, it\'s an ajax call when the form is submitted which lets me build a file with the data taken from
After reading on various sources from Ext JS forum and here in stackoverflow, below is the approach I've chosen (using Ext JS version 4.2.1):
downloadFile: function(config){
config = config || {};
var url = config.url,
method = config.method || 'POST',// Either GET or POST. Default is POST.
params = config.params || {};
// Create form panel. It contains a basic form that we need for the file download.
var form = Ext.create('Ext.form.Panel', {
standardSubmit: true,
url: url,
method: method
});
// Call the submit to begin the file download.
form.submit({
target: '_blank', // Avoids leaving the page.
params: params
});
// Clean-up the form after 100 milliseconds.
// Once the submit is called, the browser does not care anymore with the form object.
Ext.defer(function(){
form.close();
}, 100);
}
I think you can take a much easier solution. Forget about the ajax, and just get plain old js to open the file for you:
window.open('http://whatever.com/count?client='+client+'&start='+start+'&end='+end)
This will open a new tab and start the download from there.
You cannot use ajax to download file. I've implemented file downloading in extjs which is like ajax. see the blog ajaxlikefiledownload.
FileDownload.downloadFile = function(arguments) {
var url = arguments['url'];
var params = arguments['params'];
var successCallback = arguments['success'];
var failureCallback = arguments['failure'];
var body = Ext.getBody();
var frame = body.createChild({
tag:'iframe',
cls:'x-hidden',
id:'hiddenframe-frame',
name:'iframe'
});
var form = body.createChild({
tag:'form',
cls:'x-hidden',
id:'hiddenform-form',
action: url,
method: 'POST',
target:'iframe'
});
if (params) {
for (var paramName in params) {
form.createChild({
tag:'input',
cls:'x-hidden',
id:'hiddenform-'+paramName,
type: 'text',
text: params[paramName],
target:'iframe',
value: params[paramName],
name: paramName
});
}
}
form.dom.submit();
FileDownload.isFinished(successCallback,failureCallback);
};
FileDownload.isFinished = function(successCallback,failureCallback) {
//Check if file is started downloading
if (Ext.util.Cookies.get('fileDownload') && Ext.util.Cookies.get('fileDownload')=='true' ) {
//Remove cookie call success callback
Ext.util.Cookies.set('fileDownload', null, new Date("January 1, 1970"),application.contextPath+'/');
Ext.util.Cookies.clear('fileDownload',application.contextPath+'/');
successCallback();
return;
}
//Check for error / IF any error happens then frame will load with content
try {
if(Ext.getDom('hiddenframe-frame').contentDocument.body.innerHTML.length>0){
Ext.util.Cookies.set('fileDownload', null, new Date("January 1, 1970"),application.contextPath+'/');
Ext.util.Cookies.clear('fileDownload',application.contextPath+'/');
failureCallback();
//Cleanup
Ext.getDom('hiddenframe-frame').contentDocument.body.innerHTML = "";
return;
}
}
catch (e) {
console.log(e);
}
console.log('polling..');
// If we are here, it is not loaded. Set things up so we check the status again in 100 milliseconds
window.setTimeout('FileDownload.isFinished('+successCallback+','+failureCallback+')', 100);
};
Usage :
FileDownload.downloadFile({
url : url,
params : params,
success : function(){
//Success call back here
},
failure : function(){
//Failure callbak here
}
});
In the http response you need to add a cookie nammed fileDownload = true
After extracting/reading many posts, I managed to get this simple method to work..
Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
standardSubmit: true,
url: 'URL'
}).submit({params: {'PARAM1': param1, 'PARAM2': param2}});
The following code used to download the file using extjs 5 or 6. Add the following code to method and invoke this for button action. This downloads the file directly insteadof opening in new tab.
use an iframe like this:
/**
* prints the file
*/
printReport: function () {
var url = 'downloadURL';
Ext.Ajax.request({
url: url,
method: 'GET',
autoAbort: false,
success: function(result) {
if(result.status == 204) {
Ext.Msg.alert('Empty Report', 'There is no data');
} else if(result.status == 200) {
Ext.DomHelper.append(Ext.getBody(), {
tag: 'iframe',
frameBorder: 0,
width: 0,
height: 0,
css: 'display:none;visibility:hidden;height:0px;',
src: url
});
}
},
failure: function() {
//failure here will automatically
//log the user out as it should
}
});
}
Copied the answer from extjs forum
Option:2 If you want to open the file in new tab
/**
* open file in tab
*/
openReport: function () {
var url = 'downloadURL';
Ext.Ajax.request({
url: url,
method: 'GET',
autoAbort: false,
success: function(result) {
if(result.status == 204) {
Ext.Msg.alert('Empty Report', 'There is no data');
} else if(result.status == 200) {
var win = window.open('', '_blank');
win.location = url;
win.focus();
}
},
failure: function() {
//failure here will automatically
//log the user out as it should
}
});
}
I had a similar problem trying to download an Excel File in an Ajax call I solved it this way:
Make a standard sumbit instead of Ajax.
var form = Ext.create('Ext.form.Panel', { // this wolud be your form
standardSubmit: true, // this is the important part
url: '../ObtenerArchivoAdjuntoServlet'
});
form.submit({
params: {
nombreArchivo: nombreArchivo
}
});
After this you would be able return the desired file.