Hello everyone,
In my last post I have explained the multi file upload control created in ExtJs. I have enhanced that controls to a further level as per my requirements. We can check file types , file duplication etc in the client side. We can restrict the user from adding certain file extensions. In this post I'm gonna explain how can we check the file size and restrict the user from adding a file of size more than a configured value ( say 2Mb). There are ways to check file size in the client side .
1. Use HTML5 File API.
This will work only in browsers which have HTML support ( IE 10 onwards , Chrome , FF latest versions). (IE 8 and 9 will not support this )
2. In IE ( older versions 9 below) use ActiveX objects.
- This may not work if browsers settings are not configured accordingly. In secure environment users browser might not have permission to run ActiveX objects
What we can do to check the file size in a cross-browser way.
The idea is to pass the added file to server and check the size in server and return the file size and success value . Don't worry about thinking what happens if we pass a 1GB file. It will not pass to the server anyway, instead you will get exception response like content length exceeded from network transport layer and you can catch the exception and reject the file as well.
This is nothing to do with ExtJs. We can use this with any javascript framework. I am using ExtJs framework.
See how it works !
In the "change" event of filefield control we will first validate the file for allowed extensions , then validate if it is already added or not. if these to validations passed then the file will be sent to a webform ( say filechecker.aspx) and wait for the response. If the response contains success: true then it will be added if false error message will be displayed. Meanwhile we will try to decode the Json returned from the server. if decode failed means some error in between which is nothing but http content exception.
I have implemented one more validation checking which restrict the user from adding many files with a combined size limit exceeds a configured value ( say 20Mb) like in emails. You may not be allowed to add files of total size more than say 20Mb.
Code snippet
I have pasted the code only for your idea.
In the screen shot you can see two buttons one is for adding files another is for adding hyperlink. This is my requirement. Nothing in it ! . Clicking on the add attachment button will open file dialogue and upon selecting the file you will get validation message if the validation fails otherwise the file will be added.
So Don't confuse with other stuff in my code
Just take a look at the ValidateFileSize() function
Here FilesizeChecker.aspx code
Happy coding !
In my last post I have explained the multi file upload control created in ExtJs. I have enhanced that controls to a further level as per my requirements. We can check file types , file duplication etc in the client side. We can restrict the user from adding certain file extensions. In this post I'm gonna explain how can we check the file size and restrict the user from adding a file of size more than a configured value ( say 2Mb). There are ways to check file size in the client side .
1. Use HTML5 File API.
This will work only in browsers which have HTML support ( IE 10 onwards , Chrome , FF latest versions). (IE 8 and 9 will not support this )
2. In IE ( older versions 9 below) use ActiveX objects.
- This may not work if browsers settings are not configured accordingly. In secure environment users browser might not have permission to run ActiveX objects
What we can do to check the file size in a cross-browser way.
The idea is to pass the added file to server and check the size in server and return the file size and success value . Don't worry about thinking what happens if we pass a 1GB file. It will not pass to the server anyway, instead you will get exception response like content length exceeded from network transport layer and you can catch the exception and reject the file as well.
This is nothing to do with ExtJs. We can use this with any javascript framework. I am using ExtJs framework.
See how it works !
In the "change" event of filefield control we will first validate the file for allowed extensions , then validate if it is already added or not. if these to validations passed then the file will be sent to a webform ( say filechecker.aspx) and wait for the response. If the response contains success: true then it will be added if false error message will be displayed. Meanwhile we will try to decode the Json returned from the server. if decode failed means some error in between which is nothing but http content exception.
I have implemented one more validation checking which restrict the user from adding many files with a combined size limit exceeds a configured value ( say 20Mb) like in emails. You may not be allowed to add files of total size more than say 20Mb.
Code snippet
I have pasted the code only for your idea.
In the screen shot you can see two buttons one is for adding files another is for adding hyperlink. This is my requirement. Nothing in it ! . Clicking on the add attachment button will open file dialogue and upon selecting the file you will get validation message if the validation fails otherwise the file will be added.
So Don't confuse with other stuff in my code
Just take a look at the ValidateFileSize() function
/* File Created: August 19, 2013 */
/* Author : Sebastian */
Ext.define("PrIns.controls.AttachmentControl", {
extend: 'Ext.form.Panel',
fileUpload: true,
border: 0,
alias: 'widget.attachcontrol',
requires: [
'PrIns.controls.Attachments',
'Ext.MessageBox'
],
margins: '2 2 2 2',
accept: ['pdf', 'jpg', 'png', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'bmp', 'tif', 'zip', 'ppt', 'pptx', 'txt', 'csv', 'rar', 'xps'],
frame: false,
layout: {
type: 'hbox'
},
items: [
{
xtype: 'fieldcontainer',
layout: 'vbox',
items: [
{
xtype: 'filefield',
buttonOnly: true,
flex: 1,
tooltip: '',
listeners: {
change: function (view, value, eOpts) {
// alert(value);
var parent = this.up('form');
parent.onFileChange(view, value, eOpts);
}
},
buttonConfig: {
text: '',
width: 25,
iconCls: 'add-attachment-btn',
iconAlign: 'center',
tooltip: 'Translate(Add Attachment)',
}
},
{
xtype: 'button',
width: 25,
iconAlign: 'center',
tooltip: 'Translate(Add Hyperlink)',
handler: function (button) {
var handleFunction = function (btn, text, cfg) {
if (btn == 'ok' && Ext.isEmpty(text)) {
var newMsg = '<span style="color:red">Translate(Please enter hypelink):</span>';
Ext.Msg.show(Ext.apply({}, { msg: newMsg }, cfg));
}
if (btn == 'ok' && !Ext.isEmpty(text)) {
var form = button.up('form');
var Id = form.getFirstItem();
var fileItem = [{ 'Id': Id, "FileName": text, 'AttachmentType': 'Url' }];
form.addItem(fileItem);
}
};
var customPrompt = function (title, msg, fn) {
Ext.MessageBox.show({
title: title,
msg: msg,
buttons: Ext.MessageBox.OKCANCEL,
fn: fn,
minWidth: 400,
prompt: true
});
return Ext.MessageBox;
};
customPrompt('Translate(Add Hyperlink)', 'Translate(Please enter hypelink):', handleFunction);
},
iconCls: 'add-hyperlink-btn',
flex: 1
}
]
},
{
xtype: 'tbseparator',
margin: '0 3 0 3'
},
{
xtype: 'attachments',
flex: 1
}
],
constructor: function (config) {
this.fileslist = [];
this.totalSizeLimit = 0;
this.callParent(arguments);
},
setControlValue: function (data) {
//debugger;
var me=this;
var control = Ext.ComponentQuery.query('[xtype=attachments]', this);
if (!Ext.isEmpty(control)) {
control[0].setControlValue(data);
}
},
disableControl: function (disabled) {
var fieldContainer = Ext.ComponentQuery.query('[xtype=fieldcontainer]', this);
if (!Ext.isEmpty(fieldContainer)) {
fieldContainer = fieldContainer[0];
var attachBtn = fieldContainer.items.items[0];
var hyerLinkBtn = fieldContainer.items.items[1];
attachBtn.setDisabled(disabled);
hyerLinkBtn.setDisabled(disabled);
if (disabled) {
attachBtn.buttonConfig.tooltip = '';
hyerLinkBtn.setTooltip('');
}
else {
attachBtn.buttonConfig.tooltip = 'Translate(Add Attachment)';
hyerLinkBtn.setTooltip('Translate(Add Hyperlink)');
}
}
},
getControlValue: function () {
var control = Ext.ComponentQuery.query('[xtype=attachments]', this);
if (!Ext.isEmpty(control)) {
return control[0].getControlValue();
}
},
getFirstItem: function () {
var control = Ext.ComponentQuery.query('[xtype=attachments]', this);
if (!Ext.isEmpty(control)) {
return control[0].getFirstItem();
}
},
addItem: function (itemArray) {
var control = Ext.ComponentQuery.query('[xtype=attachments]', this);
if (!Ext.isEmpty(control)) {
return control[0].addItem(itemArray);
}
},
hideHyperlink: function () {
var fieldContainer = Ext.ComponentQuery.query('[xtype=fieldcontainer]', this);
if (!Ext.isEmpty(fieldContainer)) {
fieldContainer = fieldContainer[0];
var hyerLinkBtn = fieldContainer.items.items[1];
hyerLinkBtn.hide();
}
},
setDisabled: function (disabled) {
var fieldContainer = Ext.ComponentQuery.query('[xtype=fieldcontainer]', this);
if (!Ext.isEmpty(fieldContainer)) {
fieldContainer = fieldContainer[0];
var attBtn = fieldContainer.items.items[0];
var hypBtn = fieldContainer.items.items[1];
attBtn.setDisabled(disabled);
hypBtn.setDisabled(disabled);
}
var control = Ext.ComponentQuery.query('[xtype=attachments]', this);
if (!Ext.isEmpty(control)) {
control[0].hideDeleteButton();
}
},
onFileChange: function (view, value, eOpts) {
// debugger;
var me = this;
var filename = me.extractFileName(value);
var IsValid = this.fileValidiation(view, filename);
if (!IsValid) { return; }
me.validateFileSize(view, filename)
},
validateFileSize: function (view, filename) {
// debugger
var me = this;
me.setLoading('Translate(Checking file...)');
me.getForm().submit({
url: 'FilesizeChecker.aspx',
params: { MaxSize: 2 },
success: function (form, action) {
me.OnafterValidation(view, filename,action.response.responseText);
},
failure: function (form, action) {
me.OnafterValidation(view, filename,action.response.responseText);
}
});
},
OnafterValidation: function (view, filename,reponseJson) {
var me = this;
if (!Ext.isEmpty(reponseJson))
{
var success = false;
try {
reponseJson = Ext.JSON.decode(reponseJson);
success = reponseJson.success;
} catch (e) {
}
//debugger;
var maxSize = PrIns.getApplication().Configuration.MaxFileSizeMB;
var totalFilesizeMb = PrIns.getApplication().Configuration.TotalFileSizeMB;
var totalSizeAllowed = totalFilesizeMb * 1024 * 1024;
if (!success) {
var erroMsg = Ext.String.format('Translate(The file {0} exceeds the maximum allowed size limit [{1}MB])', filename, maxSize);
var messageBox = Ext.MessageBox.show({
title: 'Translate(Add Attachment)',
msg: erroMsg,
buttons: Ext.Msg.OK,
icon: Ext.Msg.ERROR
});
view.setRawValue(null);
view.reset();
me.setLoading(false);
}
else {
// debugger
var nBytes = reponseJson.fileSize;
me.totalSizeLimit = me.totalSizeLimit + nBytes;
var filesize;
for (var aMultiples = ["KB", "MB", "GB"], nMultiple = 0, nApprox = nBytes / 1024; nApprox > 1; nApprox /= 1024, nMultiple++) {
filesize = nApprox.toFixed(2) + " " + aMultiples[nMultiple];
}
if (nBytes < 1024) {
filesize = nBytes + " Bytes"
}
filename = filename + ' (' + filesize + ')';
if (me.totalSizeLimit > totalSizeAllowed) {
var totalSize;
for (var aMultiples = ["KB", "MB", "GB"], nMultiple = 0, nApprox = me.totalSizeLimit / 1024; nApprox > 1; nApprox /= 1024, nMultiple++) {
totalSize = nApprox.toFixed(2) + " " + aMultiples[nMultiple];
}
var erroMsg = Ext.String.format('Translate(Total file size limit [{0} MB] exceeded.The file {1} cannot be attached.)', totalFilesizeMb, filename);
var messageBox = Ext.MessageBox.show({
title: 'Translate(Add Attachment)',
msg: erroMsg,
buttons: Ext.Msg.OK,
icon: Ext.Msg.ERROR
});
view.setRawValue(null);
view.reset();
me.totalSizeLimit = me.totalSizeLimit - nBytes;
me.setLoading(false);
return;
}
me.fileslist.push(filename);
var addedFilePanel = Ext.create('Ext.form.Panel', {
frame: false,
hidden: true,
border: 0,
padding: 2,
margin: '0 10 0 0',
layout: {
type: 'hbox',
align: 'middle'
},
items: []
});
var Id = me.getFirstItem();
addedFilePanel.setTitle(Id);
var newUploadControl = Ext.create('Ext.form.FileUploadField', {
buttonOnly: true,
buttonConfig: {
text: '',
width: 25,
iconCls: 'add-attachment-btn',
iconAlign: 'center',
tooltip: 'Translate(Add Attachment)',
},
listeners: {
change: function (view, value, eOpts) {
var parent = this.up('form');
parent.onFileChange(view, value, eOpts);
}
}
});
view.hide();
addedFilePanel.add(view);
// alert(Id);
var fileItem = [{ 'Id': Id, "FileName": filename, 'AttachmentType': 'File', "FileSize": nBytes }];
me.addItem(fileItem);
var fieldContainer = Ext.ComponentQuery.query('[xtype=fieldcontainer]', me);
if (!Ext.isEmpty(fieldContainer)) {
fieldContainer = fieldContainer[0];
fieldContainer.insert(0, newUploadControl);
}
me.add(addedFilePanel);
me.setLoading(false);
}
}
},
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.toLowerCase())) {
isValid = false;
// Add the tooltip below to
// the red exclamation point on the form field
var erroMsg = Ext.String.format('Translate(Please upload files with an extension of {0} only!)', this.accept.join());
me.setActiveError(erroMsg);
// Let the user know why the field is red and blank!
var messageBox = Ext.MessageBox.show({
title: 'Translate(Add Attachment)',
msg: erroMsg,
buttons: Ext.Msg.OK,
icon: Ext.Msg.WARNING
});
me.setRawValue(null);
me.reset();
}
for (var i = 0; i < this.fileslist.length; i++) {
if (this.fileslist[i].indexOf(filename) !== -1) {
isValid = false;
var erMsg = Ext.String.format('Translate(The file {0} already added)!', filename);
me.setActiveError(erMsg);
var messageBox = Ext.MessageBox.show({
title: 'Translate(Add Attachment)',
msg: erMsg,
buttons: Ext.Msg.OK,
icon: Ext.Msg.INFO
});
me.setRawValue(null);
me.reset();
break;
}
}
return isValid;
},
hasAttachments: function () {
if (!Ext.isEmpty(this.fileslist)) {
return true;
}
return false;
},
extractFileName: function (value) {
var fileNameIndex = value.lastIndexOf("/") + 1;
if (fileNameIndex == 0) {
fileNameIndex = value.lastIndexOf("\\") + 1;
}
var filename = value.substr(fileNameIndex);
filename = filename.replace('"', '');
filename = filename.replace('"', '');
return filename;
}
});
Here FilesizeChecker.aspx code
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.Configuration;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace xxxxx
{
public partial class FilesizeChecker : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
int Max_Size_In_Mb = 2; //default
try
{
Max_Size_In_Mb = int.Parse(WebConfigurationManager.AppSettings["MaxFileSizeMB"]);
}
catch (Exception)
{
}
long MaxSizeBytes = Max_Size_In_Mb * 1024 * 1024;
long fileSize = 0;
bool success = true;
for (int i = 0; i < Request.Files.Count; i++)
{
HttpPostedFile file = Request.Files[i];
if (!string.IsNullOrEmpty(file.FileName))
{
BinaryReader reader = new BinaryReader(file.InputStream);
fileSize = (long)file.InputStream.Length;
if (fileSize > MaxSizeBytes)
{
success = false;
break;
}
}
}
string json = "{success:true,fileSize:" + fileSize + "}";
if (!success)
{
json = "{success:false,fileSize:" + fileSize + "}";
}
Response.Clear();
Response.ContentType = "application/json; charset=utf-8";
Response.Write(json);
Response.End();
}
}
}
Happy coding !