talha06
talha06

Reputation: 6466

ExtJS 6 - How to upload a file without using form?

Ext JS provides fileuploadfield which is bundled with a button to browse local files. I just need to upload a file using as soon as it is selected from local instead of using a submit button in order to trigger the post process. Could not find an event which is fired after the file is selected.

p.s. Actually, the version I use is Ext JS 6 but I think the solutions based on previous versions do the work as well.

Upvotes: 4

Views: 15139

Answers (4)

khmurach
khmurach

Reputation: 484

Form is not required. You can use AJAX and FormData.

var file = s.fileInputEl.dom.files[0],
    data = new FormData();

data.append('file', file);

Ext.Ajax.request({
   url: '/upload/files',
   rawData: data,
   headers: {'Content-Type':null}, //to use content type of FormData
   success: function(response){ }
});

Online demo here

Upvotes: 10

matt
matt

Reputation: 4047

While I agree with scebotari's answer that in your case embedding a form in the toolbar is probably the easiest solution, for the sake of answering the original question:

If you really cannot or do not want to use a form and you're not limited regarding browser support, have a look at the FileReader.

The idea is to read the file contents on the client side (JavaScript) and then send the data using a regular AJAX request.

Your code could look like that:

function (fileField) {
    var file = fileField.fileInputEl.dom.files[0],
        reader;

    if (file === undefined || !(file instanceof File)) {
        return;
    }

    reader = new FileReader();    
    reader.onloadend = function (event) {
         var binaryString = '',
             bytes = new Uint8Array(event.target.result),
             length = bytes.byteLength,
             i,
             base64String;

         // convert to binary string
         for (i = 0; i < length; i++) {
             binaryString += String.fromCharCode(bytes[i]);
         }

         // convert to base64
         base64String = btoa(binaryString);

         Ext.Ajax.request({
             url: 'save-file.php',
             method: 'POST',
             params: {
                 data: base64String
             }
         });
    };

    reader.readAsArrayBuffer(file);
}

Upvotes: 3

scebotari66
scebotari66

Reputation: 3480

You will need to use a form if you want to submit the file. Even if you want the button to be in a toolbar, you can enclose it in a form and it will still look like a normal toolbar button (you will need to specify the proper ui config for this).

Example:

dockedItems: [{
    dock: 'top',
    xtype: 'toolbar',
    items: [{
        xtype: 'form',
        padding: '10 0 0',
        url: 'submit/image',
        items: {
            xtype: 'filefield',
            buttonOnly: true,
            width: 100,
            buttonConfig: {
                text: 'Add logo',
                width: '100%',
                ui: 'default-toolbar-small'
            },
            listeners: {
                change: function (filefield) {
                    filefield.up('form').submit();
                }
            }
        }
    }, {
        text: 'Remove logo'
    }, '-', {
        text: 'Discard changes'
    }]
}]

Working fiddle example: https://fiddle.sencha.com/#view/editor&fiddle/1pdk

Upvotes: 5

pagep
pagep

Reputation: 3629

You are looking for the event change on the fileuploadfield.

The code could look like this:

Ext.create('Ext.form.Panel', {
    renderTo: Ext.getBody(),
    title: 'Upload Panel',
    items: [{
        xtype: 'filefield',
        name: 'photo',
        fieldLabel: 'Photo',
        labelWidth: 50,
        msgTarget: 'side',
        allowBlank: false,
        anchor: '100%',
        buttonText: 'Select Photo...',
        listeners: {
            change: function (me, value, eOpts) {
                console.log('trigger upload of file:', value);
            }
        }
    }],
});

Fiddle https://fiddle.sencha.com/#view/editor&fiddle/1pd2

Upvotes: 1

Related Questions