Uploading a file with AngularJS and bluimp on success callback of another form
Blueimp has an AngularJS version of jQuery File Upload available.
It includes a fileUpload
directive and a FileUploadController
with a submit()
method that you can call manually.
You can see a working version at http://blueimp.github.io/jQuery-File-Upload/angularjs.html.
One thing you should pay attention to: make sure you load all .js files from the example in the correct order to avoid problems (cf. source of the example page).
Hope that helps!
UPDATE AFTER YOUR COMMENT:
When using the AngularJS version of jQuery File Upload, you create a form tag with the file-upload
attribute like this:
<!-- Create a file upload form with options passed in from your scope -->
<form data-file-upload="options" data-ng-controller="YourController">
<!-- This button will trigger a file selection dialog -->
<span class="btn btn-success fileinput-button" ng-class="{disabled: disabled}">
<span>Add files...</span>
<input type="file" name="files[]" multiple="" ng-disabled="disabled">
</span>
<!-- This button will start the upload -->
<button type="button" class="btn btn-primary start" data-ng-click="submit()">
<span>Start upload</span>
</button>
<form>
Then in your controller you can assign the options for the jQuery File Upload like this:
angular.module('yourModule')
.controller('YourController', [$scope, function($scope){
// Options you want to pass to jQuery File Upload e.g.:
$scope.options = {
maxFileSize: 5000000,
acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i
};
}]);
You can assign the submit()
handler to any ng-click
attribute as long as it is inside the form (and thus can access the method).
Let me know if you need further help...
EXTRA SAMPLE CODE FOR SUCCESS CALLBACK:
If you need to run a callback function after all uploads have been completed, you can listen to the fileuploadstop
event that is broadcasted by Blueimp:
// Listen to fileuploadstop event
$scope.$on('fileuploadstop', function(){
// Your code here
console.log('All uploads have finished');
});
Hope that helps!
![Oleg Belousov](https://i.stack.imgur.com/ft76r.jpg?s=256&g=1)
Oleg Belousov
Founder of https://n.exchange - the fastest and easiest API for instant crypto exchange
Updated on September 09, 2020Comments
-
Oleg Belousov almost 4 years
I have followed the following tutorial in order to integrate the notorious bluimp jQuery file uploader in my AngularJS project.
After some research I found that in the options array, witihn the jquery.fileuploader.js file, there is an option called autoUpload, which when set to true upload the file automatically. I tried to disable it(false, undefined), but quickly I learned out that this causes the upload not to function at all, not even on the form submit.
I need to trigger the upload manually, say within another callback, or by a click event. can that be done?.
code:
app.directive("fileupload", function() { return { restrict: "A", scope: { done: "&", progress: "&", fail: "&", uploadurl: "=", customdata: "&" }, link: function(scope, elem, attrs) { var uploadOptions; uploadOptions = { url: scope.uploadurl, dataType: "json" }; if (scope.done) { uploadOptions.done = function(e, data) { return scope.$apply(function() { return scope.done({ e: e, data: data }); }); }; } if (scope.fail) { uploadOptions.fail = function(e, data) { return scope.$apply(function() { return scope.fail({ e: e, data: data }); }); }; } if (scope.progress) { uploadOptions.progress = function(e, data) { return scope.$apply(function() { return scope.progress({ e: e, data: data }); }); }; } return elem.fileupload(uploadOptions).bind("fileuploadsubmit", function(e, data) { return data.formData = { JSON.stringify(scope.customdata()) }; }); } }; }); app.service('uploadService', function(authService) { var initializeFn, processFn; initializeFn = function(e, data, process) { var upload; return upload = { message: '', uploadurl: authService.getBaseUrl() + '/applications/', status: false }; }; processFn = function(e, data, process) { var file, upload; upload = {}; upload.successData = []; upload.status = true; upload.error = false; if (process === 'done') { upload.message = data.result.result; console.log(data); file = data.result.resume; upload.successData = { // name: file.name, // fullUrl: file.url, // thumbUrl: file.thumbnail_url }; } else if (process === 'progress') { upload.message = 'Uploading....!!!'; } else { upload.error = true; upload.message = 'Please try again'; console.log(e, data); } return upload; }; return { process: processFn, initialize: initializeFn }; }); app.controller('applyCtrl', function($scope, $routeParams, uploadService){ $scope.model.formData = {}; $scope.model.formData.job = $routeParams.jobId; $scope.uploadLayer = function(e, data, process) { return $scope.uploadReturn = uploadService.process(e, data, process); }; $scope.customData = function() { return $scope.model.formData; }; return $scope.uploadReturn = uploadService.initialize(); });
view:
<form class="applyForm" ng-submit="uploadLayer(e, data, 'progress')"> <fieldset> <div class="formLine"> <div class="wideFieldContainer"> <input id="testUpload" type="file" fileupload customdata="customData()" name="resume" uploadurl="uploadReturn.uploadurl" done="uploadLayer(e, data, 'done')" fail="uploadLayer(e, data, 'fail')" progress="uploadLayer(e, data, 'progress')" /> </div> </div> </fieldset> </form>
scripts loading order:
... <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script src="lib/angular/angular.js"></script> <script src="lib/angular/angular-resource.js"></script> <script src="js/app.js"></script> <script src="js/services.js"></script> <script src="js/controllers.js"></script> <script src="js/filters.js"></script> <script src="js/directives.js"></script> <script src="lib/bluimp/js/vendor/jquery.ui.widget.js"></script> <script src="lib/bluimp/js/jquery.piframe-transport.js"></script> <script src="lib/bluimp/js/jquery.fileupload.js"></script> </body> </html>
-
Oleg Belousov almost 11 yearsIs there anyway to integrate this submit method in my current code?
-
Oleg Belousov almost 11 yearsWell, it doesn't work with my existent code, which leaves me no choice but to use the more heavy full version of the up loader, which I figured out by myself prior to asking this question. Please take a moment to observe the code and the instruction at the link that is included within my question. Thank you for you time & help
-
jvandemo almost 11 yearsThe AngularJS version of jQuery File Upload contains all directives and controllers you need to get the example working. Do you see an error when you try to run it? Can you create a plnkr so we can edit it? Thanks!
-
Oleg Belousov almost 11 yearsHere is a plunker: plnkr.co/edit/dMfWj2?p=preview My goal id to include the least libraries and external dependencies as possible, I am looking to create an agile and relatively lightweight application(from round trips and overall static files weight point of view).
-
Oleg Belousov almost 11 yearsAlso, my API requires me to post the file as multi-part along with a bunch of other formData, this is the reason why I tried the solution from the 'code like a poem blog'
-
jvandemo almost 11 yearsI created a working version of your plnkr at plnkr.co/edit/VAlEaR?p=preview. If you open the console you will notice that the upload is triggered when the button is clicked (but doesn't succeed as there is no server to send it to). If you need additional help, just let me know...
-
Oleg Belousov almost 11 yearsThank you sir, the one last thing that I need is to be able to upload from data(text fields) along with the file since the new version of my API has one endpoint for attachment and other textual data. I also took the liberty of subscribing to your blog, looks very interesting!
-
jvandemo almost 11 yearsI added additional input fields to the form in the plnkr: plnkr.co/edit/VAlEaR?p=preview. You can add any data you like (input, select, etc). It will be sent as a POST param along with the file uploads. Thanks for subscribing to my blog!
-
Oleg Belousov almost 11 yearsThanks for all of the kind help and specific explanations & examples, although you're answer doesn't solve my original problem precisely, it is most definitely correct and working, so I marked you answer as the correct one for others to learn from it. Do you actively participate on any IRC channel perhaps, so I'll be able to use your advice if I'll encounter any problems with re-factoring my code?
-
Oleg Belousov almost 11 yearsBTW, I need CORS support, can I set an external API link as my target at the form?, provided I'll add withCredentials: true to the xhrFields at the bluimp config
-
Oleg Belousov almost 11 yearsIt is weird, but for me the upload doesn't fire for some reason
-
jvandemo almost 11 yearsYes, if you need CORS support, then you'll have to enable the
withCredentials
option. Also, the server side will have to add the correct headers to accept your request. You can find the exact headers in my answer on stackoverflow.com/questions/18310394/…. The example is about Node.js but the headers are the same with any server side technology. Are you using the browser devtools to check if the upload fires? You should see the browser trying to POST to the current url (which will fail due to being on plnkr). -
Oleg Belousov almost 11 yearsIt appears that you have included the AngularJS library twice, once the 1.0.5 version, and once the 1.0.7. I took the liberty to fix that for you
-
Oleg Belousov almost 11 yearsIt is, and with cores support, the only problem is that the API calls the file field 'attachment' and bluimp calls it 'files[]' which kind of screws me up, since my friend who does the backend cannot change it right now because he is out of town without his computer. Any easy way to change the name of the file field in the request headers? Also is there any easy way to $watch the status of the upload, or at least get a success callback function within the controller in order to redirect the user upon success. Sorry for all of the dumb questions and thanks again for the help!
-
jvandemo almost 11 yearsBlueimp names it
files[]
because the example is aimed at a PHP backend that can accept multiple file uploads at the same time. You can rename it toattachment
and disable multiple uploads in the options. No need to change the headers. As for the callback I will add extra example code to my original answer... -
Oleg Belousov almost 11 yearsRenaming the field name to 'attachment' instead of files[] break the code for some reason, I suspect that the js of bluimp refers to this field as $("name['files[]']") or something
-
Oleg Belousov almost 11 yearsAlso, I was looking for a way to use the bluimp basic plugin along with Angular JS, but found no information on that topic, are you familiar with any blog post or article on this topic?
-
jvandemo almost 11 yearsBlueimp will use
files[]
as the default input name. If you change it in the form, you will also have to pass it as an option (I believe it is calledfileInput
but it is best to check the source/docs of the version you are using). As for the basic version, I don't have any experience with that I'm affraid... -
Oleg Belousov almost 11 yearsChecked the docs, it is indeed fileInput, the irony is that the source is documented better than the project it self. I ended up changing the jquery.fileupload.js file, but i believe that those options can also be passed as $Scope.options. NO I only need to make some visual enhancements such as displaying the selected file name, and a progress bar perhaps
-
jvandemo almost 11 yearsAwesome, glad you finally got it working. I would highly recommend not to change the
jquery.fileupload.js
but rather use theoptions
to pass in the file input name to allow for future maintainability when upgrading to a newer version. -
Oleg Belousov almost 11 yearsAgh, now I cannot display the selected file and cannot show the progress bar and the pretty UI options :(
-
merveotesi over 10 yearsHi, can you look at the question: stackoverflow.com/questions/21047204/…
-
revolutionNET over 9 yearsNice answer, I want to preview the image before upload with 100% wdth and height, what should I do?
-
Shivendra about 8 yearsSomebody there? i wanted to ask that when
fileuploadstop
event is successfully fired, how can I see the data that is returned back. I passed thedata
parameter in the function but it is not giving much information like it used to give in the simple jquery version of the blueimp library.