Treehouse

Downloadify: Client-Side File Generation Using JavaScript and Flash

By on  

The following tools is in its very beta stages and works intermittently. Its so damn useful that I had to show it off now though!

I recently stumbled upon Downloadify, a client-side file generation tool based on JavaScript and Flash ActionScript code. A huge advantage to creating files on the client-side is that you can reduce the load on the server -- especially when there's no need for the server to get involved (the data is available within the page, etc.) Lets take a look at how we can use Downloadify.

Downloadify Usage

Downloadify.create('downloader',{
  filename: function(){
    return 'secret-message.txt'; //static file -- you could retrieve from form input box
  },
  data: function(){ 
    return 'MooTools FTW!'; //static content -- you could retrieve from form input box
  },
  onComplete: function(){ 
    alert('The file has been saved!'); 
  },
  onCancel: function(){ 
    alert('You have cancelled the saving of this file.');
  },
  onError: function(){ 
    alert('Error!  Damn!'); 
  },
  transparent: false,
  swf: 'media/downloadify.swf',
  downloadImage: 'images/download.png',
  width: 210,
  height: 55,
  transparent: true,
  append: false
});

Downloadify provides numerous options which you may pass per instance within the create method -- this should look familiar to notice to advanced JavaScript users. What I really love about Downloadify is that it provides just the right amount of customization -- events and filename/content settings. Too many JavaScript classes/functions try to do too much; Downloadify gets it right. My only criticism of Downloadify is it's requirement of a 4-state sprite; it would be great if that were an option or the ActionScript could detect the height setting vs. the image file's actual height and use the sprite if available.

MooTools Helper

/* mootools helper */
if(typeof(MooTools) != 'undefined'){
	Element.implement({
		downloadify: function(options) {
			options = $merge(Downloadify.defaultOptions,options);
			return this.store('Downloadify',Downloadify.create(this,options));
		}
	});
}

Downloadify comes with a jQuery helper but not a MooTools helper...I've remedied this.

Downloadify fills a need for many developers. Avoid unnecessary server load and jump on Downloadify!

ydkjs-6.png

Recent Features

Incredible Demos

  • Fading Links Using jQuery: dwFadingLinks

    UPDATE: The jQuery website was down today which caused some issues with my example. I've made everything local and now the example works. Earlier this week, I posted a MooTools script that faded links to and from a color during the mouseover and mouseout events....

  • MooTools ContextMenu Plugin

    ContextMenu is a highly customizable, compact context menu script written with CSS, XHTML, and the MooTools JavaScript framework. ContextMenu allows you to offer stylish, functional context menus on your website. The XHTML Menu <ul id="contextmenu"> <li><a href="#edit" class="edit">Edit</a></li> <li class="separator"><a href="#cut" class="cut">Cut</a></li> <li><a href="#copy" class="copy">Copy</a></li> <li><a href="#paste" class="paste">Paste</a></li> <li><a href="#delete" class="delete">Delete</a></li> <li...

