📜 ⬆️ ⬇️

Drag'n'drop files in Flex using the HTML5 File API

Good day! Recently, for a single web application on Flex, it was necessary to drag and drop photos. Flash does not allow this to be implemented directly, although such functionality is present in AIR applications. To solve the problem, it was necessary to apply the HTML5 File API.

Thus, the solution of the problem is divided into several stages. The first step is handling drag'n'drop files using the File API. All uploaded files are added to the list from which they will later be transferred to Flash.

 $(document).ready(function() { var dropZone = $('div#dropZone'); //    if (typeof(window.FileReader) == 'undefined') { dropZone.text('  !'); dropZone.addClass('error'); } //   Drop dropZone[0].ondrop = function(event) { event.preventDefault(); dropZone.removeClass('hover'); dropZone.addClass('drop'); displayFiles(event.dataTransfer.files); }; }); //-------------------------------------------------------------------------------------------------- var fileList = new Array(); function displayFiles(files) { $.each(files, function(i, file) { var imgList = $('ul#img-list'); var maxFileSize = 20*1000000; //    - 1 . if (!file.type.match(/image.*/)) { //    return true; } //   li     ,  //      file,    File (  ) var li = $('<li/>').appendTo(imgList); $('<div/>').text(file.name).appendTo(li); //    if (file.size > maxFileSize) { $('<div/>').text('  !').appendTo(li); } else { var img = $('<img/>').appendTo(li); li.file = file; //   FileReader     ,     //     var reader = new FileReader(); reader.onload = (function(aImg, file) { return function(e) { aImg.attr('src', e.target.result); aImg.attr('width', 75); file.f_data = e.target.result; //       fileList.push(file); }; })(img, file); reader.readAsDataURL(file); } }); } //-------------------------------------------------------------------------------------------------- 
HTML flex , div, .
<div style="float:left"> </div> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" id="web-client" width="800px" align="middle" height="600px"> <param name="allowScriptAccess" value="sameDomain"> <param name="allowFullScreen" value="false"> <param name="movie" value="dd_test.swf"><param name="quality" value="high"><param name="bgcolor" value="#cccccc"><embed src="test.swf" quality="high" bgcolor="#cccccc" name="web-client" allowscriptaccess="sameDomain" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="https://www.adobe.com/go/getflashplayer" width="800" align="middle" height="600"> </object> <div id="dropzone" style="float:left"> <p> , .</p> <ul id="img-list"></ul> </div>
$(document).ready(function() { var dropZone = $('div#dropZone'); // if (typeof(window.FileReader) == 'undefined') { dropZone.text(' !'); dropZone.addClass('error'); } // Drop dropZone[0].ondrop = function(event) { event.preventDefault(); dropZone.removeClass('hover'); dropZone.addClass('drop'); displayFiles(event.dataTransfer.files); }; }); //-------------------------------------------------------------------------------------------------- var fileList = new Array(); function displayFiles(files) { $.each(files, function(i, file) { var imgList = $('ul#img-list'); var maxFileSize = 20*1000000; // - 1 . if (!file.type.match(/image.*/)) { // return true; } // li , // file, File ( ) var li = $('<li/>').appendTo(imgList); $('<div/>').text(file.name).appendTo(li); // if (file.size > maxFileSize) { $('<div/>').text(' !').appendTo(li); } else { var img = $('<img/>').appendTo(li); li.file = file; // FileReader , // var reader = new FileReader(); reader.onload = (function(aImg, file) { return function(e) { aImg.attr('src', e.target.result); aImg.attr('width', 75); file.f_data = e.target.result; // fileList.push(file); }; })(img, file); reader.readAsDataURL(file); } }); } //--------------------------------------------------------------------------------------------------
HTML flex , div, .
<div style="float:left"> </div> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" id="web-client" width="800px" align="middle" height="600px"> <param name="allowScriptAccess" value="sameDomain"> <param name="allowFullScreen" value="false"> <param name="movie" value="dd_test.swf"><param name="quality" value="high"><param name="bgcolor" value="#cccccc"><embed src="test.swf" quality="high" bgcolor="#cccccc" name="web-client" allowscriptaccess="sameDomain" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="https://www.adobe.com/go/getflashplayer" width="800" align="middle" height="600"> </object> <div id="dropzone" style="float:left"> <p> , .</p> <ul id="img-list"></ul> </div>
 $(document).ready(function() { var dropZone = $('div#dropZone'); //    if (typeof(window.FileReader) == 'undefined') { dropZone.text('  !'); dropZone.addClass('error'); } //   Drop dropZone[0].ondrop = function(event) { event.preventDefault(); dropZone.removeClass('hover'); dropZone.addClass('drop'); displayFiles(event.dataTransfer.files); }; }); //-------------------------------------------------------------------------------------------------- var fileList = new Array(); function displayFiles(files) { $.each(files, function(i, file) { var imgList = $('ul#img-list'); var maxFileSize = 20*1000000; //    - 1 . if (!file.type.match(/image.*/)) { //    return true; } //   li     ,  //      file,    File (  ) var li = $('<li/>').appendTo(imgList); $('<div/>').text(file.name).appendTo(li); //    if (file.size > maxFileSize) { $('<div/>').text('  !').appendTo(li); } else { var img = $('<img/>').appendTo(li); li.file = file; //   FileReader     ,     //     var reader = new FileReader(); reader.onload = (function(aImg, file) { return function(e) { aImg.attr('src', e.target.result); aImg.attr('width', 75); file.f_data = e.target.result; //       fileList.push(file); }; })(img, file); reader.readAsDataURL(file); } }); } //-------------------------------------------------------------------------------------------------- 
HTML flex , div, .
<div style="float:left"> </div> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" id="web-client" width="800px" align="middle" height="600px"> <param name="allowScriptAccess" value="sameDomain"> <param name="allowFullScreen" value="false"> <param name="movie" value="dd_test.swf"><param name="quality" value="high"><param name="bgcolor" value="#cccccc"><embed src="test.swf" quality="high" bgcolor="#cccccc" name="web-client" allowscriptaccess="sameDomain" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="https://www.adobe.com/go/getflashplayer" width="800" align="middle" height="600"> </object> <div id="dropzone" style="float:left"> <p> , .</p> <ul id="img-list"></ul> </div>
$(document).ready(function() { var dropZone = $('div#dropZone'); // if (typeof(window.FileReader) == 'undefined') { dropZone.text(' !'); dropZone.addClass('error'); } // Drop dropZone[0].ondrop = function(event) { event.preventDefault(); dropZone.removeClass('hover'); dropZone.addClass('drop'); displayFiles(event.dataTransfer.files); }; }); //-------------------------------------------------------------------------------------------------- var fileList = new Array(); function displayFiles(files) { $.each(files, function(i, file) { var imgList = $('ul#img-list'); var maxFileSize = 20*1000000; // - 1 . if (!file.type.match(/image.*/)) { // return true; } // li , // file, File ( ) var li = $('<li/>').appendTo(imgList); $('<div/>').text(file.name).appendTo(li); // if (file.size > maxFileSize) { $('<div/>').text(' !').appendTo(li); } else { var img = $('<img/>').appendTo(li); li.file = file; // FileReader , // var reader = new FileReader(); reader.onload = (function(aImg, file) { return function(e) { aImg.attr('src', e.target.result); aImg.attr('width', 75); file.f_data = e.target.result; // fileList.push(file); }; })(img, file); reader.readAsDataURL(file); } }); } //--------------------------------------------------------------------------------------------------
HTML flex , div, .
<div style="float:left"> </div> <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0" id="web-client" width="800px" align="middle" height="600px"> <param name="allowScriptAccess" value="sameDomain"> <param name="allowFullScreen" value="false"> <param name="movie" value="dd_test.swf"><param name="quality" value="high"><param name="bgcolor" value="#cccccc"><embed src="test.swf" quality="high" bgcolor="#cccccc" name="web-client" allowscriptaccess="sameDomain" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="https://www.adobe.com/go/getflashplayer" width="800" align="middle" height="600"> </object> <div id="dropzone" style="float:left"> <p> , .</p> <ul id="img-list"></ul> </div>

The second step is to transfer the downloaded file to Flash. To communicate with the external world, Flash has the ExternalInterface class, it allows you to call JS functions, as well as to make functions available to call Flash. Unfortunately, the function call from Flash did not work for me steadily, so I had to start the timer inside and call the JS function to transfer the already loaded files.
The main problem was the form of transfer photos. Inside Flash, it was convenient for me to work with a photo as with an object of the class ByteArray . Since there is no analogue of the class ByteArray in JS, we had to use the additional data conversion to base64 during the transfer. The File API has a corresponding function - readAsDataURL (), which returns the file as a string in base64 encoding. We pass the resulting string to flash and use Base64Decoder to get an object of the ByteArray class containing our original photo.
 // Flex ,     var dragTimer:Timer; var file_count_already_have:int; //   -  JS  ,   JS -   public function init_draginteface():void { dragTimer = new Timer(3*1000,0); //  3  dragTimer.addEventListener(TimerEvent.TIMER, dragTimerEvent); dragTimer.start(); file_count_already_have = 0; } //--------------------------------------------------------------------------- public function dragTimerEvent(e:TimerEvent):void { dragTimer.stop(); if(ExternalInterface.available) { var file_count:int = ExternalInterface.call("dropFileCount"); // JS -,      if (file_count>0) { for(var i:int = file_count_already_have ; i<file_count; i++) { dragImageFromJS(i); } file_count_already_have = file_count; } dragTimer.start(); } } //--------------------------------------------------------------------------- public function dragImageFromJS(i:int):void { var file_size:int = ExternalInterface.call("getFileSize", i); //    var file_name:String = ExternalInterface.call("getFileName", i); //   var file_ba:ByteArray = new ByteArray; var base64dec:Base64Decoder = new Base64Decoder(); var start_load:uint = getTimer(); base64dec.decode(ExternalInterface.call("getFile", i)); //       base64 var load_time:uint = getTimer() - start_load; file_ba = base64dec.toByteArray(); if(file_ba != null) { trace(""); trace("add new item [file_name: "+file_name+"] [file_size:"+file_size.toString()+"] [fr_ba_size: "+file_ba.length + "] [load_time: "+load_time.toString()+"]"); loadFromByteArray(file_ba); //   Flex  } } 
// Flex , var dragTimer:Timer; var file_count_already_have:int; // - JS , JS - public function init_draginteface():void { dragTimer = new Timer(3*1000,0); // 3 dragTimer.addEventListener(TimerEvent.TIMER, dragTimerEvent); dragTimer.start(); file_count_already_have = 0; } //--------------------------------------------------------------------------- public function dragTimerEvent(e:TimerEvent):void { dragTimer.stop(); if(ExternalInterface.available) { var file_count:int = ExternalInterface.call("dropFileCount"); // JS -, if (file_count>0) { for(var i:int = file_count_already_have ; i<file_count; i++) { dragImageFromJS(i); } file_count_already_have = file_count; } dragTimer.start(); } } //--------------------------------------------------------------------------- public function dragImageFromJS(i:int):void { var file_size:int = ExternalInterface.call("getFileSize", i); // var file_name:String = ExternalInterface.call("getFileName", i); // var file_ba:ByteArray = new ByteArray; var base64dec:Base64Decoder = new Base64Decoder(); var start_load:uint = getTimer(); base64dec.decode(ExternalInterface.call("getFile", i)); // base64 var load_time:uint = getTimer() - start_load; file_ba = base64dec.toByteArray(); if(file_ba != null) { trace(""); trace("add new item [file_name: "+file_name+"] [file_size:"+file_size.toString()+"] [fr_ba_size: "+file_ba.length + "] [load_time: "+load_time.toString()+"]"); loadFromByteArray(file_ba); // Flex } }

 //JS -,    Flex  function dropFileCount() //   { return fileList.length; } //-------------------------------------------------------------------------------------------------- function getFile(i) //     { var data = fileList[i].f_data; var data_cat = data.substr(23); return data_cat; } //    ,   ,    //data:image/jpeg;base64,/9j/4U3ARXhpZgAASUkq //-------------------------------------------------------------------------------------------------- function getFileSize(i) { return fileList[i].size; } //-------------------------------------------------------------------------------------------------- function getFileName(i) { return fileList[i].name; } //-------------------------------------------------------------------------------------------------- 
//JS -, Flex function dropFileCount() // { return fileList.length; } //-------------------------------------------------------------------------------------------------- function getFile(i) // { var data = fileList[i].f_data; var data_cat = data.substr(23); return data_cat; } // , , //data:image/jpeg;base64,/9j/4U3ARXhpZgAASUkq //-------------------------------------------------------------------------------------------------- function getFileSize(i) { return fileList[i].size; } //-------------------------------------------------------------------------------------------------- function getFileName(i) { return fileList[i].name; } //--------------------------------------------------------------------------------------------------

As a result, we get drag'n'drop loading photos in the Flex application. A small piece of code for displaying photos from ByteArray.
 <mx:Script> <![CDATA[ // Flex       ByteArray public function loadFromByteArray(data:ByteArray):void { _loader = new Loader(); _loader.contentLoaderInfo.addEventListener(Event.COMPLETE,_load_loader_complete); _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorOnLoad); _loader.loadBytes(data); } public function _load_loader_complete(e:Event):void { _loader.removeEventListener(Event.COMPLETE,_load_loader_complete); var bitmapIm:Bitmap = Bitmap(e.target.content); this.itemIm.addChild(bitmapIm); } ]]> </mx:Script> <mx:Image source="" id="itemIm" maxWidth="100" maxHeight="100" horizontalAlign="left" verticalAlign="top"/> 
<mx:Script> <![CDATA[ // Flex ByteArray public function loadFromByteArray(data:ByteArray):void { _loader = new Loader(); _loader.contentLoaderInfo.addEventListener(Event.COMPLETE,_load_loader_complete); _loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorOnLoad); _loader.loadBytes(data); } public function _load_loader_complete(e:Event):void { _loader.removeEventListener(Event.COMPLETE,_load_loader_complete); var bitmapIm:Bitmap = Bitmap(e.target.content); this.itemIm.addChild(bitmapIm); } ]]> </mx:Script> <mx:Image source="" id="itemIm" maxWidth="100" maxHeight="100" horizontalAlign="left" verticalAlign="top"/>

This solution has one significant drawback: when downloading large-sized photos, the browser significantly loads the processor. Perhaps there is a more optimal way, but I did not find it.

ps Link to a working example, do not consider an advertisement, a local project and designed for a different audience. Example

')

Source: https://habr.com/ru/post/139492/


All Articles