lunes, 8 de diciembre de 2008

Flex: Ventanas modales e intercambio de datos

A veces es necesario gestionar información fuera del entorno de interfaz que estamos usando, pero esta información ha de estar sincronizada. Una buena opción es el uso de ventanas modales, las cuales se pueden utilizar para, por ejemplo, cuadros de diálogo, barra de herramientas, pop-ups, etc.

El ejemplo práctico con el que vamos a ilustar este artículo, extraerá una ventana con un teclado numérico (muy útil en pantallas táctiles), a partir de la pulsación de un botón ligado a una caja de texto. Al mostrar el teclado numérico, éste contendrá el número tecleado en la caja de texto previa. Cuando se termina de operar con el dato en el teclado numérico, el número resultante se lleva a la caja de texto de la ventana principal.



Ventana modal


En Flex, podemos crear una ventana modal creando un componente que herede de TitleWindow. Para ello, se crea un componente en Flex Builder que utilice este layout. También puede cambiarse el código por defecto que genera el asistente de componentes, sustituyendo Canvas por TitleWindow. Este sería el armazón de nuestra ventana modal (componente TitleWindow):


<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow
xmlns:mx="http://www.adobe.com/2006/mxml"
width="172" height="202"
layout="absolute" title="Teclado"
showCloseButton="true"
close="cerrar();">


</mx:TitleWindow>


Las propiedades utilizadas para este componente son:
- width: Ancho de la ventana
- height: Alto de la ventana
- layout: Forma de la distribución de los componentes dentro de la ventana. El valor "absolute" (absoluto), permitirá colocar los componentes en un sistema de coordenadas X e Y, desde la esquina superior izquierda (0,0)
- title: Título de la ventana
- showCloseButton: Permite mostrar el botón de cierre en la ventana
- close: Qué hacer cuando se hace click en el botón de cierre de la ventana. En este caso se invocará a la función cerrar()

Una vez definida la ventana se incorporan los componentes de la ventana:


<mx:TextInput width="136"
x="10" y="10"
id="txtNumero"
textAlign="right"/>
<mx:Button x="10" y="124"
label="." id="btnComa"
click="ponerComa();"/>
<mx:Button x="58" y="124"
label="0" id="btn0"
click="ponerNumero(0);"/>
<mx:Button x="106" y="124"
label="C" id="btnC"
click="txtNumero.text='0';"/>
<mx:Button x="10" y="94"
label="1" id="btn1"
click="ponerNumero(1);"/>
<mx:Button x="58" y="94"
label="2" id="btn2"
click="ponerNumero(2);"/>
<mx:Button x="106" y="94"
label="3" id="btn3"
click="ponerNumero(3);"/>
<mx:Button x="10" y="64"
label="4" id="btn4"
click="ponerNumero(4);"/>
<mx:Button x="58" y="64"
label="5" id="btn5"
click="ponerNumero(5);"/>
<mx:Button x="106" y="64"
label="6" id="btn6"
click="ponerNumero(6);"/>
<mx:Button label="8"
x="58" y="34" id="btn8"
click="ponerNumero(8);"/>
<mx:Button label="7"
id="btn7" x="10" y="34"
click="ponerNumero(7);"/>
<mx:Button x="106" y="34"
label="9" id="btn9"
click="ponerNumero(9);"/>


Los botones '0' a '9' invocan a la función ponerNumero(), el botón ',' invoca a la función ponerComa() y el botón 'C' pone a cero el número.

Para terminar el código de la ventana quedaría incluir el código ActionScript, el cual se colocaría justo antes de la declaración de los componentes. Este código incluiría las funciones que van a ser invocadas, así como alguna cosa más que se detallará un poco más adelante:


<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;

public var origen:Object;

public function sincronizaTeclado():void
{
var texto:String = origen.text;

if (texto=="")
texto="0";

txtNumero.text = texto;
}

private function ponerNumero(numero:int):void
{
if (txtNumero.text=="0")
if (numero!=0)
txtNumero.text = ""+numero;
else
txtNumero.text = "0"
else
txtNumero.text = txtNumero.text+numero;
}

private function ponerComa():void
{
var texto:String = txtNumero.text;

if (texto=="0")
texto="0,";
else
if (texto.indexOf(",")<1)
texto+=",";

txtNumero.text = texto;
}

private function cerrar():void
{
var texto:String=txtNumero.text;

if (texto.charAt(texto.length-1)==',')
texto = texto.substr(0, texto.length-1);

origen.text = texto;
PopUpManager.removePopUp(this);
}

]]>
</mx:Script>

La clave de la comunicación entre la ventana modal y la ventana principal es una propiedad objeto que sirva de enlace entre ambas ventanas. A veces se utiliza una referencia a la ventana principal, con el fin de poder acceder desde la ventana modal a todos los elementos públicos de aquella. En esta ocasión se procede a utilizar únicamente un componente interno de la ventana principal, que es la caja de texto. Esta propiedad es la variable 'origen' de tipo Object.

La función sincronizaTeclado() es pública, y se utiliza para sincronizar la caja de texto de la ventana principal con la caja de texto de la ventana modal. Permite validar y realizar una inicialización del dato.

La función ponerNumero() se encarga de escribir el número en el visor. Antes hace comprobaciones, tales como si el número actual es cero, se sustituye por el tecleado, y si no, añade el tecleado al número actual.

La función ponerComa() se encarga de comprobar si no hay antes otra coma en el número que aparece en el visor, antes de proceder a ponerla.

La función cerrar() es invocada al pulsar el botón de cierre de la ventana. Si el número tecleado termina en coma (sin decimales), eliminará la coma, dejando el número entero. Por último, actualiza la caja de texto de la ventana principal (a través de la referencia de la variable 'origen').

Ventana principal


El código de la ventana principal es el siguiente:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute">

<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;

private function mostrarTeclado():void
{
var teclado:WindowTeclado =
WindowTeclado(PopUpManager.createPopUp(
this,WindowTeclado,true));

PopUpManager.centerPopUp(teclado);
teclado.origen = txtNumero;
teclado.sincronizaTeclado();
}

]]>
</mx:Script>

<mx:TextInput x="10" y="10"
id="txtNumero" textAlign="right"/>
<mx:Button x="178" y="10"
label="Teclado" id="btnTeclado"
click="mostrarTeclado();"/>
</mx:Application>


La función mostrarTeclado() contiene la clave del proceso. En primer lugar se define una variable del tipo componente de la ventana modal, la cual se crea invocando a su constructor mediante la creación de un PopUp (PopUpManager.createPopUp()). A esta creación se le pasa tres parámetros: ventana padre (this), ventana a crear (la misma) y si es modal (true) o no (false).

Creada la ventana se centra ésta mediante PopUpManager.centerPopUp().

A continuación se enlaza el elemento de conexión entre las dos ventanas, utilizando la variable 'origen' de la ventana modal. A esta variable se le asigna la referencia al objeto de caja de texto de la ventana principal. A través de este nexo, ambas ventanas pueden comunicar sus datos. En este ejemplo se conecta un sólo dato. en ventanas más complejas, con más datos a unir (como una caja de diálogo), lo mejor es utilizar la referencia a la ventana padre (this), y conectar los elementos comunes entre las dos ventanas.

La última acción es sincronizar los datos entre las dos ventanas, y por ello, se invoca al método sincronizaTeclado() de la ventana modal.

Safe Creative #1001195348709