In this post we are going to see how to create a file upload control with progress bar and abort options using angular js. we are going to use the existing module angular-file-upload.js , angular-file-upload-shim.js create by daniel , This needs to be add as reference to our project. Where angularFileUpload module is added as dependency module in root module.
<script src="~/Scripts/angular.js" type="text/javascript"></script>
<script src="~/Scripts/angular-route.js" type="text/javascript"></script>
<script src="~/Scripts/angular-file-upload.js" type="text/javascript"></script>
<script src="~/Scripts/angular-file-upload-shim.js" type="text/javascript"></script>
First we have to create a Directive which will acts as Fileupload control. where the directive have options like showing progress bar and abort options.
progressWidth directive change the progress bar width while uploading
var rgapp = angular.module('rgapp', ['angularFileUpload']);
rgapp.directive('progressWidth', [function () {
return {
restrict:'A',
scope: {
progressWidth:'='
},
link: function (scope, elem, attr, cntrl) {
var width = (elem.prop('offsetWidth') * scope.progressWidth) / 100
angular.element(elem.find('div')).css('width', width + 'px');
scope.$watch(function () { return scope.progressWidth; },
function (newval, oldval) {
if (newval != oldval) {
var width = (elem.prop('offsetWidth') * scope.progressWidth) /
100;
angular.element(elem.find('div')).css('width', width + 'px');
}
});
}
}
}]);
rgapp.directive('fileuploadForm', ['$upload', function ($upload) {
return {
scope: {
asyncurl: '@',
successCallback: '&',
fileselectCallback:'&',
errorCallback: '&',
inputData:'='
},
restrict: 'E',
templateUrl:'../App/templates/upload.html',
link: function (scope, element, attr, cntrl) {
scope.progressFiles = [];
var uploadingFiles = [];
var uploadFileHandlers = [];
scope.uploadedFilesString = '';
scope.uploading = function(){
for (var i = 0; i
< uploadingFiles.length; i++) {
var _file = uploadingFiles[i];
scope.progressFiles[i].isabort = false;
scope.progressFiles[i].isfinished = false;
(function (indx) {
scope.progressFiles[i].isprogress = true;
uploadFileHandlers[indx] =
$upload.upload({
url: attr.asyncurl,
method: 'POST',
file: _file,
data:
scope.inputData
})
.progress(function (prg) {
console.log("index " + indx);
scope.progressFiles[indx].progress =
Math.round((prg.loaded * 100) /
prg.total);
if (scope.progressFiles[indx].progress==100)
scope.progressFiles[indx].isfinished = true;
})
.success(function (data, status, headers, config) {
scope.progressFiles[indx].isprogress = false;
scope.progressFiles[indx].isfinished = true;
if (scope.successCallback)
scope.successCallback({
data: data, status: status,
headers: headers, config: config });
})
.error(function (data, status, headers, config) {
scope.progressFiles[i].isabort = true;
if (scope.errorCallback)
scope.errorCallback({ data: data, status: status, headers:
headers,
config: config });
});
})(i);
}
uploadingFiles = [];
scope.uploadedFilesString = '';
}
scope.abort = function (indx) {
if (uploadFileHandlers.length > indx) {
uploadFileHandlers[indx].abort();
scope.progressFiles[indx].isabort = true;
scope.progressFiles[indx].isprogress = false;
}
}
scope.close = function (indx) {
scope.progressFiles[indx].isshow = false;
}
scope.uploadedFiles = function (files) {
uploadingFiles = files;
scope.progressFiles = [];
scope.uploadedFilesString = '';
for (var i = 0; i
< uploadingFiles.length; i++) {
scope.uploadedFilesString
+= uploadingFiles[i].name + ";";
scope.progressFiles[i] =
{
isshow:true,isprogress:false, index: i, isabort: false,
isfinished: false, extn: '',filecolor:'',
filename: uploadingFiles[i].name,
size: uploadingFiles[i].size,
progress: 0, type: uploadingFiles[i].type };
scope.progressFiles[i].extn
=
scope.progressFiles[i].filename.substr(
scope.progressFiles[i].filename.lastIndexOf('.') + 1);
scope.progressFiles[i].filecolor =
scope.getExtensionFile(scope.progressFiles[i].extn);
}
if (scope.fileselectCallback)
scope.fileselectCallback({
files: files });
}
scope.browseFiles = function () {
document.getElementById('rgfile').click();
}
scope.getExtensionFile = function (extn) {
switch (extn) {
case "jpg":
case "png":
case "bmp":
return "#7b8c25";
break;
case "xls":
case "xlsx":
case "csv":
return "#468847";
break;
case "doc":
case "docx":
return "#428bca";
break;
case "ini":
case "jar":
case "zip":
return "#773472";
break;
case "exe":
return "#bce8f1";
break;
default:
return "red";
}
}
}
}
}]);
Template:
**************************
<div>
<div class="" style="width:500px">
<div class="form-inline" style="padding:20px">
<label>Files :</label>
<input type="text" ng-model="uploadedFilesString" class="form-control" />
<button ng-click="browseFiles()" class="btn btn-sm">Browse</button>
<button ng-click="uploading()" class="btn btn-sm
btn-success">Upload</button>
</div>
<div class="form-group">
<input
type="file" style="display:none" ng-file-select="uploadedFiles($files)"
class="form-control" id="rgfile"
ng-model="user.file" multiple />
</div>
<div>
<div class="panel">
<div ng-show="upfile.isshow" class="row container" style="padding:10px;"
ng-repeat="upfile in progressFiles">
<div class="col-lg-2 col-md-2
col-sm-2">
<span style="color: {{upfile.filecolor}};font-size: 40px;
position:
absolute;" class="glyphicon glyphicon-file"></span>
<span style="font-size: 12px;font-weight: 600;color: white;
position: absolute;margin-top:25px;
border-top-left-radius: 5px;width: 35px;
text-align:center">{{upfile.extn}}</span>
</div>
<div class="col-lg-5 col-md-5
col-sm-5">
<strong style="padding:5px;">File : {{upfile.filename}}</strong>
<div style="padding:5px;">Size : {{upfile.size}}</div>
</div>
<div class="col-lg-5 col-md-5
col-sm-5">
<div class="row container">
<div class="col-lg-10 col-md-9
col-sm-8">
<div style="border:1px solid green;border-radius:5px;
margin-top:10px;background-color:lightgray"
progress-width="upfile.progress">
<div ng-show="!upfile.isabort"
style="border:1px solid green;border-radius:5px;
background-color:lawngreen;width:40px;"></div>
<div ng-show="upfile.isabort"
style="border:1px solid red;border-radius:5px;
background-color:lawngreen;width:40px;"></div>
</div>
<div>
<button ng-show="upfile.isprogress"
style="margin-top:5px;"
ng-click="abort(upfile.index)"
class="btn btn-danger
btn-xs">Abort</button>
<button ng-show="upfile.isfinished"
style="margin-top:5px;"
ng-click="close(upfile.index)"
class="btn btn-success
btn-xs">Close</button>
<button ng-show="upfile.isabort"
style="margin-top:5px;"
ng-click="close(upfile.index)"
class="btn btn-warning
btn-xs">Close</button>
</div>
</div>
<div class="col-lg-2 col-md-3
col-sm-4">
<span><strong>{{upfile.progress}}%</strong>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Controller
rgapp.controller('blogcontroller', ['$scope','$upload',function ($scope,$upload) {
$scope.Files = [];
$scope.FilesData = [];
$scope.filedata = { trackingid:'', description:''};
$scope.success = function (data,status,headers,config) {
console.log('config');
console.log(config);
$scope.FilesData.push(data);
}
$scope.error = function (data,status,headers,config) {
console.log('error');
console.log(config);
}
$scope.uploadfiles = function (files) {
console.log(files);
}
$scope.uploadFile = function () {
for (var i = 0; i < $scope.Files.length; i++) {
var file = $scope.Files[i];
$upload.upload({
}).progress(function (evt) {
}).success(function (evt) {
})
}
}
$scope.uploadedFiles = function (files) {
$scope.Files = files;
}
}]);
Html:
****************
<div ng-controller="blogcontroller">
<div>
<div style="margin-left:25px;">
<fileupload-form asyncurl="~/api/Blog"
method="post"
input-data="filedata"
fileselect-callback="uploadfiles(files)"
success-callback="success(data,status,headers,config)"
error-callback="error(data,status,headers,config)">
</fileupload-form>
</div>
</div>
</div>
MVC Controller:
********************
[CheckMimeMultiPart]
public void Post()
{
try
{
var path = HttpContext.Current.Server.MapPath("~/files");
var sprovide = new MultipartFormStreamProvider(path);
await Request.Content.ReadAsMultipartAsync(sprovide);
}catch(Exception ex)
{
}
}
Output:
*********************
Once you click on the upload button, the files starts showing the progress bar with abort options like below, if you click abort then it will change the color of progress bar and shows the close button
From this post you can learn how to create a file upload control with progress bar and abort options using angular js