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>
Crearemos un ItemRenderer que será el que muestre la imagen y su respectivo nombre, este IR consta únicamente de un objeto de tipo Image y un Label.
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>
Ya creada la interfaz, procederemos con el código. El código se divide en varias partes, las principales, son para controlar los Drag&Drop desde el FileSystemTree hacia el TileList, para controlar el Drag&Drop desde el sistema de archivos local del sistema hacia nuestra Aplicación, la eliminación de imágenes y para subir las imágenes al servidor.
El Drag&Drop del FileSystemTree al TileList será controlado con los siguiente métodos:
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); }
El Drag&Drop del sistema de archivos local a nuestra Aplicación será controlado con los siguiente métodos:
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); }
Se generó una función genérica con la cual se alimentará nuestro DataProvider del TileList, se hace una verificación para saber si recibimos un arreglo de File’s o si recibimos un arreglo de Rutas:
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; } } } } }
Para eliminar las imágenes, únicamente eliminamos los elementos del DataProvider con el siguiente método:
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]); } }
Para subir las imágenes de nuestro TileList al server, utilizamos los siguientes métodos:
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"); }
Y bien ahora va la parte de php, un pequeño script que recibe el archivo y lo mueve a nuestro servidor:
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'/>"; } ?>
Ya solo queda dejar un archivo comprimido con el proyecto de Flex y este script de PHP. El archivo DragAndDrop.zip, incluye dos archivos:
DragDrop.zip que es archivo que se importa desde Flex para que se genere el proyecto.
upload.php que es el script que se encarga de mover las imagenes al servidor.
descargar archivo
¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.
Por Gz.Francisco el 27 de Julio de 2009
Por XKlibur el 30 de Julio de 2009
Por Rafeo el 30 de Julio de 2009
Código :
Pero al momento de querer debuggear la aplicación me sale este error :
Y pues no puedo correr tampoco la aplicación.
Esto lo hice teniendo instalada la nueva versión de AIR y utilizando Flex Builder 3.
Muchas thanks por adela.
Por master_of_puppetz el 30 de Julio de 2009
Por Rafeo el 30 de Julio de 2009
Por master_of_puppetz el 30 de Julio de 2009
Por Rafeo el 30 de Julio de 2009
Ahora instalé el SDK 4 pero me dá este error
Código :
Por master_of_puppetz el 31 de Julio de 2009
Mira, de aquí http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4, bajate algún Stable Build y pruebas
Por rodrigo morales el 03 de Abril de 2010
Por carlos - peru el 25 de Junio de 2010
los ejemplo en la web solo son php, pero con java no hay