ExtJS 4 - How to download a file using Ajax? - javascript

I have a form with various textfields and two buttons - Export to Excel and Export to CSV.
The user can provide the values to different fields in the form and click one of the buttons.
Expected behaviour is that an Ajax request should be fired carrying the values of fields as parameters and the chosen file (Excel/CSV as per the button click) should get downloaded (I am not submitting the form as there needs to be done some processing at the values before submit).
I have been using the following code in success function of Ajax request for the download:
result = Ext.decode(response.responseText);
try {
Ext.destroy(Ext.get('testIframe'));
}
catch(e) {}
Ext.core.DomHelper.append(document.body, {
tag: 'iframe',
id:'testIframe',
css: 'display:none;visibility:hidden;height:0px;',
src: result.filename,
frameBorder: 0,
width: 0,
height: 0
});
The above code has been working fine in the case when the file is created physically at the server. But in my current project, the file is not created at the server, rather the contents are just streamed to the browser with proper headers.
Thus, is there a way to download a file using Ajax when the file is not present at the server physically? Just to add that I have a long list of parameters which I need to send to the server and hence can not add them all to the src of iframe.
Could anyone guide at this?
Thanks for any help in advance.

You may use component like this:
Ext.define('CMS.view.FileDownload', {
extend: 'Ext.Component',
alias: 'widget.FileDownloader',
autoEl: {
tag: 'iframe',
cls: 'x-hidden',
src: Ext.SSL_SECURE_URL
},
stateful: false,
load: function(config){
var e = this.getEl();
e.dom.src = config.url +
(config.params ? '?' + Ext.urlEncode(config.params) : '');
e.dom.onload = function() {
if(e.dom.contentDocument.body.childNodes[0].wholeText == '404') {
Ext.Msg.show({
title: 'Attachment missing',
msg: 'The document you are after can not be found on the server.',
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
})
}
}
}
});
Put it somewhere in viewport, for example:
{
region: 'south',
html: 'South',
items: [
{
xtype: 'FileDownloader',
id: 'FileDownloader'
}
]
}
Do not forget to require it in your viewport class:
requires: [
'CMS.view.FileDownload'
]
Action handler may look like this:
var downloader = Ext.getCmp('FileDownloader')
downloader.load({
url: '/attachments/' + record.get('id') + '/' + record.get('file')
});
It's very important to have Content-Disposition header in response, otherwise nothing is downloaded.
Regards go to http://www.quispiam.com/blog/post.php?s=2011-06-09-download-a-file-via-an-event-for-extjs4
This thing works for me.

Related

Automatically create header from JSON file, Bootstrap-table

