Comunidad de diseño web y desarrollo en internet

Flash con base de datos Access y ASP - Parte 2

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.

Descargar Archivo

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?

¿No estás registrado aún pero quieres hacerlo antes de publicar tu comentario?

Registrate