En la primera parte de este tutorial (Parte I – de Access a XML) desarrollamos una página ASP que, luego de conectarse a una base de datos Access, recogía los datos correspondientes a los representantes comerciales de una empresa ficticia y los volvía a grabar en formato XML respetando la estructura jerárquica original.
Esta jerarquía implicaba que los Representantes estaban divididos según su País de residencia y que a su vez los Países estaban agrupados en Areas Geográficas.
El archivo XML resultante (Archivo representantes.xml adjunto en los archivos del tutorial) tiene la estructura que se muestra en la siguiente imagen:
Nota: no se muestran los datos, solo la arquitectura general del archivo para el utópico caso de un Area con un solo País y dos Representantes.
Desarrollaremos el resto del trabajo dentro del Flash, desde donde cargaremos el contenido del archivo XML en una serie de Arrays (o Matrices) que a su vez utilizaremos para mostrar dinámicamente los datos.
En este contexto, dinámicamente significa que crearemos en tiempo de ejecución los movieclips que contendrán el texto que queremos mostrar.
Para tratar de que la cosa sea un poco más clara comentaremos primero cuáles serán los Arrays que utilizaremos:
- Un Array de Areas Geográficas, cuyos elementos serán las Areas que se encuentren en el XML.
En el caso del ejemplo será:
areas = [“América del Sur”, “América Central y Caribe”, “América del Norte”, “Europa”]
- Un Array por cada Area Geográfica, cuyos elementos serán los Países que están incluídos en esa Area.
Por ejemplo:
América del Sur = [“Argentina”, “Brasil”, “Chile”, “Uruguay”]
- Un Array por cada País, cuyos elementos serán los datos de cada uno de los Reresentantes de ese País.
Este Array es peculiar ya que sus elementos son en realidad Arrays Asociativos, que guardan pares dato:”valor”, y son especialmente útiles para los datos personales de los Representantes.
Veamos el ejemplo simplificado del Array Argentina:
Argentina = [“elem1”, “elem2”] tiene dos asociativos:
elem1 = {ciudad:”Buenos Aires”,nombre:”Alejandro”,apellido:”González”,…etc.}
elem2 = {ciudad:”Córdoba”,nombre:”Mabel”,apellido:”Lucero”,…etc.}
Para acceder a sus valores:
Argentina [0].nombre = Alejandro
Argentina[1].ciudad = Córdoba
Trabajando en Flash
Ya con el Flash, abrimos una nueva película que denominaremos, en un exceso de creatividad, como representantes.fla (Archivo Flash representantes.fla adjunto en los archivos del tuto).
Denominaremos la primera capa como Actionscript y allí colocaremos todo el código utilizando el Panel de Acciones (F9 para abrir).
En el fotograma 1 colocaremos primero el código encargado de:
- Cargar los datos del XML dentro de un Objeto XML del Flash
- Construir el esquema de Arrays que analizamos un poco más arriba
Utilizaremos tres bucles for anidados (Areas, Países de cada Area y Representantes de cada País).
Debemos recordar que desconocemos de antemano el nombre que tomarán la mayoría de los Arrays (dependerán de los datos contenidos en la base), por lo que deberán declararse como _root[nombre_variable] (sin punto).
Cargar datos y armar Arrays
// Nos aseguramos que se muestren bien los acentos System.useCodepage = true; // Creamos el objeto que guardará los datos del archivo XML represXML = new XML(); represXML.ignoreWhite = true; //Cargamos el archivo XML en el objeto recién creado represXML.load("../xml/representantes.xml"); // Cuando termina de cargar lo mandamos a organizar para poder mostrar los datos represXML.onLoad = organizarXML; stop(); // Esta es la función encargada de armar los Arrays a partir de los datos function organizarXML() { // Array para las Areas Geográficas areas = new Array(); // Primer bucle para buscar Areas revisando todos los primeros nodos // ejemplo: América del Sur, América Central, etc. for (yy=0; yy<represXML.firstChild.childNodes.length; yy++) { // Agregar el nombre del Area (guardado como Atributo) al Array de Areas Geográficas areas.push(represXML.firstChild.childNodes[yy].attributes.nombre); // Crear un Array con el nombre de cada una de las Áreas encontradas _root[represXML.firstChild.childNodes[yy].attributes.nombre] = new Array(); // Segundo bucle para buscar el nombre de los Países (atributo) de cada Area // ejemplo: Argentina, Brasil, etc. for (aa=0; aa<represXML.firstChild.childNodes[yy].childNodes.length; aa++) { // Agregar el nombre del País al Array del Area a la que pertenece _root[represXML.firstChild.childNodes[yy].attributes.nombre].push(represXML.firstChild.childNodes[yy].childNodes[aa].attributes.nombre); // Utilizar el nombre de cada País (ejemplo: Argentina) para crear un nuevo Array // donde se van a guardar los datos de los Representantes que pertenecen a ese país _root[represXML.firstChild.childNodes[yy].childNodes[aa].attributes.nombre] = new Array(); // Tercer bucle para entrar a cada Representante y leer sus atributos for (bb=0; bb<represXML.firstChild.childNodes[yy].childNodes[aa].childNodes.length; bb++) { // Creo un Objeto para guardar los datos de cada Representante como si fueran propiedades del Objeto (array asociativo con pares dato:”valor” ) repre = new Object(); repre.ciudad = represXML.firstChild.childNodes[yy].childNodes[aa].childNodes[bb].attributes.ciudad; repre.nombre = represXML.firstChild.childNodes[yy].childNodes[aa].childNodes[bb].attributes.nombre; repre.apellido = represXML.firstChild.childNodes[yy].childNodes[aa].childNodes[bb].attributes.apellido; repre.telefono = represXML.firstChild.childNodes[yy].childNodes[aa].childNodes[bb].attributes.telefono; repre.email = represXML.firstChild.childNodes[yy].childNodes[aa].childNodes[bb].attributes.email; // Agrego el Objeto (datos representante) al Array del país _root[represXML.firstChild.childNodes[yy].childNodes[aa].attributes.nombre].push(repre); // Elimino el Objeto delete repre; } } } // Mandamos los datos ya organizados a que se muestren (la función está más abajo) mostrarDatos(); }
En este punto tenemos nuestros datos poblando una serie de Arrays y solo nos resta mostrarlos ordenadamente.
Mostrar los datos dinámicamente
Dado que disponemos de tres tipos de datos: Area, País y los datos del Representante, agregaremos a la Biblioteca tres movieclips. Cada movieclip tendrá como contenido cajas de texto dinámico que mostrarán el contenido de las siguientes variables:
- mc_areas (identificador para linkage: mc_areas)
- tx_area
- mc_paises (identificador para linkage: mc_paises)
- tx_pais
- mc_repres (identificador para linkage: mc_repres)
- tx_ciudad
- tx_nom_ape
- tx_telefono
- tx_email
Por ejemplo, para el mc_areas:
Como estos movieclips se agregarán al escenario dinámicamente debemos indicarle al Flash que los exporte para ser utilizados en tiempo de ejecución. Esto lo realizamos indicando un identificador para Linkage, que por comodidad establecemos igual al nombre del movieclip.
Para establecer el identificador se debe pulsar con el botón derecho del mouse sobre el movieclip en la Biblioteca y seleccionar Linkage en el menú emergente.
Básicamente lo que haremos será crear un movieclip vacío que denominaremos “contenedor”, que contendrá la lista en sí, utilizando createEmptyMovieClip(nombre de instancia, nivel).
De un modo similar a lo que hicimos antes, utilizaremos tres bucles for anidados para recorrer nuestros Arrays e iremos sucesivamente agregando a “contenedor” instancias de los movieclips que tenemos en la Biblioteca mediante attachMovie(id. de linkage, nombre de instancia, nivel).
Como la lista resultará extensa (tendrá un desarrollo vertical mayor que el alto de la película) crearemos otro movieclip vacío (denominado “mc_msk”) y dentro dibujaremos con ActionScript un rectángulo del tamaño apropiado para oficiar de “ventana”.
Colocando a “mc_msk” como máscara de “contenedor” lograremos ocultar el sobrante de la lista y solo restará hacer que “contenedor” se deslice hacia arriba y hacia abajo dentro de ciertos límites para que todos los Representantes resultes visibles.
El siguiente código continúa al anterior:
function mostrarDatos() { // Creamos un mc vacío para encapsular la lista de Representantes // y lo posicionamos en el escenario principal _root.createEmptyMovieClip("contenedor", 300); _root.contenedor._x = 10; _root.contenedor._y = 50; // Construímos la lista intContaPaises = 0; intContaRepres = 0; intPosicion = 0; intSeparar = 50; // Para cada una de las Areas for (aa=0; aa<areas.length; aa++) { _root.contenedor.attachMovie("mc_areas", "mc_areas"+aa, aa); _root.contenedor["mc_areas"+aa]._y = (intPosicion*intSeparar); _root.contenedor["mc_areas"+aa]._x = 25; _root.contenedor["mc_areas"+aa].tx_area = areas[aa]; intPosicion++; // Para cada uno de los Países del Area for (bb=0; bb<_root[areas[aa]].length; bb++) { _root.contenedor.attachMovie("mc_paises", "mc_paises"+intContaPaises, 100+intContaPaises); _root.contenedor["mc_paises"+intContaPaises]._y = (intPosicion*intSeparar); _root.contenedor["mc_paises"+intContaPaises]._x = 45; _root.contenedor["mc_paises"+intContaPaises].tx_pais = _root[areas[aa]][bb]; intPosicion++; // Para cada Representante de cada País for (cc=0; cc<_root[_root[areas[aa]][bb]].length; cc++) { _root.contenedor.attachMovie("mc_repres", "mc_repres"+intContaRepres, 200+intContaRepres); _root.contenedor["mc_repres"+intContaRepres]._y = (intPosicion*intSeparar); _root.contenedor["mc_repres"+intContaRepres]._x = 55; _root.contenedor["mc_repres"+intContaRepres].tx_ciudad = _root[_root[areas[aa]][bb]][cc].ciudad; _root.contenedor["mc_repres"+intContaRepres].tx_nom_ape = _root[_root[areas[aa]][bb]][cc].nombre+" "+_root[_root[areas[aa]][bb]][cc].apellido; _root.contenedor["mc_repres"+intContaRepres].tx_telefono = _root[_root[areas[aa]][bb]][cc].telefono; _root.contenedor["mc_repres"+intContaRepres].tx_email = _root[_root[areas[aa]][bb]][cc].email; intPosicion++; intContaRepres++; } intContaPaises++; } } // Creamos un nuevo mc en el que dibujamos un rectángulo con las dimensiones // apropiadas para el tamaño de nuestra película _root.createEmptyMovieClip("mc_msk", 301); mc_msk._x = 10; mc_msk._y = 50; // Dibujamos el rectángulo (en este caso de 530px de ancho por 350px de alto) // No importan los colores de trazo y relleno porque no se verá, lo utilizaremos como máscara. with (mc_msk) { beginFill(0xff0000, 50); lineStyle(1, 0x00ff00, 100); lineTo(530, 0); lineTo(530, 350); lineTo(0, 350); lineTo(0, 0); endFill(); } // Enmascaramos el listado con el recuadro que acabamos de dibujar y LISTO! ;-) _root.contenedor.setMask(mc_msk); }
Como último detalle ponemos el código de los botones que manejan el scroll de “contenedor”:
Botón Subir
on (release) { if (_root.contenedor._y<_root.mc_msk._y) { _root.contenedor._y += _root.intSeparar; } }
Botón Bajar
on (release) { if (_root.contenedor._y>_root.mc_msk._height-_root.contenedor._height) { _root.contenedor._y -= _root.intSeparar; } }
Al ejecutar la película terminada(representantes.swf adjunta en los archivos) se obtendrá un resultado similar al de la siguiente imagen, dependiendo de los detalles accesorios de presentación que se agreguen:
¿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.
Publica tu comentario
El autor de este artículo ha cerrado los comentarios. Si tienes preguntas o comentarios, puedes hacerlos en el foro
Entra al foro y participa en la discusión
o puedes...
¿Estás registrado en Cristalab y quieres
publicar tu URL y avatar?
Inicia sesión
¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?
Registrate