There's a significant amount of code in this project, so I don't know how much I actually want to explain in this blog post directly. To me, the most interesting part of this experiment is that I used both a primary uploader (a Plupload "Uploader" instance) and a secondary dropzone (a mOxie "FileDrop" instance). Both of these were encapsulated within AngularJS directives and cross-communicated using the native event system provided by the AngularJS scope chain.
The two Plupload-related directives in the above code are:
The first handles the primary uploader that supports both "drag-n-drop" and "click-to-select" interactions. This is the instance that actually takes care of POSTing the files to the server.
The second directive handles "drag-n-drop" interaction for the list. But, not only does it allow files to be dropped, it allows them to be dropped in a specific area of the list. This latter aspect, the targeted drop, was what took about 90% of the effort of this entier experiment. Overall, this project took about 2 full days to build and the majority of that time was spent trying to figure out how to get the drop-indicators to show in the right place in the list during the drag events.
If you haven't dealt with drag events yet, they are a complete nightmare! Not only are they a quirky in a cross-browser sense, they also fire in counter-intuitive ways that make them dang-near impossible to work with. If you look at my second directive, you'll see that I basically fallback to using a timer that constantly resets itself. This is terribly inefficient; but, after hour and hours of dead-ends and outlier situations, this was the only thing that I could get to work in all the browsers (including IE 10, which now supports drag-n-drop).
As I move forward with these Plupload / AngularJS experiments, I'll keep trying to think about how to best encapsulate things. You might be tempted to simply wrap Plupload in a generic directive; but I'm not sure that it's actually feasible to do that. As the interactions become more granular, and cross-instance communication is required, I think you'd have to start jumping through unnecessarily-complex hoops in an effort to keep Plupload completely back-boxed.
Hopefully more fun and interesting stuff to come!
Want to use code from this post? Check out the license.
Good stuff. Good stuff.
Thanks my man. Not that it's entirely on-topic, that is to say, not entirely off-topic either, I did a follow-up post on generating per-file Amazon S3 "upload policies":
Plupload is pretty bad-ass. A very well executed library.
Really nice and wonderful effors. Love this blog
What is happeneing in the ImagesController and what all libraries should I import to make file uploading work?
Thank you Ben for such a good tutorial. Can you also write a post on how to upload video files in Angular?
I was originally using Dropzone at my job but switched to Plupload for the chunked uploading. Using your example from Github has been extremely useful in determining how to structure my code. And now large file uploading works! Thanks so much. Love your work.