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 !
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 !
Hi Sebastian,
ReplyDeleteCan you share the code to this mail dineshharaveer207@gmail.com.
Hi Dinesh,
DeleteI remember you asked me about filesize checking before uploading. Please refer my new post
Thank you
Hello Sebastian, congratulations for the post, this will help many colleagues who are looking for this solution.
ReplyDeletePlease, I'm trying to deploy your code in ASP.NET MVC and RAZOR 4, you could send a sample of your code in the email javahti@gmail.com ???
Hi, i just implemented and works great but dont have any idea on how to upload those files. I don't even see an "upload" button. Can you share the upload code please? Appreciate it
ReplyDeleteHi
DeleteUploading logic you have to implement .
On clicking the upload button you may have to post the form to server side
In the server side you will get the form contents including the files you have added
Thank you much for the post. It could fix one of the issue that I was facing.
ReplyDeleteHi Sebastian Louis,
ReplyDeleteI want list out all file names just after the browse button not as below the button how can achieve this
This comment has been removed by the author.
DeleteHi ,
ReplyDeleteYou can do this by layout changes. In this example I have created a panel containing label for showing file name and a delete button below the browse button the button .
In my current version I use a grid panel to hold the filenames list.
You can change the layout to show the file names on the right side of browse button as well. But I'm not clear about your requirement since the files can go many so it is better to keep below so that it can grow downwards rather than sideways !
Cheers..!!
This comment has been removed by the author.
ReplyDeleteHi Sebastian,
ReplyDeletei am new to extjs , i have extra form filed like textarea , combobox in form.but using ur code i am getting the below err:
:283 Uncaught TypeError: Cannot read property 'onFileChange' of undefined
.
Help me to figure out the issue.
i am using 4.2 version.
Thanks.
Hi ,
DeleteonFileChange Function is defined in the Multiupload class. It extends a form class. It seems you are doing something wrong. Please try to debug . It seems
var parent = this.up('form');
Returns undefined in your case
ok thanks.. i found the issue.
DeleteHi Sebastian,
ReplyDeleteHow to remove all the Uploaded Files before Submit .
I am using 5.1 Version.
Thanks.
Hi ,
DeleteMay I know why do you want to remove uploaded files before submit?
Please consider this as a request, While writing function pls update it's use and working.. if it's there more easy to identify. And Thank you for your grate effort..
ReplyDelete