PDA

View Full Version : [3.1.0] Ext.ux.MozDropZone



kavih7
16 Mar 2010, 10:29 PM
Hello fellow Exters!

It has been a while since I've been in the forums and that is because I've been very busy! Recently, I won the MySpace Developer Challenge using my company's software and because I am all for sharing (and getting feedback), I'd like to briefly describe a plugin I made during my development for the contest. As I'm sure some of you know, with FF 3.? Drag and Drop support allows dragging and dropping files from your computer into FF. However, it wasn't until FF 3.6 (Gecko 1.9.2) that Mozilla added the File API. Mixing the two, you can read in files off of a "drop." This is exactly what I needed for my contest entry and so I developed a plugin to allow this functionality to be reused by folks like you!

Here is the source:


Ext.ux.MozDropZone = function(cfg)
{
var comp, dom;
var cfg = cfg;

this.init = function(cmp)
{
if (typeof cfg.handleFiles != 'function')
{
throw 'Error in intializing Ext.ux.MozDropZone. The "handleFiles" config option must be a function';
return;
}

if (typeof cmp.getEl != 'function')
{
throw 'Error in intializing Ext.ux.MozDropZone. A drop zone can only be applied to an Ext.Component.';
return;
}

cmp.onRender = cmp.onRender.createSequence(onRender, this);
comp = cmp;

//Store a public reference to the Component
this.cmp = cmp;
};

this.disableDrop = function()
{
dom.removeAttribute("dragenter");
}

this.enableDrop = function()
{
dom.setAttribute("dragenter", true);
}

function onRender()
{
dom = comp.getEl().dom;
registerListeners.call(this);
}

function registerListeners()
{
var capture = false;

if (dom != Ext.getBody().dom)
{
var parent = dom.parentNode;
}
else
{
var parent = window;
capture = true;
}

parent.addEventListener("dragenter", dragenter.createDelegate(this), capture);
parent.addEventListener("dragleave", dragleave.createDelegate(this), capture);
dom.addEventListener("dragover", dragover, false);
dom.addEventListener("drop", drop.createDelegate(this), false);
}

function dragenter(e) {
this.enableDrop();
e.stopPropagation();
e.preventDefault();
}

function dragleave(e) {
e.stopPropagation();
e.preventDefault();
this.disableDrop();
}

function dragover(e) {
e.stopPropagation();
e.preventDefault();
}

function drop(e) {
var dt = e.dataTransfer;
var files = dt.files;

cfg.handleFiles.call(this, files);
e.stopPropagation();
e.preventDefault();
}
};


The plugin registers itself on any component (only tested it on a generic Ext.Panel) and turns that component into a dropzone for a mozilla dragdrop event.

Here is a video of it in action (the video is in the blog post I wrote after I won):

http://bit.ly/95DNMy

Here is a sample usage snippet (I took this from my application and trimmed it down, but did not test it). The plugin currently just accepts a config object and the config.handleFiles attribute must be a function, which will get passed to it the array of Files:


new Ext.Panel
({
title:'A Mozilla Drop Zone',
plugins: new Ext.ux.MozDropZone
({
handleFiles: function(files)
{
if (files.length > 0)
{
//Do some preparation (setting variables here that will need scope later) and/or show a wait messagebox
var imageType = /image.*/; //Only allow images

for (var i = 0; i < files.length; i++)
{
var file = files[i];

if (!file.type.match(imageType))
{
continue;
}

var reader = new FileReader();
reader.onloadend = (function(aFile)
{
return function(e)
{
//The file has loaded at this point and e.target.result has binary data of the image.
//Also aFile is a locally scoped variable holding the value of the "file" variable from before
//Keep in mind file reading is asynchronous in this way, hence the need for getting proper
//scope
}
})(file);

reader.readAsDataURL(file);
}
}
}
}),
html: '<div align="center" style="border:1px solid red;height:200px;">Drop it here</div>
})


Here are some related links that helped me put my application together:
http://hacks.mozilla.org/2009/12/w3c-fileapi-in-firefox-3-6/
http://hacks.mozilla.org/2009/12/file-drag-and-drop-in-firefox-3-6/

I hope it helps any of you working on an application that is Mozilla based. Maybe you should just build one on my software! ;)

xantus
18 Mar 2010, 6:15 AM
Niiiice! Congrats!

Yoris
18 Mar 2010, 6:57 AM
Thanks for sharing dude!!! how cool is that?!?!!...... =P~=P~=P~

wemerson.januario
18 Mar 2010, 8:41 PM
Humm, Whats nice. Congratssss!

jay@moduscreate.com
19 Mar 2010, 11:01 AM
Congrats dude!

jay@moduscreate.com
19 Mar 2010, 11:02 AM
Btw, you made myspace suck a little less :P

kavih7
19 Mar 2010, 6:03 PM
Thanks a lot guys. I'm always open to feedback on the plugin too. Also, I started a couple threads a while back in which I was going to be sharing code that I've used in my software (like this plugin), but I got so busy that I never had a chance to do that, so I hope to finish the sharing soon.

Some of the code will cover:
1) A Tour system using tooltips and spotlight.
2) Animation sculpting, which allows freezing an animation (not pausing) and then applying a different animation (or same) to happen from that point on.
3) Allowing multiple MessageBoxes (Ext.Msg) instances.

Anyways, thanks again.

steffenk
20 Mar 2010, 3:29 AM
Congrats for the competition win! And thanks for sharing!
I watched the video and it'S impressing.

Can you give a hint how you do the image processing?

vg Steffen

kavih7
24 Mar 2010, 10:30 PM
Congrats for the competition win! And thanks for sharing!
I watched the video and it'S impressing.

Can you give a hint how you do the image processing?

vg Steffen

Ya, I used this JS library: http://www.pixastic.com/

Unless you meant how to actually read in the images on "drop" and in that case, I'd have to strip out a bunch of stuff from my code to provide an easy to read example.