I'm working with this bootstrap library and actually everything works fine. The question is, Can bootstrap-table generate header automatically in depend of JSON file? I've tried to find any information about that, but unlucky. Now my header is generated from script like from this example:
function initTable() {
$table.bootstrapTable({
height: getHeight(),
columns: [{
field: 'field1',
title: 'title1',
sortable: true
}, {
field: 'field2',
title: 'title2',
sortable: true
}, {
field: 'field3',
title: 'title3',
sortable: true
}, {
field: 'Actions',
title: 'Item Operate',
align: 'center',
events: operateEvents,
formatter: operateFormatter
}
],
formatNoMatches: function () {
return "This table is empty...";
}
});
Does anyone how to generate header automatically?
Populating from a flat json file is definetly possible but harder than from a seperate (slimmer and preped) data request, because title and other attributes 'might' have to be guessed at.
Ill show basic approach, then tell you how to make it work if stuck with a flat file that you CAN or CANT affect the format of (important point, see notes at end).
Make a seperate ajax requests that populates var colArray = [], or passes direct inside done callback.
For example, in callback (.done(),.success(), ect) also calls to the function that contains the js init code for the table.
You might make it look something like this:
function initTable(cols) {
cols.push({
field: 'Actions',
title: 'Item Operate',
align: 'center',
events: operateEvents,
formatter: operateFormatter
});
$("#table").bootstrapTable({
height: getHeight(),
columns: cols,
formatNoMatches: function () {
return "This table is empty...";
}
});
}
$(document).ready(function(){
$.ajax({
method: "POST",
url: "data/getColumns",
// data: { context: "getColumns" }
datatype: "json"
})
.done(function( data ) {
console.log( "getCols data: ", data );
// Prep column data, depending on what detail you sent back
$.each(data,function(ind,val){
data.sortable = true;
});
initTable(data);
});
});
Now, if you are in fact stuck with a flat file, point the ajax towards that then realise the question is whether you can edit the contents.
If yes, then add a columns array into it with whatever base data (title, fieldname, ect) that you need to help build your columns array. Then use responseHandler if needed to strip that columns array if it causes issues when loading into table.
http://bootstrap-table.wenzhixin.net.cn/documentation/#table-options
http://issues.wenzhixin.net.cn/bootstrap-table/ (click 'see source').
If no, you cant edit contents, and only have the fieldname, then look at using that in the .done() handler with whatever string operation (str_replace(), ect) that you need to make it look the way you want.

Second File Upload fails in ExtJS 6, works in ExtJS 4

Very low-level file upload:
dockedItems: [{
xtype: 'toolbar',
dock: 'top',
items: [{
xtype: 'form',
items: [{
xtype: 'filefield',
fieldLabel: 'Select file',
listeners: {
change: {
fn: me.onFilefieldChange,
scope: me
}
}
}]
},{
...
onFilefieldChange: function(filefield, value, eOpts) {
var form = filefield.up('form').getForm();
form.submit({
url: APIURI+'FileUpload',
headers: {'Accept':'application/json','Content-Type':'application/json'},
waitMsg: 'Uploading',
success: function(fp, o) {
var filedata = Ext.decode(o.response.responseText).data;
var rec = Ext.create("MyApp.model.FileModel",filedata);
Ext.getStore("FileStore").add(rec);
},
failure: function(fp, o) {
Ext.alert("ERROR", "File save failed"));
}
});
The first file upload works like a charm; the file is packed into the multipart/mime and submitted correctly.
The second file upload from the very same file upload field fails, because the file is not packed into the mime.
If I close the window and open it again, the file field is working again - for a single upload, that is.
The difference in DOM of the file input field tells us why the browser behaves like this. The following three attributes are magically missing from the <input type="file" field after the first file upload:
data-ref=​"fileInputEl"
name=​"filefield-1333-button"
data-componentid=​"filefield-1333-button"
Now, this does not happen if I use the file upload field in the sencha docs. It doesn't happen with my code in ExtJS 4.2.2. But it does happen with ExtJS 6.0.1.
You wouldn't know why, would you?
It is a bug in Sencha ExtJS 6 Framework. Everything works as expected if you provide a name property to the file upload field.
xtype: 'filefield',
fieldLabel: 'Select file',
name: 'RequiredSenchaBugWorkaround',
...
Adding a name doesn't always work. It still has issues in Ext 6.2. In addition to that you should do
FileInputField1.reset();
This makes sure that the field is reset and lets you upload the same file again.

File download - ExtJs 4.2.3

I'm using ExtJs 4.2.3.
In my web application I need to download files.
In order to do that I'm using a 'FileDownloader' component defined as in post
fileDownloader
The code is:
Ext.define('myApp.FileDownload', {
extend: 'Ext.Component',
alias: 'widget.FileDownloader',
autoEl: {
tag: 'iframe',
cls: 'x-hidden',
src: Ext.SSL_SECURE_URL
},
load: function(config) {
var e = this.getEl();
e.dom.src = config.url +
(config.params ? '?' + Ext.Object.toQueryString(config.params) : '');
console.log('in FileDownloader - src: ' + e.dom.src);
e.dom.onLoad = function() {
if(e.dom.contentDocument.body.childNodes[0].wholeText == '404') {
Ext.Msg.show({
title: 'Attachment missing',
msg: 'File cannot be found on the server !',
buttons: Ext.Msg.OK,
icon: Ext.MessageBox.ERROR
});
};
};
}
});
I call it by code:
downloader.load({
url: src
});
where src is complete path to file.
If I download Word, Excel, PDF files it's working well, file reference is visualized in download bar of browser, but with other data types (ex. .txt, .jpg) it doesn't do nothing.
I think it's no a question about Extjs or js, it's the server's reponse. See this download the text file instead of opening in the browser

What does the filebrowser field actually do in CKEditor?

The upload tab of image2 plugin looks like this -
{
id: 'Upload',
hidden: false,
filebrowser: 'uploadButton',
label: lang.uploadTab,
elements: [
{
type: 'file',
id: 'upload',
label: lang.btnUpload,
style: 'height:40px',
onChange: function(evt){
alert('file uploaded');
}
},
{
type: 'fileButton',
id: 'uploadButton',
filebrowser: 'info:src',
label: lang.btnUpload,
'for': [ 'Upload', 'upload' ]
}
]
}
Here in the 'tab' details there is filebrowser field which is equal to 'uploadButton' and filebrowser field is also in UI element object where it is equal to 'info:src'.
I am not implementing Browse Server functionality, only upload functionality. I have implemented it but I want to understand how filebrowser plugin and filebrowser fields are facilitating it?
Can anyone here explain here a little bit in detail as CKEditor documentation does not tell much?
The ck_config.js file has settings which determine the URL of the file browser for various purposes:
config.filebrowserBrowseUrl = '';
config.filebrowserImageBrowseUrl = '';
config.filebrowserFlashBrowseUrl = '';
config.filebrowserUploadUrl = '';
config.filebrowserImageUploadUrl = '';
config.filebrowserFlashUploadUrl = '';
Basically this will be a webpage which appears in a roughly 600px-wide popup.
One of the GET parameters of this URL (automatically added) will be CKEditorFuncNum which determines the callback function for sending the results back to CK.
On selection of a file/path, you would typically do:
window.opener.CKEDITOR.tools.callFunction(ck_callback,pathrel2page);
where ck_callback is the CKEditorFuncNum value and pathrel2page is the selected file.
HTH.

List not populating with a JsonP proxy

I want to have a Navigation view. I am trying to populate the list in Sencha Touch using a JsonP proxy.
Here's the sample code snippet of what I have tried till now :
var view = Ext.define('MyApp.view.NavigateView', {
extend: 'Ext.navigation.View',
xtype:'navigateview',
config : {
fullscreen:true,
styleHtmlContent:true,
scrollable:true,
items : [
{
title:'Navigation',
items : [
{
xtype:'list',
store: {
fields : ['title','author'],
proxy : {
type:'jsonp',
url:'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
},
autoLoad:true,
},
itemTpl:'<div class="contact">{title} <strong>{author}</strong></div>',
listeners : {
itemtap : function(){
Ext.Msg.alert('Called');
}
}
}
],
}
]
}
});
But the problem is, my list is not getting populated. No items are being shown up in the list.
Also, I am constantly getting this error on console.
XMLHttpRequest cannot load
http://api.tinyhippos.com/xhr_proxy?tinyhippos_apikey=ABC&tinyhippos_rurl=list.php%3F_dc%3D1334462633038%26page%3D1%26start%3D0%26limit%3D25.
Origin http://localhost is not allowed by Access-Control-Allow-Origin.
Anyone please guide ? Anything that I am missing here ?
i was facing the same error when using AJAX request in cross domain.
have a look here
you have to make sure that the server part is configured properly using jsonp
as a first step identify if your application will run correctly when you disable web security in your browser
locate your chrome installation directory
then type in your cmd: chrome --disable-web-security
Your Ext.navigation.View object is containing one Ext.Component object (xtype not defined so defaulted to 'component') that is containing your list. If you put your list directly as an item of your view, it'll be rendered:
var view = Ext.define('MyApp.view.NavigateView', {
extend: 'Ext.navigation.View',
xtype: 'navigateview',
config : {
fullscreen: true,
styleHtmlContent: true,
scrollable: true,
items : [{
title: 'Navigation',
xtype: 'list',
store: {
fields: ['title','author'],
proxy: {
type: 'jsonp',
url: 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://feeds.feedburner.com/SenchaBlog',
reader: {
type: 'json',
rootProperty: 'responseData.feed.entries'
}
},
autoLoad:true
},
itemTpl: '<div class="contact">{title} <strong>{author}</strong></div>'
}]
}
});
Note1: Not sure why your code is not working.
Note2: The error your mentioned is not related to your code snippet

Categories

Resources