En este tip, voy a mostrar como subir imágenes a un servidor utilizando una Aplicación en AIR, desde la aplicación se podrán seleccionar las imágenes que se quieren subir o bien, hacer un Drag&Drop desde el sistema de archivos local. También se muestra una vista previa de la imagen y la opción para borrarla.
Lo primero que debemos de hacer, es crear un proyecto nuevo en Flex y seleccionar el tipo de aplicación que sea de escritorio, o sea, que corra con AIR.
Bien, ya que tenemos nuestro proyecto creado, procederemos a crear la interfaz, lo que mostraremos, serán controles como TileList, Botones y un componente exclusivo para AIR, el FileSystemTree. En el TileList mostraremos las imágenes que se subirán y con los botones controlaremos acciones como: “Eliminar Imágenes” y “Subir Imágenes”. Con el FileSystemTree mostraremos toda la estructura de carpetas y archivos de la computadora que este ejecutando nuestra aplicación y desde ahí se podrán agregar las imágenes también.
Código :
<mx:ApplicationControlBar x="35" y="120" dock="true" height="40">
<mx:Button label="Eliminar Imagenes" icon="{ImageUtil.imagen.Delete}" click="click_eliminar()"/>
<mx:VRule height="100%"/>
<mx:Button label="Subir al Servidor" icon="{ImageUtil.imagen.ServerGo}" click="click_subir()"/>
</mx:ApplicationControlBar>
<mx:HDividedBox width="100%" height="100%">
<mx:FileSystemTree id="archivos_fst" width="250" height="100%" showIcons="true" showExtensions="true"
allowMultipleSelection="true"
allowDragSelection="true" dragEnabled="true" dragMoveEnabled="false"/>
<mx:TileList id="imagenes_tl" width="100%" height="100%" itemRenderer="ir.ImagenIR"
direction="horizontal" allowMultipleSelection="true" dataProvider="{imagenes_ac}"
dragEnter="dragEnter_imagenes(event)" dragDrop="dragDrop_imagenes(event)" dragExit="dragExit_imagenes(event)"/>
</mx:HDividedBox>Código :
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" width="100" height="130" horizontalAlign="center" verticalAlign="middle"
dataChange="dataChange_this(event)">
<mx:Script>
<![CDATA[
import mx.controls.Label;
import mx.controls.Image;
import mx.events.FlexEvent;
private var imagen:Image;
private var nombre_lbl:Label;
private function dataChange_this(event:FlexEvent):void
{
try
{
//intentamos eliminar el Image y el Label, pues la primera vez no existen
this.removeChild(imagen);
this.removeChild(nombre_lbl);
}
catch (error:Error)
{
}
if (this.data is File)
{
//como cada elemento del ArrayCollection es un File,
//casteamos la variable data
var f:File = File(this.data);
//creamos el objeto que mostrara la imagen
imagen = new Image();
imagen.width = 95;
imagen.height = 95;
//le indicamos a la imagen de donde debe de cargar la imagen
imagen.load(f.url);
//creamos el objeto que mostrara el nombre de la imagen
nombre_lbl = new Label();
nombre_lbl.width = 95;
//asignamos el nombre
nombre_lbl.text = f.name;
//agregamos los objetos al VBox
this.addChild(imagen);
this.addChild(nombre_lbl);
}
}
]]>
</mx:Script>
</mx:VBox>Código :
private function dragEnter_imagenes(event:DragEvent):void
{
//verifico que la fuente sea el FileSystemTree
if (event.dragSource.hasFormat("treeItems"))
{
//le digo que el TileList que muestra las imagenes puede recibir objetos
DragManager.acceptDragDrop(imagenes_tl);
//deshabilito los Listeners de la aplicacion para evitar confusiones de drop
this.removeEventListener(NativeDragEvent.NATIVE_DRAG_DROP, drag_drop_this);
this.removeEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, drag_enter_this);
}
}
private function dragExit_imagenes(event:DragEvent):void
{
//si no suelta los elementos del FileSystemTree en el TileList,
//solamente rehabilitamos los Listeners de la aplicacion
this.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, drag_drop_this);
this.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, drag_enter_this);
}
private function dragDrop_imagenes(event:DragEvent):void
{
//creamos una variable del FileSystemTree que origino el Drag
var fst:FileSystemTree = FileSystemTree(event.dragInitiator);
//vemos cuales son las rutas que fueron seleccionadas
var rutas:Array = fst.selectedPaths;
//agregamos esas rutas a nuestro ArrayColecction de File's
agregaAlDP(rutas);
//rehabilito los Listeners de la aplicacion
this.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, drag_drop_this);
this.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, drag_enter_this);
}Código :
private function dragExit_imagenes(event:DragEvent):void
{
//si no suelta los elementos del FileSystemTree en el TileList,
//solamente rehabilitamos los Listeners de la aplicacion
this.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, drag_drop_this);
this.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, drag_enter_this);
}
private function dragDrop_imagenes(event:DragEvent):void
{
//creamos una variable del FileSystemTree que origino el Drag
var fst:FileSystemTree = FileSystemTree(event.dragInitiator);
//vemos cuales son las rutas que fueron seleccionadas
var rutas:Array = fst.selectedPaths;
//agregamos esas rutas a nuestro ArrayColecction de File's
agregaAlDP(rutas);
//rehabilito los Listeners de la aplicacion
this.addEventListener(NativeDragEvent.NATIVE_DRAG_DROP, drag_drop_this);
this.addEventListener(NativeDragEvent.NATIVE_DRAG_ENTER, drag_enter_this);
}Código :
private function agregaAlDP(imgs:Array):void
{
var i:int = 0;
//cuento el numero de elementos del arreglo
var l:int = imgs.length;
//defino la variable que contendra al archivo
var f:File;
for (i = 0; i < l; i++)
{
if (imgs[i] is File)
{
//si el arreglo ya es de File, solo lo casteo
f = File(imgs[i]);
}
else
{
//si el arreglo es de las rutas, instancio la variable
f = new File(imgs[i]);
}
//si lo que se arrastra es un directorio,
//la propiedad extension = null, por eso lo valido
if (f.extension)
{
//lo hago minusculas, por ahi hay muchos .JPG que entrarian a ningun caso
switch (f.extension.toLowerCase())
{
case "png":
case "gif":
case "jpg":
case "jpeg":
{
//solo le permito a los archivos de algun tipo de imagen
imagenes_ac.addItem(f);
break;
}
}
}
}
}Código :
private function click_eliminar():void
{
//recupero los indices seleccionados y los asigno a un Array
var indices:Array = imagenes_tl.selectedIndices;
var i:int = 0;
//veo cuantos elementos son y le resto 1
var l:int = indices.length - 1;
//recorro el ArrayCollection del fin al principio por que conforme voy eliminando,
//van cambiando los indices
for (i = l; i >= 0; i--)
{
//voy quitando los elementos del ArrayCollection
imagenes_ac.removeItemAt(indices[i]);
}
}Código :
private function click_subir():void
{
//inicializo un arreglo nuevo
archivosSeleccionados = [];
var i:int = 0;
//veo cuantos elementos tiene nuestro ArrayColection de File's
var l:int = imagenes_ac.length;
for (i = 0; i < l; i++)
{
//proceso cada elemento por separado
agregarPendiente(File(imagenes_ac.getItemAt(i)));
}
}
private function agregarPendiente(f:File):void
{
//agrego el archivo al arreglo
archivosSeleccionados.push(f);
//agrego Listeners de progreso y de completado
f.addEventListener(ProgressEvent.PROGRESS, progress_f);
f.addEventListener(Event.COMPLETE, complete_f);
//con upload le digo a File que suba el archivo usando el script
//definido en el URLRequest
f.upload(ur);
}
private function progress_f(event:ProgressEvent):void
{
//aquí se puede mostrar el progreso en un ProgressBar, en un TextArea o como más te guste
trace("progressHandler: name=" + File(event.currentTarget).name + " bytesLoaded=" + event.bytesLoaded + " bytesTotal=" + event.bytesTotal);
}
private function complete_f(event:Event):void
{
//cuando se ha subido el archivo, lo quitamos del Array
quitarPendiente(File(event.currentTarget))
}
private function quitarPendiente(f:File):void
{
var i:int = 0;
//vemos cuantos archivos tenemos
var l:int = archivosSeleccionados.length;
for (i = 0; i < l; i++)
{
if (archivosSeleccionados[i].name == f.name)
{
//si el archivo que se subió es el actual del Array, se quita
archivosSeleccionados.splice(i, 1);
if (archivosSeleccionados.length == 0)
{
//si el Array ya no tiene elementos, terminó de subir
terminado();
}
return;
}
}
}
private function terminado():void
{
//Le avisamos al usuario que se han terminado de subir las imagenes
Alert.show("Las imagenes han sido subidas al servidor con éxito!", "Confirmación");
}Código :
<?php
$carpeta = "";
$archivo = $carpeta . $_FILES['Filedata']['name'];
if(move_uploaded_file($_FILES['Filedata']['tmp_name'], $archivo))
{
echo "<datos err='no'/>";
}
else
{
echo "<datos err='si'/>";
}
?>
Código :
The CSS type selector 'ProgressBar' was not processed, because the type was not used in the application. DragDrop/src DragDrop.mxml line 143 1248979828953 11
Código :
VerifyError: Error #1053: Illegal override of z in mx.core.UIComponent. at flash.display::MovieClip/nextFrame() at mx.managers::SystemManager/deferredNextFrame()[E:\dev\beta1\frameworks\projects\framework\src\mx\managers\SystemManager.as:352] at mx.managers::SystemManager/preloader_initProgressHandler()[E:\dev\beta1\frameworks\projects\framework\src\mx\managers\SystemManager.as:3287] at flash.events::EventDispatcher/dispatchEventFunction() at flash.events::EventDispatcher/dispatchEvent() at mx.preloaders::Preloader/timerHandler()[E:\dev\beta1\frameworks\projects\framework\src\mx\preloaders\Preloader.as:418] at flash.utils::Timer/_timerDispatch() at flash.utils::Timer/tick()