Discussion

  1. Now that is something useful (hey, I’m not saying the rest isn’t)!

    I always wondered if that could be done client-side, instead of downloading an already existing file on the server.
    As the tool get more and more supported, I hope to see more “usage-exemple” of it.

  2. Trae Robrock

    Great tool and thanks for the MooTools helper, that seems to be something lacking of a lot of addons I find. I think I’ll get a lot of use out of this. By the way, should that transparent option be in there twice?

  3. Hey David! I was super excited to see you post on this! I’d love to discuss the intermittent issues with you and see if they can’t be resolved. Also, can I add your MooTools helper to the core Downloadify download? I started to work on adding it originally, but I haven’t worked with MooTools in such a long time :(.

    I am about to start work on getting it to support saving binary files, and hope to put together a demo combining it with JSZip to dynamically create zip files containing full directory trees and files.

    Thanks again for covering the project!

  4. Hey Doug!

    Great work on the project! A few things:

    1. The intermittent issue was on Windows XP. And I think it was flat out deciding not to work. I’ll look at it more tomorrow.

    2. Definitely add the MooTools helper! I just retested it and it works wonderfully.

    Be sure to keep me up to speed on the project — it’s something I was so happy to see that I almost cried! :)

    David

  5. I must be missing something. I understand that this script’s advantage is to reduce the number of calls to the server by allowing to download (most likely small) files containing informations which are already available on the page/in the DOM. It might be useful in some very specific usage (for example a popular SNS which would allow to download vcard files or an intranet with accessed with javascript-enabled and flash-enabled browser (sounds like a dream)) but pretty useless or even harmful in general since Downloadify consists of two files with a total size of 5ko/KB (most likely more than the file’s size). That would mean two http requests to the server even if the user doesn’t actually want to download the file. There would also be our actual “content formatter” script which could get quite lengthy.

    As I said I must be missing something. Reading about any real world use could be enlightening.

  6. Nicolas

    This should be doable without Flash.

    Right click here and select ‘save to disk’

  7. Nicolas

    Okay I didn’t expect this crap to actually parse HTML.

    Second try:
    <a href=”data:text/plain,Hello world”>Right click here and select ‘save to disk’</a>

  8. @Nicolas: There seems to be large misunderstanding of the limitations of data URI’s. First there is limited browser support. Second, you cannot pre-supply a file name. Finally, having worked for the last number of years to make sure a user never has to “right click and choose save” to download by setting proper headers, etc, it sure feels like 3 steps backwards in the interest of progress.

    I think browsers will get there eventually, but I really think we are a few years out to get what I consider serious usability issues worked out as well full cross-browser support.

  9. brett

    I agree with Kevin, can you give a real world example of its usefulness?

  10. @brett, @Kevin: Easy. I hope to use this on my site site. Look at 95% of my posts. I have code snippets everywhere. I’d love to offer a “download snippet” link which would use Downloadify. I find it hard to believe you couldn’t thing of a use for this.

  11. @David Walsh: Though I wonder what the added bonus of using this over the tried-and-proven method of letting your language of choice crank out the proper headers to trigger a file download. Thoughts?

  12. @Dave: This isn’t a replacement for that method at all. This is so front end functionality (for instance David’s code snippets) can be downloaded without server interaction. If David wanted to add that functionality without Downloadify, he would have to post every snippet back to the server before he could trigger a download of the data.

    One benefit of this is that the download triggers instantly. On an overtaxed server, and when data can be repurposed on the client side, this will greatly increase speed to download.

    The sample project that uses this as a good example is http://starter.pixelgraphics.us It is a plugin starter for jQuery. Once the page loads, the user can generate as many variations as they want without any trips to the server.

  13. @Douglas Neiner: Ok, that makes sense, didn’t think about it like that :)

  14. Aditya

    I tried initiating the downloadify object with the Mootools Swiff plugin, but had not success. Is it possible to do so?

  15. David
    I just wanted to run a couple of things out there.
    1) It took me a couple of hours before I figured out that I needed a place holder in the form of an element that had the id=downloadify.
    2) I have a web page that lets users define the parts they want on a bike, much like a web page that lets users define their build on building a computer.
    All my code is javascript on the client side and the downloadify looked like a good solution to getting the information into a spread sheet through .csv file.
    It works very nicely and I was able to put a couple of formulas and column headers in the file. The problems is, the button does not even show up in FireFox. And Chrome adds \n and 16 spaces after the first line item.
    Any ideas? Any help would be appreciated
    example web page http://bikemountain.info/926worksheet/926erWorksheetZ.html

    • Oleg

      Can you expand on the first point? What place holder do you need for ?

  16. Sounds cool ! I tried using “c:\testfile.txt” as filename in the test.html — it doesn’t work and no message at all on IE 9 and Chrome latest. Remove c:\ and it works again ! Idem c:/

  17. viet hung

    @David Walsh: if i want to fillter excel or text file on the dialog. Whati have to change or add more code ? Please tell me? Im need it now. :)

  18. I’ve developed News service site (http://www.bharatnewsservice.com). I’ve used downloadify to download news in text file. Problem with downloadify is that download button doesn’t appear in their browser who are using Net protector as antivirus in their PC.

  19. [...] I want to read the contents of zip files, let a user change some of their contents on a webpage (via canvas and textarea), and give the changed .zip back via data:uri (and probably Downloadify) [...]

  20. Zhuster

    I think Downloadify is a wonderful tool dealing with cross-browser issue. One quick question, is there a way I can simulate the onclick event on the “Save To Disk” in javascript/jquery?

    Thanks

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!