I'm working on an app that will have file uploads. I want to create a reusable file upload component that be can be included on any of the pages that need file upload functionality. I was originally thinking that I could just use a JSP tag. However, we recently discovered AngularJS and now want to use it throughout the app. So, I want to create a directive that will allow me to simply put a <myApp-upload>
tag to stick in my upload functionality.
I first made my upload functionality it's own HTML page to make sure the AngularJS was playing nicely with the Plupload plugin. I put together something like this:
<html ng-app="myApp">
<head>
<script src="resources/scripts/angular-1.0.1.min.js"></script>
<script src="resources/scripts/myApp.js"></script>
</head>
<body>
<style type="text/css">@import url(resources/scripts/plupload/jquery.plupload.queue/css/jquery.plupload.queue.css);</style>
<script type="text/javascript" src="resources/scripts/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="resources/scripts/plupload/plupload.full.js"></script>
<script type="text/javascript" src="resources/scripts/plupload/jquery.plupload.queue/jquery.plupload.queue.js"></script>
<div id="uploadContainer" ng-controller="FileUploadCtrl">
<div id="dropArea" style="border: 1px black dashed;">Drag files to here<br><br><br></div>
Files to upload:<br>
<div ng-repeat="currFile in uploader.files">{{currFile.name}} ({{currFile.size}})</div>
<br><br>
<!-- For debugging -->
{{uploader.files}}
</div>
</body>
</html>
The myApp.js looks like this:
function FileUploadCtrl($scope)
{
$scope.uploader = new plupload.Uploader({
runtimes : 'html5,flash,html4',
url : 'media/upload',
max_file_size : '10mb',
container: 'uploadContainer',
drop_element: 'dropArea'
});
$scope.uploader.init();
$scope.uploader.bind('FilesAdded', function(up, files) {
$scope.$apply();
});
}
When I drag files in, I see the file names appear and the output of {{uploader.files}} change from []
to the files in the uploader object. So, now I want to make it into a directive. I take all the content that's in the body tag and save it to a file called upload.html. I then added the following to myApp.js:
angular.module('myApp', [])
.directive('myAppUpload', function () {
return {
restrict: 'E',
templateUrl: 'upload.html',
};
});
Then, I have an HTML file like this:
<html ng-app="myApp">
<head>
<script src="resources/scripts/angular-1.0.1.min.js"></script>
<script src="resources/scripts/myApp.js"></script>
</head>
<body>
<myApp-upload>
This will be replaced
</myApp-upload>
</body>
</html>
When I load this HTML page, the <myApp-upload>
tag does bring in the upload.html file. However, it doesn't do any of the data binding. At the bottom I see {{uploader.files}}
instead of []
that I was seeing initially when it was it's own page.
I'm very new to AngularJS, so I'm sure I'm just missing something, or doing something wrong. How do I get this directive working?
I figured out my problem. I was including all the javascript and CSS on my template HTML page. I tried moving it to the main HTML file, and then it worked. In other words, I moved
<style type="text/css">@import url(resources/scripts/plupload/jquery.plupload.queue/css/jquery.plupload.queue.css);</style>
<script type="text/javascript" src="resources/scripts/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="resources/scripts/plupload/plupload.full.js"></script>
<script type="text/javascript" src="resources/scripts/plupload/jquery.plupload.queue/jquery.plupload.queue.js"></script>
from the upload.html file to the main, index.html file.
The javascript was dying when trying to call some Plupload stuff in the the script hadn't had a chance to be included yet.
We just created an Angular directive for plUpload. Check here.