Introdução
Faz algum tempo =/, que publiquei um video demonstrando a comunicação entre swfs construidos com CFFORM, como os pedidos foram muitos venho aqui compartilhar essa implementação com vocês.
Pré-requisito
- ColdFusion MX 7.0.2, com um repositório de classes configurado.
Conceitos
Esta aplicação está baseada na comunicação provida através da classe LocalConnection, e consequentemente todo seu conceito também baseia-se nela.
Esta classe ActionScript cria um objeto, encarregado de transportar mensagens (chamada de função) e responder a uma mensagem (execução da função solicitada), entre aplicações SWF, ao mesmo tempo pode ser rementente e destinatário, fazendo uma analogia ao envio de correspondência na no mundo real.
Quando selecionarmos (evento change) uma linha
do select, chamaremos uma função no swf de destino, passando como parâmetro a linha selecionado, esta função adicionará este elemento no select de destino, e após a execução da função remota, removeremos a linha selecionada.
Conteúdo
Para implementar isto, utilizei dois arquivos ActionScript, e dois arquivos CFM. O primeiro arquivo ActionScript permite o uso da class LocalConnection em qualquer outra aplicação, não está amarrada a esta aplicação, o segundo arquivo, um pouco mais complexo, conté toda as movimentações de dados, e os arquivos cfm é onde contruiremos os forms.
Vamos aos aquivos CFM, não vou comentar ainda, mesmo porque o CFML é bem simples e explicito.
Mas chamo a atenção para a propriedade onload do cfform, nela encontramos a função que construirá toda a comunicação entre os forms, note que os dois primeiros parâmtros da chamada, serão os nomes dos conectores LocalConnection, o primeiro sempre será o objeto corrente, e o segundo o objeto remoto, eles devem ser únicos (repare que foram colocado em posições diferentes na chamada), o mais apropriado seria utilzar a função CFML CreateUUID, não foi feito isso aqui para não confundir, os demais parâmetros podem ser identificados com facilidade.
BD1.cfm
<cfform name=”form1″ id=”form1″ method=”post” format=”flash” width=”300″ height=”250″
onload=”cfform2cfform(‘connector1′,’connector2′,’MyList1′,’addRight’,'Enviar’)”> <cfformitem type=”script”>
#include “communication.as”
</cfformitem>
<cfformgroup type=”horizontal”>
<cfselect name=”MyList1″ size=”5″ multiple=”yes”>
<option value=”pcsilva” >pcsilva </option>
<option value=”Pedro” >Pedro </option>
<option value=”Pedro Claudio”>Pedro Claudio</option>
</cfselect>
<cfinput type=”button” name=”addRight” value=”>>” />
</cfformgroup>
<cfinput type=”button” name=”Enviar” value=”Enviar” />
</cfform>
<cfdump var=”#FORM#” />
BD2.cfm
<cfform name=”form1″ id=”form1″ method=”post” format=”flash” width=”300″ height=”250″
onload=”cfform2cfform(‘connector2′,’connector1′,’MyList2′,’addLeft’,'Enviar2′)”> <cfformitem type=”script”>
#include “communication.as”
</cfformitem>
<cfformgroup type=”horizontal”>
<cfinput type=”button” name=”addLeft” value=”<<” />
<cfselect name=”MyList2″ size=”5″ multiple=”yes” />
</cfformgroup>
<cfinput type=”button” name=”Enviar2″ value=”Enviar” />
</cfform>
<cfdump var=”#FORM#” />
O arquivo seguinte foi utilizado no include ActionScript das duas paginas CFML, tente compreender o que ele faz, pois todas as operações de transferência de dados, forma colocados nele, e possivelmente você possa utilizar estas operações para um select2select no mesmo cfform.
communication.as
function cfform2cfform(connection1:String,connection2:String,gridName:String,buttonAdd:String,buttonPost:String){ /* crio o objeto LocalConnection */
cfLocalConnection.receptor(connection1);
/* primeira ação
nela permitimos que um swf remoto adicione uma linha no select local */
var f1:Function = function(item:Object){
_root[gridName].addItem(item.label,item.data);
_root[gridName].selectedIndex = null;
};
/* adicionamos esta ação no objeto, impondo nome ADD */
cfLocalConnection.append(‘add’,f1);
/* segunda ação
aqui o swf remoto pode adicionar mais de uma linha no select local */
var f2:Function = function(db:Array){
/* linha estranha?
getDataProvider retona o dataProvider que é um array
concat une dois arrays
setDataProvider atribui um array ao dataProvider */
_root[gridName].setDataProvider(_root[gridName].getDataProvider().concat(db));
};
/* chamaremos esta ação de ADDALL e atribuimos ao objeto LocalConnection */
cfLocalConnection.append(‘addAll’,f2);
/* terceira ação
o swf selecionará todos as linhas do select e enviará o formulário */
var f3:Function = function(){
if(_root[gridName].getLength()>0){
var bd:Array = [];
for(var i = 0; i < _root[gridName].getLength(); i++){
bd.push(i);
}
_root[gridName].setSelectedIndices(bd, false);
}
_root.submitForm();
};
/* denominei esta ação como post */
cfLocalConnection.append(‘post’,f3);
/* primerio evento
esta ação é atribuida ao select local */
var listener1:Object = {};
listener1.change = function(event:Object):Void{
/* ao selecinar, executamos remotamente o metodo ADD, no ouvinte connection2, com o parametro sendo a linha corrente*/
cfLocalConnection.execute(connection2, ‘add’,_root[gridName].getSelectedItem());
/* removemos a linha selecionada */
_root[gridName].removeItemAt(_root[gridName].getSelectedIndex());
/* removemos a seleção */
_root[gridName].selectedIndex = null;
};
/* atribuimos ação ao evento */
_root[gridName].addEventListener(‘change’,listener1);
/* segundo evento
esta ação será atribuida ao botão que adicionará todos os dados da select local no select remoto*/
var listener2:Object = {};
listener2.click = function(event:Object):Void{
/* lista deve ter alguma linha selecionada */
if(_root[gridName].getLength() > 0 ){
/* executamos adição remota */
cfLocalConnection.execute(connection2, ‘addAll’,_root[gridName].getDataProvider());
/* limpamos lista local */
_root[gridName].removeAll();
}
};
/* atribuimos ação ao evento */
_root[buttonAdd].addEventListener(‘click’,listener2);
/* terceiro evento
esta é a ação de submit dos dois formulários */
var listener3:Object = {};
listener3.click = function(event:Object):Void{
/* ver linha 23 */
f3(‘pcsilva’);
/* esta linha está executando o ‘f3();’ no swf remoto */
cfLocalConnection.execute(connection2, ‘post’,'pcsilva’);
};
/* atribuimos ação ao evento */
_root[buttonPost].addEventListener(‘click’,listener3);
}
Por fim, a classe que ficou oculta pelo nome cfLocalConnection, é até simples comparando com o script acima, mas vamos a ela.
cfLocalConnection.as
import mx.controls.Alert;
class cfLocalConnection extends Object{ /* esta variável é a nossa tão falada LocalConnection, ela é quem executará todas as ações */
private static var conn:LocalConnection;
/* aqui armazenamos todas as ações */
public static var actions:Object;
/* amarra a comunição de swfs em um dominio */
public static var domain:String = ‘localhost’;
/* contrutor */
private function cfLocalConnection(){}
/* metodo criador do objeto LocalConnection */
private static function createConnection():Void{
/* cria a o objeto LocalConnection */
conn = new LocalConnection();
/* amarra ao dominio */
conn.allowDomain(domain);
/* cria informe de erro */
conn.onStatus = function(info:Object):Void{
if(info.level==’error’){
Alert.show(‘Receptor inexistente!’,'Erro’);
}
};
if(actions != null){
var i:String;
for(i in actions){
conn[i] = actions[i];
}
}
}
/* cria o receptor */
public static function receptor(connector:String):Void{
if(conn == null){
createConnection();
}
conn.connect(connector);
}
/* execução remota */
public static function execute(recepcao:String,functionName:String,param):Void{
if(conn == null){
createConnection();
}
conn.send(recepcao,functionName,param);
}
/* adiciona ações ao objeto localconnection */
public static function append(functionName:String,currentFunction:Function):Void{
if(conn == null){
createConnection();
}
if(actions == null){
actions = new Object();
}
actions[functionName] = currentFunction;
conn[functionName] = currentFunction;
}
}
Feliz Páscoa.
–
Pedro Claudio
Adobe Certified Professional
Blog |