Upload de múltiplos arquivos com o FileReferenceList em Flex

Compartilhe este artigo!

Sobre o autor

Entre em contato...

Redação ForumWeb

Redação ForumWeb Equipe de desenvolvimento do ForumWeb.com.br, responsável pelas dicas e downloads do site.

Site do autor: http://www.forumweb.com.br

Indique este artigo

Para

Seu email

Mensagem

Fechar
Personalize sua mensagem

Código

Arquivos relacionados

  • Por enquanto, nenhum arquivo para download.

Upload de múltiplos arquivos com o FileReferenceList em Flex

Sexta-Feira, 25 de Fevereiro de 2011 às 14:54

As vezes em nosso projetos precisamos fazer uploads de mais de um arquivo.

No Flex a classe FileReferenceList fornece recurso para permitir que o usuário selecione um ou mais arquivos para upload. Um objeto FileReferenceList é uma lista de FileReference. Isso significa que ao selecionar vários arquivos o método fileList possuirá a lista de FileReference, dos arquivos que você selecionou.

No exemplo abaixo, ao selecionar os arquivo, a lista é passada para o TileList e este gerencia as listas. No TileList criei um itemrenderer com um Label, um ProgressBar e imagens para mostrar o status do upload. No main.mxml, gerenciamos toda a aplicação, chamando o próximo upload assim que o primeiro se encerar. Assim que o upload inicia a barra de progresso aparece e desaparece automaticamente assim que o upload for concluído.

main.mxml:

<mx:Script>
<![CDATA[
	import mx.controls.Alert;

	// Instancia da classe FileReferenceList
	private var files:FileReferenceList = new FileReferenceList()
	// número do Filereference que esta sendo realizado o Upload.
	private var uploadAtual:int = -1;
	private function init ():void
	{
		files.addEventListener( Event.SELECT, selectHandler );
	}
	private function selecionar ():void
	{
		var tipos:FileFilter = new FileFilter( 'Somente Imagens',
			'*.jpg;*.jpeg;*.gif;*.png' )
		files.browse( [ tipos ] )
	}
	private function selectHandler ( event:Event ):void
	{
		lista.dataProvider = files.fileList
		lista.height = files.fileList.length * 29
		btEnviar.visible = true
		btSeleciona.visible = false
	}
	private function cancelHandler ():void
	{
		( lista.dataProvider[ uploadAtual ] as FileReference ).cancel()
		btCancela.visible = false
	}
	private function enviarHandler ():void
	{
		proximoUpload()
		btEnviar.visible = false
		btCancela.visible = true
	}
	private function proximoUpload ():void
	{
		uploadAtual++;

		var url:String = "upload.php"
		var request:URLRequest = new URLRequest( url );
		var file:FileReference = ( lista.dataProvider[ uploadAtual ] as FileReference )
		file.addEventListener( Event.COMPLETE, uploadCompleteDataHandler )
		file.upload( request, 'imagem' )
	}
	private function uploadCompleteDataHandler ( event:Event ):void
	{
		if ( lista.dataProvider.length == uploadAtual )
		{
			Alert.show( "Todos Upload concluidos" )
			btCancela.visible = false
		}
		else
			proximoUpload()
	}
]]>
</mx:Script>
<mx:Canvas x="10"
	   y="10"
	   height="400"
	   width="534"
	   borderThickness="1"
	   borderStyle="solid"
	   backgroundColor="#CFCFCF"
	   verticalScrollPolicy="on">
<mx:TileList id="lista"
			 width="515"
			 height="100%"
			 labelField="name"
			 columnWidth="{lista.width}"
			 itemRenderer="com.eduardokraus.renderer.ListaRenderer"
			 backgroundAlpha="0"
			 horizontalScrollPolicy="off"
			 verticalScrollPolicy="off"
			 borderThickness="0" />
</mx:Canvas>
<mx:VBox x="552" y="10">
<mx:Button id="btSeleciona"
		   label="Selecione os arquivos"
		   click="selecionar()"
		   includeInLayout="{btSeleciona.visible}" />
<mx:Button id="btEnviar"
		   label="Enviar arquivos"
		   width="148"
		   click="enviarHandler()"
		   visible="false"
		   includeInLayout="{btEnviar.visible}" />
<mx:Button id="btCancela"
		   label="Cancelar"
		   width="148"
		   click="cancelHandler()"
		   visible="false"
		   includeInLayout="{btCancela.visible}" />
</mx:VBox>


Ao clicar em selecionar, é chamado o método browser do FileReferenceList, que abre uma caixa de diálogo do seu SO para que você possa selecionar os arquivos. O filtro serve para você designar um filtro de extensão, para somente certas extensões sejam selecionadas. Assim que você clicar em Abrir na caixa de diálogo, o método selectHandler do main.mxml e este passa a lista TileList. O botão enviar passa a ser visível e o botão selecionar invisível.

