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! ;)
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! ;)