AngularJS HTML5 Download Directive
directive to create client side downloads
HTML
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.min.js"></script>
<div ng:init="filedata = 'Your file content'; name = 'your_file'; fileurl = 'https://www.google.be/images/srpr/logo3w.png'">
<a ng:download="'{{name}}.txt'" content="filedata" draggable>Download or drag to desktop</a>
<br>
<br>
</div>
CoffeeScript
class DownloadDirective
@$inject: ['$window']
constructor: (window) ->
@URL = window.webkitURL or window.URL
@Blob = window.Blob
restrict: 'A'
link: (scope, element, attrs) =>
a = element[0]
if a.draggable
element.bind "dragstart", (event) ->
event.originalEvent.dataTransfer.setData "DownloadURL", a.dataset.downloadurl
a.href = '#'
element.click -> no if a.href == '#'
attrNames = ['ngDownload', 'mimeType', 'url', 'content']
updateDom = =>
[filename, mimeType, url, content] = (scope.$eval attrs[attr] for attr in attrNames)
filename or= 'file'
mimeType or= 'text/plain'
if url?
@setupUrlDownload a, url, filename, mimeType
else if content?
@setupDataDownload a, content, filename, mimeType
watchers = {}
for attr in attrNames
do (attr) ->
attrs.$observe attr, (attrValue) ->
watchers[attr]() if watchers[attr]?
watchers[attr] = scope.$watch attrValue, updateDom if attrValue
setupUrlDownload: (a, url, filename, mimeType) =>
@URL.revokeObjectURL a.href if a.href != '#'
a.download = filename
a.href = url
a.dataset.downloadurl = [mimeType, a.download, a.href].join(":")
setupDataDownload: (a, data, filename, mimeType) =>
blob = new @Blob [data], type: mimeType
url = @URL.createObjectURL blob
@setupUrlDownload a, url, filename, mimeType
app = angular.module 'app', []
buildDirectiveFactory = (ctor) ->
factory = (args...) -> new ctor args...
factory.$inject = ctor.$inject
factory
app.directive 'ngDownload', buildDirectiveFactory DownloadDirective
angular.bootstrap document, ['app']