Ao clicar em enviar, o botão é ocultado e o botão cancelar é apresentado. E é chamado o método proximoUpload para enviar os itens ao servidor.

ListaRenderer.mxml:

<mx:Script>
		<![CDATA[
			import flash.net.navigateToURL;

			private var file:FileReference
			private var fileSalvo:String = ''

			override public function set data ( value:Object ):void
			{
				super.data = value

				if ( value is FileReference )
					file = value as FileReference
				file.addEventListener( Event.OPEN, initUploadHandler )
				file.addEventListener( DataEvent.UPLOAD_COMPLETE_DATA, uploadCompleteDataHandler )
				file.addEventListener( IOErrorEvent.IO_ERROR, errorHandler );
				file.addEventListener( SecurityErrorEvent.SECURITY_ERROR, errorHandler );
				file.addEventListener( Event.CANCEL, cancelHandler )
			}
			private function initUploadHandler ( event:Event ):void
			{
				progresso.visible = true
			}
			private function uploadCompleteDataHandler ( event:DataEvent ):void
			{
				if ( event.data == 'erro' )
					error.visible = true;
				else
				{
					fileSalvo = event.data.toString()
					sucess.visible = true;
				}
			}
			private function errorHandler ( event:Event ):void{}
			private function visualizar ():void
			{
				navigateToURL( new URLRequest( 'imagens/' + fileSalvo ) )
			}
			private function cancelHandler ( event:Event ):void
			{
				error.visible = true;
				progresso.visible = false
			}
		]]>
	</mx:Script>
	<mx:Label x="5"
			  text="{data.name}"
			  verticalCenter="0" />
	<mx:ProgressBar id="progresso"
					visible="{ false }"
					verticalCenter="0"
					right="5"
					labelPlacement="center"
					width="295"
					label="Carregando %1 de %2 KB (%3%%)"
					conversion="1024"
					source="data">
		<mx:completeEffect>
			<mx:Parallel>
				<mx:Fade alphaTo="0.0" />
				<mx:Zoom zoomHeightTo="0" />
			</mx:Parallel>
		</mx:completeEffect>
	</mx:ProgressBar>
	<mx:HBox id="sucess"
			 right="5"
			 visible="{ false }"
			 click="visualizar()"
			 verticalCenter="0"
			 verticalAlign="middle">
		<mx:Label text="Clique para Visualizar"
				  fontWeight="bold"
				  color="#BB0404" />
		<mx:Image useHandCursor="true" source="@Embed('assets/success-icon.png')" />
	</mx:HBox>
	<mx:Image id="error"
			  right="5"
			  visible="{ false }"
			  source="@Embed('assets/error-icon.png')"
			  height="24"
			  verticalCenter="0" />


Primeiro eu sobrescrevo o método data do Container para receber as alterações de valor do ItemRenderer do TileList. Quando recebo estas atualizações adiciono a escuta ao eventos que fazem com que meu componente funcione.

Você agora deve estar se perguntando por que não tem escuta no evento do ProgressEvent para gerenciar a barra de progresso. Simples, a barra de progresso se gerencia automaticamente através do método source do ProgressBar.

Quando os dados retornam do servidor, o método uploadCompleteDataHandler é executado e nele temos o dado retornado pelo servidor. Este dado retornado pode ser um simples echo. Se o valor retornado for “erro” mostramos a imagem de erro. Caso não for erro, mostramos a imagem de sucesso em um link para visualizarmos a imagem que foi feito upload.

Upload.php:

<?php
$arquivo = $_FILES['imagem']['tmp_name'];
$nome = $_FILES['imagem']['name'];
$novoNome = md5(microtime());
$destino = 'imagens/' . $novoNome;

// Pega a extensão
$extensao = strrchr( $nome, '.' );

// Converte a extensão para minúsculo
$extensao = strtolower($extensao);

// 'Somente imagens', '*.jpg;*.jpeg;*.gif;*.png'
if( strstr( '*.jpg;*.jpeg;*.gif;*.png', $extensao ) )
{
  move_uploaded_file( $arquivo, $destino . $extensao  );
  echo $novoNome . $extensao;
}
else
  echo 'erro';
?>


Este recebe o pedido de upload e antes analisa se o arquivo pode ser salvo. Para isto ele valida se a extensão do arquivo enviado esta na lista de extensões permitidas, se sim, movo para a pasta de imagem e retorna o novo nome para o Flex. Se não está na lista, apenas retorna a palavra “erro”.

Execute tudo para vê-lo funcionando.

Fonte/Autor: Eduardo Kraus

Qual a sua opinião?

Comente e interaja!



Ainda sem comentários, comente!