forked from twilson63/ngUpload
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
updated 3.0 - refactored to use angularjs directive for submit control
- Loading branch information
Tom Wilson
committed
Mar 11, 2013
1 parent
0e32a4a
commit 9988098
Showing
10 changed files
with
381 additions
and
215 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# 0.3.0 | ||
|
||
* Refactored API | ||
|
||
Now there are two directives, ng-upload on your upload form and | ||
upload-submit on your clickable submit object. This new pattern | ||
is more angularjs like and you can declare these directives as | ||
attributes or classes. | ||
|
||
see the examples | ||
|
||
|
||
# 0.2.1 | ||
|
||
* Added test | ||
* Modified callback function to use angularjs $parse | ||
* Removed explict usage of $ as jQuery | ||
|
||
# 0.2.0 | ||
|
||
* Bug fixes and enahncements (#12 and #13) | ||
* Addition of an example to demonstrate using ngUpload to submit a full form, with a file input and other types of inputs, to the server. | ||
* Example also demonstate how to consume a JSON returned by the server in Angular. (Checkout example 5 on the demo page(s) - [ASP.Net MVC](http://ng-upload.azurewebsites.net) or [NodeJS](http://ng-upload.eu01.aws.af.cm/). | ||
|
||
## Update 0.1.1 | ||
|
||
* ngUpload is now an AngularJS Directive, removing the need to deal with the form[@id] attribute. | ||
* Addition of the __uploadOptionsEnableControls__ option to prevent the default disabling of submission controls during upload, like so: | ||
``` html | ||
<form ng-upload='callbackFunction(contents, completed)' uploadOptionsEnableControls> | ||
... | ||
</form> | ||
``` | ||
_Submission controls are html elements marked with the **upload-submit** css class_. | ||
* Some bug fixes. | ||
|
||
|
||
This source code of this example is given below: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,112 +1,106 @@ | ||
// Version 0.2.0 | ||
// Version 0.3.0 | ||
// AngularJS simple file upload directive | ||
// this directive uses an iframe as a target | ||
// to enable the uploading of files without | ||
// losing focus in the ng-app. | ||
// | ||
// <div ng-app="app"> | ||
// <div ng-controller="mainCtrl"> | ||
// <form action="/uploads" ng-upload="results()"> | ||
// <form action="/uploads" ng-upload> | ||
// <input type="file" name="avatar"></input> | ||
// <input type="submit" value="Upload"></input> | ||
// <input type="submit" value="Upload" | ||
// upload-submit="submited(content, completed)"></input> | ||
// </form> | ||
// </div> | ||
// </div> | ||
// | ||
// angular.module('app', ['ngUpload']) | ||
// .controller('mainCtrl', function($scope) { | ||
// $scope.results = function(content) { | ||
// console.log(content); | ||
// $scope.submited = function(content, completed) { | ||
// if (completed) { | ||
// console.log(content); | ||
// } | ||
// } | ||
// }); | ||
// | ||
angular.module('ngUpload', []) | ||
.directive('ngUpload', ['$parse', function ($parse) { | ||
.directive('uploadSubmit', ['$parse', function($parse) { | ||
return { | ||
restrict: 'A', | ||
link: function (scope, element, attrs) { | ||
|
||
restrict: 'AC', | ||
link: function(scope, element, attrs) { | ||
// Options (just 1 for now) | ||
// Each option should be prefixed with 'upload-Options-' or 'uploadOptions' | ||
// 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); | ||
// Retrieve the callback function | ||
var fn = $parse(attrs.uploadSubmit); | ||
|
||
if (!angular.isFunction(fn)) { | ||
var message = "The expression on the ngUpload directive does not point to a valid function."; | ||
throw message + "\n"; | ||
}; | ||
|
||
element.bind('click', function() { | ||
// 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)) | ||
element.attr('disabled', null); | ||
element.attr('title', 'Click to start upload.'); | ||
}); | ||
|
||
// add the new iframe to application | ||
//element.parents('form').parent().append(iframe); | ||
scope.uploadForm.parent().append(iframe); | ||
|
||
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 () { | ||
scope.$apply(function () { | ||
fn(scope, {content: "Please wait...", completed: false | ||
} /* upload not completed */); }); | ||
|
||
// 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); | ||
var enabled = true; | ||
if (!options.enableControls) { | ||
// disable the submit control on click | ||
element.attr('disabled', 'disabled'); | ||
enabled = false; | ||
} | ||
|
||
//if (options.enableControls == null || !(options.enableControls.length >= 0)) | ||
submitControl.attr('disabled', null); | ||
submitControl.attr('title', 'Click to start upload.'); | ||
}); | ||
element.attr('title', (enabled ? '[ENABLED]: ' : '[DISABLED]: ') + 'Uploading, please wait...'); | ||
|
||
// add the new iframe to application | ||
element.parent().append(iframe); | ||
}; | ||
// submit the form | ||
scope.uploadForm.submit(); | ||
|
||
// 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 () { | ||
console.log('foo'); | ||
|
||
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."); | ||
}).attr('title', 'Click to start upload.'); | ||
} | ||
} | ||
}]) | ||
.directive('ngUpload', ['$parse', function ($parse) { | ||
return { | ||
restrict: 'AC', | ||
link: function (scope, element, attrs) { | ||
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"); | ||
scope.uploadForm = element; | ||
} | ||
} | ||
}; | ||
}]); | ||
}]); |
Oops, something went wrong.