Skip to content

Commit

Permalink
added spec and refactored out $ dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom Wilson committed Mar 10, 2013
1 parent 3921fdc commit 4d732f1
Show file tree
Hide file tree
Showing 31 changed files with 16,813 additions and 348 deletions.
Binary file added .DS_Store
Binary file not shown.
Binary file added examples/.DS_Store
Binary file not shown.
Binary file added examples/nodejs/.DS_Store
Binary file not shown.
24 changes: 12 additions & 12 deletions examples/nodejs/index.html
Expand Up @@ -27,7 +27,7 @@ <h1>Example 1 - Running with default configuration (requirement: v0.1.1 and abov
<span>Current value of foo is: <b>{{foo}}</b>. <i>(Works with the active $scope.)</i></span>
<br />
<br />
<form ng-upload="bar" action="/upload?delay=yes">
<form ng-upload="bar(content)" method="POST" action="/upload?delay=yes">

This comment has been minimized.

Copy link
@adebisi-fa

adebisi-fa Mar 10, 2013

Contributor

What's the usage scenario enabled by this change? Why would someone want to pass an argument to a function meant to be called by the ng-upload.js code whenever the hidden iframe finished loading?

I can't really figure out any use case for this modification(s). The ng-upload directive only needs the name of a function to report to whenever it finished loading the dynamic iframe. The arguments passed when such occurs is meant to be consumed in the context ngController code; thus, making the argument's present on the view, unimportant.

I'm I missing anything please?

<p>
<label>Select a file to upload:</label>
<input type="file" name="file" />
Expand All @@ -53,7 +53,7 @@ <h1>Example 2 - Using Options: <b>uploadOptionsEnableControls</b> option (requir
</span>
<br />
<br />
<form ng-upload="uploadFile" action="/upload?delay=yes" upload-options-enable-controls>
<form ng-upload="uploadFile(content)" action="/upload?delay=yes" upload-options-enable-controls>
<p>
<label>Select a file to upload:</label>
<input type="file" name="file" />
Expand All @@ -68,7 +68,7 @@ <h1>Example 2 - Using Options: <b>uploadOptionsEnableControls</b> option (requir
<h1>Example 3 - Submitting forms with any html element (requirement: v0.1.1 and above)</h1>
<span>This examples show how to use any html element to submit your form. It makes use of a 'div', an 'a', and an 'img' tags to submit the same form.</span>
<br />
<form ng-upload="uploadFile" action="/upload?delay=yes">
<form ng-upload="uploadFile(content, completed)" action="/upload?delay=yes">
<p>
<label>Select a file to upload:</label>
<input type="file" name="file" />
Expand Down Expand Up @@ -97,7 +97,7 @@ <h1>Example 4 - Processing Callback Function Contents (requirement: v0.2.0 and a
<br /><br />
<span style="font-size: 15px">Example 4.1: The example below displays all statuses, without inspection.</span>
<br /><br />
<form ng-upload="uploadFile1" action="/upload?delay=yes">
<form ng-upload="uploadFile1(content, completed)" action="/upload?delay=yes">
<p>
<label>Select a file to upload:</label>
<input type="file" name="file" />
Expand All @@ -110,7 +110,7 @@ <h1>Example 4 - Processing Callback Function Contents (requirement: v0.2.0 and a
<br />
<span style="font-size: 15px">Example 4.2: The example below displays only the server response, ignoring other contents</span>
<br /><br />
<form ng-upload="uploadFile2" action="/upload?delay=yes">
<form ng-upload="uploadFile2(content, completed)" action="/upload?delay=yes">
<p>
<label>Select a file to upload:</label>
<input type="file" name="file" />
Expand All @@ -125,7 +125,7 @@ <h1>Example 4 - Processing Callback Function Contents (requirement: v0.2.0 and a
<h1>Example 5 - Processing a full form (requirement: v0.2.0)</h1>
Post a full form with a file and other inputs (text, etc) to the server and get a JSON result.
<br /><br />
<form ng-upload="uploadComplete" action="/upload-full-form">
<form ng-upload="uploadComplete(content, completed)" action="/upload-full-form">
<p>
<label>Fullname:</label>
<input type="text" name="fullname" ng-model="fullname" />
Expand Down Expand Up @@ -163,7 +163,7 @@ <h1>Example 5 - Processing a full form (requirement: v0.2.0)</h1>
var app = angular.module('ngUploadApp', ['ngUpload']);
app.controller('Example1Ctrl', function ($scope) {
$scope.foo = "Hello World";
$scope.bar = function (content) {
$scope.bar = function(content) {
console.log(content);
$scope.uploadResponse = content;
}
Expand All @@ -184,23 +184,23 @@ <h1>Example 5 - Processing a full form (requirement: v0.2.0)</h1>
});

app.controller('Example4Ctrl', function ($scope) {
$scope.uploadFile1 = function (content, isComplete) {
$scope.uploadFile1 = function (content, completed) {
console.log(content);
$scope.uploadResponse1 = content;
};

$scope.uploadFile2 = function (content, isComplete) {
$scope.uploadFile2 = function (content, completed) {
console.log(content);
if (isComplete)
if (completed)
$scope.uploadResponse2 = "[Status: Completed] " + content;
else
$scope.uploadResponse2 = "[Status: Incomplete] Content ignored. Check log the actual content.";
}
});

app.controller('Example5Ctrl', function ($scope) {
$scope.uploadComplete = function (content, isComplete) {
if (isComplete && content.length > 0)
$scope.uploadComplete = function (content, completed) {
if (completed && content.length > 0)
{
$scope.response = JSON.parse(content); // Presumed content is a json string!
$scope.response.style = {
Expand Down
Binary file added examples/nodejs/libs/.DS_Store
Binary file not shown.
181 changes: 88 additions & 93 deletions examples/nodejs/libs/js/ng-upload.js
Expand Up @@ -21,96 +21,91 @@
// });
//
angular.module('ngUpload', [])
.directive('ngUpload', function () {
return {
restrict: 'A',
link: function (scope, element, attrs) {

// Options (just 1 for now)
// Each option should be prefixed with 'upload-Options-' or 'uploadOptions'
// {
// // specify whether to enable the submit button when uploading forms
// enableControls: bool
// }
var options = {};
options.enableControls = attrs['uploadOptionsEnableControls'];

// get scope function to execute on successful form upload
if (attrs['ngUpload']) {

element.attr("target", "upload_iframe");
element.attr("method", "post");

// Append a timestamp field to the url to prevent browser caching results
element.attr("action", element.attr("action") + "?_t=" + new Date().getTime());

element.attr("enctype", "multipart/form-data");
element.attr("encoding", "multipart/form-data");

// Retrieve the callback function
var fn = attrs['ngUpload'].split('(')[0];
var callbackFn = scope.$eval(fn);
if (callbackFn == null || callbackFn == undefined || !angular.isFunction(callbackFn))
{
var message = "The expression on the ngUpload directive does not point to a valid function.";
// console.error(message);
throw message + "\n";
}

// Helper function to create new iframe for each form submission
var addNewDisposableIframe = function (submitControl) {
// create a new iframe
var iframe = $("<iframe id='upload_iframe' name='upload_iframe' border='0' width='0' height='0' style='width: 0px; height: 0px; border: none; display: none' />");

// attach function to load event of the iframe
iframe.bind('load', function () {

// get content - requires jQuery
var content = iframe.contents().find('body').text();

// execute the upload response function in the active scope
scope.$apply(function () { callbackFn(content, content !== "" /* upload completed */); });

// remove iframe
if (content != "") // Fixes a bug in Google Chrome that dispose the iframe before content is ready.
setTimeout(function () { iframe.remove(); }, 250);

//if (options.enableControls == null || !(options.enableControls.length >= 0))
submitControl.attr('disabled', null);
submitControl.attr('title', 'Click to start upload.');
});

// add the new iframe to application
element.parent().append(iframe);
};

// 1) get the upload submit control(s) on the form (submitters must be decorated with the 'ng-upload-submit' class)
// 2) attach a handler to the controls' click event
$('.upload-submit', element).click(
function () {

addNewDisposableIframe($(this) /* pass the submit control */);

scope.$apply(function () { callbackFn("Please wait...", false /* upload not completed */); });

//console.log(angular.toJson(options));

var enabled = true;
if (options.enableControls === null || options.enableControls === undefined || options.enableControls.length >= 0) {
// disable the submit control on click
$(this).attr('disabled', 'disabled');
enabled = false;
}

$(this).attr('title', (enabled ? '[ENABLED]: ' : '[DISABLED]: ') + 'Uploading, please wait...');

// submit the form
$(element).submit();
}
).attr('title', 'Click to start upload.');
}
else
console.log("No callback function found on the ngUpload directive.");
}
};
});
.directive('ngUpload', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function (scope, element, attrs) {

// Options (just 1 for now)
// Each option should be prefixed with 'upload-Options-' or 'uploadOptions'
// {
// // specify whether to enable the submit button when uploading forms
// enableControls: bool
// }
var options = {};
options.enableControls = attrs.uploadOptionsEnableControls;

// get scope function to execute on successful form upload
if (attrs.ngUpload) {

element.attr("target", "upload_iframe");
element.attr("method", "post");

// Append a timestamp field to the url to prevent browser caching results
element.attr("action", element.attr("action") + "?_t=" + new Date().getTime());

element.attr("enctype", "multipart/form-data");
element.attr("encoding", "multipart/form-data");

// Retrieve the callback function
var fn = $parse(attrs.ngUpload);

if (!angular.isFunction(fn)) {
var message = "The expression on the ngUpload directive does not point to a valid function.";
throw message + "\n";
}

// Helper function to create new iframe for each form submission
var addNewDisposableIframe = function(submitControl) {
// create a new iframe
var iframe = angular.element("<iframe id='upload_iframe' name='upload_iframe' border='0' width='0' height='0' style='width: 0px; height: 0px; border: none; display: none' />");

// attach function to load event of the iframe
iframe.bind('load', function () {

// get content - requires jQuery
var content = iframe.contents().find('body').text();
// execute the upload response function in the active scope
scope.$apply(function () {
fn(scope, { content: content, completed: content !== ""});
});
// remove iframe
if (content !== "") // Fixes a bug in Google Chrome that dispose the iframe before content is ready.
setTimeout(function () { iframe.remove(); }, 250);

//if (options.enableControls == null || !(options.enableControls.length >= 0))
submitControl.attr('disabled', null);
submitControl.attr('title', 'Click to start upload.');
});

// add the new iframe to application
element.parent().append(iframe);
};

// 1) get the upload submit control(s) on the form (submitters must be decorated with the 'ng-upload-submit' class)
// 2) attach a handler to the controls' click event
var submitControl = element.find('.upload-submit');
submitControl.bind('click', function () {

addNewDisposableIframe(submitControl /* pass the submit control */);

scope.$apply(function () { fn(scope, {content: "Please wait...", completed: false } /* upload not completed */); });

var enabled = true;
if (options.enableControls === null || options.enableControls === undefined || options.enableControls.length >= 0) {
// disable the submit control on click
submitControl.attr('disabled', 'disabled');
enabled = false;
}

submitControl.attr('title', (enabled ? '[ENABLED]: ' : '[DISABLED]: ') + 'Uploading, please wait...');

// submit the form
element.submit();
}).attr('title', 'Click to start upload.');
}
else
console.log("No callback function found on the ngUpload directive.");
}
};
}]);
113 changes: 0 additions & 113 deletions examples/nodejs/ng-upload.js

This file was deleted.

0 comments on commit 4d732f1

Please sign in to comment.