Tuesday, June 18, 2013

ExtJs Multiple file Upload Control

In this post I'm gonna explain a multiple file upload control developed myself in ExtJs. I had a tough time searching for a multi file uploader in ExtJs. But I couldn't find any such control as per my requirement. Finally I did develop a control, which I wanna share with you guys.

I am using ExtJs normal single file upload control. Upon file selected the file upload control will be pushed down and make it hidden in the below panel. At the same time another panel will be displayed below , which will show the filename, attach icon and a remove button. Another file upload control will be created for the user to select next file . This process will get repeated and the user can put as many files as he can in the form. Finally when the form get submitted you will get these files in the server side.

You can remove added files as well. I have added file validation before adding the file too.

You can add or remove file extensions as you needed in the accept property array defined here

 Here is the javascript code

/* File Created: June 14, 2013 */
/* Author : Sebastian */
Ext.define("YourApp.view.util.Multiupload", {
    extend: 'Ext.form.Panel',
    border: 0,
    alias: 'widget.multiupload',
    margins: '2 2 2 2',
    accept: ['pdf', 'jpg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'bmp', 'tif', 'zip'],
    fileslist: [],
    frame: false,
    items: [
        {
            xtype: 'filefield',
            buttonOnly: true,
            listeners: {
                change: function (view, value, eOpts) {
                    //  alert(value);
                    var parent = this.up('form');
                    parent.onFileChange(view, value, eOpts);
                }
            }

        }

    ],
    onFileChange: function (view, value, eOpts) {
        // debugger;
        var fileNameIndex = value.lastIndexOf("/") + 1;
        if (fileNameIndex == 0) {
            fileNameIndex = value.lastIndexOf("\\") + 1;
        }
        var filename = value.substr(fileNameIndex);

        var IsValid = this.fileValidiation(view, filename);
        if (!IsValid) {
            return;
        }


        this.fileslist.push(filename);
        var addedFilePanel = Ext.create('Ext.form.Panel', {
            frame: false,
            border: 0,
            padding: 2,
            margin: '0 10 0 0',
            layout: {
                type: 'hbox',
                align: 'middle'
            },
            items: [

                {
                    xtype: 'button',
                    text: null,
                    border: 0,
                    frame: false,
                    iconCls: 'button-close',
                    tooltip: 'Remove',
                    listeners: {
                        click: function (me, e, eOpts) {
                            var currentform = me.up('form');
                            var mainform = currentform.up('form');
                            var lbl = currentform.down('label');
                            mainform.fileslist.pop(lbl.text);
                            mainform.remove(currentform);
                            currentform.destroy();
                            mainform.doLayout();
                        }
                    }
                },
                {
                    xtype: 'label',
                    padding: 5,
                    listeners: {
                        render: function (me, eOpts) {
                            me.setText(filename);
                        }
                    }
                },
                {
                    xtype: 'image',
                    src: 'assets/images/attach.png'

                }
            ]
        });

        var newUploadControl = Ext.create('Ext.form.FileUploadField', {
            buttonOnly: true,
            listeners: {
                change: function (view, value, eOpts) {

                    var parent = this.up('form');
                    parent.onFileChange(view, value, eOpts);
                }
            }
        });
        view.hide();
        addedFilePanel.add(view);
        this.insert(0, newUploadControl);
        this.add(addedFilePanel);


        // alert(filename);
    },

    fileValidiation: function (me, filename) {

        var isValid = true;
        var indexofPeriod = me.getValue().lastIndexOf("."),
            uploadedExtension = me.getValue().substr(indexofPeriod + 1, me.getValue().length - indexofPeriod);
        if (!Ext.Array.contains(this.accept, uploadedExtension)) {
            isValid = false;
            // Add the tooltip below to
            // the red exclamation point on the form field
            me.setActiveError('Please upload files with an extension of :  ' + this.accept.join() + ' only!');
            // Let the user know why the field is red and blank!
            Ext.MessageBox.show({
                title: 'File Type Error',
                msg: 'Please upload files with an extension of :  ' + this.accept.join() + ' only!',
                buttons: Ext.Msg.OK,
                icon: Ext.Msg.ERROR
            });
            // Set the raw value to null so that the extjs form submit
            // isValid() method will stop submission.
            me.setRawValue(null);
            me.reset();
        }

        if (Ext.Array.contains(this.fileslist, filename)) {
            isValid = false;
            me.setActiveError('The file ' + filename + ' already added!');
            Ext.MessageBox.show({
                title: 'Error',
                msg: 'The file ' + filename + ' already added!',
                buttons: Ext.Msg.OK,
                icon: Ext.Msg.ERROR
            });
            // Set the raw value to null so that the extjs form submit
            // isValid() method will stop submission.
            me.setRawValue(null);
            me.reset();
        }


        return isValid;
    },
});

once this javascript file created in your view . you can put it in your form with an xtype 'multiupload'

Here is the screen shot

Cheers ! Happy coding !