El propósito de este tutorial es mostrar el desarrollo paso a paso una película en Flash a partir de un set de datos guardados en un archivo XML. El desafío implica que seamos capaces de mostrar los datos dinámicamente mediante programación en el lenguaje de scripting específico del Flash: ActionScript, logrando que la película funcione correctamente cualquiera sea la cantidad de datos que el XML contenga, situación ideal para sitios web con actualización frecuente de contenidos.
Presentación del archivo XML y algunas nociones sobre Arrays
En la primera parte de este tutorial (Parte
1 - 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.
Independientemente de su origen (generado a partir de una base de datos o tipeado directamente en un editor de texto) el archivo
XML resultante 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:
Trabajando en Flash con ActionScript
Ya con el Flash, abrimos una nueva película que denominaremos representantes.fla.
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 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++) {
// Crear 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:
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 se obtendrá un resultado similar al de la siguiente imagen, dependiendo de los detalles accesorios
de presentación que se agreguen:
Fernando Campaña (Julio de 2006)
Diseño de Sitios Web
Palabras Clave: diseño web, XML, Flash, ActionScript, Array, dinámico, linkage, attachMovie
Copyright Rakidwam Diseño Web 2006 - Se permite la reproducción total o parcial del presente artículo manteniendo el enlace del autor.