I actually have rolled my own uploader once... but only because I didn't like any of the already made JQuery ones. Unfortunately that's proprietary and I can't post it on the internet... but... I can show you how to use just about any JQuery plugin from Angular:
Someone will probably say that its easy to use an existing uploader and integrate it into AngularJS - to that i'll say: if its easy then someone should have done it already.
Let's presume I have a jQuery plugin that works by selecting a div and calling pluginUploadCall()
on it...
app.directive('myJqueryPluginUploader', function() {
return {
restrict: 'A',
link: function(scope, elem, attr, ctrl) {
// elem is a jQuery lite object
// or a jQuery object if jQuery is present.
// so call whatever plugins you have.
elem.pluginUploadCall();
}
};
});
And here's how it would be used.
<div my-jquery-plugin-uploader></div>
Angular actually integrates really well with jQuery so any plugins that work in jQuery should work pretty easily in Angular. The only trickiness comes in when you want to keep Dependency Injection alive so you can keep your Angular App testable. JQuery isn't very good at DI, so you may have to jump through some hoops.
If you wanted to roll your own, I can tell you I did something like this:
app.directive('customUploader', function(){
return {
restrict: 'E',
scope: {},
template: '<div class="custom-uploader-container">Drop Files Here<input type="file" class="custom-uploader-input"/><button ng-click="upload()" ng-disabled="notReady">Upload</button></div>',
controller: function($scope, $customUploaderService) {
$scope.notReady = true;
$scope.upload = function() {
//scope.files is set in the linking function below.
$customUploaderService.beginUpload($scope.files);
};
$customUploaderService.onUploadProgress = function(progress) {
//do something here.
};
$customUploaderService.onComplete = function(result) {
// do something here.
};
},
link: function(scope, elem, attr, ctrl) {
fileInput = elem.find('input[type="file"]');
fileInput.bind('change', function(e) {
scope.notReady = e.target.files.length > 0;
scope.files = [];
for(var i = 0; i < e.target.files.length; i++) {
//set files in the scope
var file = e.target.files[i];
scope.files.push({ name: file.name, type: file.type, size: file.size });
}
});
}
});
Where $customUploaderService
would be a custom service you create with Module.factory()
that uses $http
to post the files and check the progress on the server.
I know that's vague, and I'm sorry that's all I can provide, but I hope that helps.
EDIT: The drag and drop file upload is a bit of a trick of CSS, BTW... for Chrome and FF, what you do is put the in a containing div... then do something like this:
<div class="uploadContainer">Drop Files Here<input type="file"/></div>
div.uploadContainer {
position: relative;
width: 600px;
height: 100px;
}
div.uploadContainer input[type=file] {
visibility: hidden;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
... now anything you drop on that div will really be dropped on the file upload, and you can make the div look like whatever you want.