<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Código Metrópoli - Blog de programación &#187; AIR</title>
	<atom:link href="http://www.codigometropoli.com/category/air/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.codigometropoli.com</link>
	<description>Programación para Super Héroes</description>
	<lastBuildDate>Wed, 27 Apr 2011 07:20:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Sistema de Clientes (AIR y SQLite) Parte IV (Consulta a la base de datos)</title>
		<link>http://www.codigometropoli.com/sistema-de-clientes-parte-iv/</link>
		<comments>http://www.codigometropoli.com/sistema-de-clientes-parte-iv/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 05:30:04 +0000</pubDate>
		<dc:creator>Carla Macías</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Proyectos]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Proyecto]]></category>
		<category><![CDATA[Sistema]]></category>

		<guid isPermaLink="false">http://www.codigometropoli.com/?p=350</guid>
		<description><![CDATA[Esta es la cuarta y última parte del proyecto &#8220;Sistema de Clientes&#8221; desarrollado en AIR con SQLite como administrador de base de datos. En la entrada anterior vimos cómo modificar y eliminar registros en la base de datos (clientesDB.sqlite) desde nuestra aplicación en AIR. En esta ocasión veremos cómo realizar consultas de los registros en [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" style="float: right;" src="http://codigometropoli.com/images/air.png" alt="Adobe AIR" width="93" height="93" />Esta es la cuarta y última parte del proyecto &#8220;Sistema de Clientes&#8221; desarrollado en AIR con SQLite como administrador de base de datos. En la <a href="http://www.codigometropoli.com/sistema-de-clientes-parte-iii/" target="_blank">entrada</a> anterior vimos cómo modificar y eliminar registros en la base de datos (<em>clientesDB.sqlite</em>) desde nuestra aplicación en AIR.</p>
<p><span id="more-350"></span></p>
<p>En esta ocasión veremos cómo realizar consultas de los registros en la base de datos; para esto crearemos una forma en la cual el usuario puede introducir el nombre, teléfono o correo del cliente que está buscando. Los resultados de esta consulta los escribiremos en un archivo HTML y lo mostraremos dentro del componente <strong>HTML </strong>(aprovechando el <a href="http://www.codigometropoli.com/crear-archivo-en-air-con-flex-builder-3/" target="_blank">post</a> que publiqué hace ya tiempo sobre cómo crear un archivo en AIR).</p>
<p><span style="color: #ff0000;"><strong>Parte 4: Consulta a la base de datos en SQLite con AIR</strong></span></p>
<p>Recuerda que para mantener organizado el código de nuestro proyecto y para evitar que se pierdan con toda la información aquí mostrada, dividí el código del proyecto en archivos .as. Estos archivos estarán almacenados en la carpeta actionscript. La estructura de nuestro proyecto será la siguiente:</p>
<div align="center">
<div class="wp-caption aligncenter" style="width: 255px"><img title="Imagen 1: Estructura de la aplicación" src="http://www.codigometropoli.com/wp-content/uploads/2008/08/proy1image1.jpg" alt="Imagen 1: Estructura de la aplicación" width="245" height="373" />
<p class="wp-caption-text">Imagen 1: Estructura de la aplicación</p>
</div>
</div>
<p>Todas las interfaces de este proyecto están incluidas en la carpeta <em>componentes</em>. La interfaz que en esta ocasión veremos es la del archivo <em>ConsultaClientes.mxml</em>. Esta interfaz funciona de la siguiente manera:</p>
<div align="center">
<div class="wp-caption aligncenter" style="width: 391px"><a href="http://www.codigometropoli.com/images/screens/proy1image7.jpg" target="_blank"><img alt="Imagen 2: Interfaz del usuario" src="http://www.codigometropoli.com/images/previews/proy1image7.jpg" title="Imagen 2: Interfaz del usuario" width="381" height="295" /></a><p class="wp-caption-text">Imagen 2: Interfaz del usuario</p></div>
</div>
<p>Al seleccionar la opción &#8220;Consultar…&#8221; del menú, se mostrará una forma con tres campos de texto, en donde el usuario podrá introducir el nombre, teléfono y correo del cliente que está buscando. Además, en la forma tendremos el botón de <em>Mostrar</em>el cual ejecutará la búsqueda. Los resultados serán mostrados dentro del rectángulo que ves en la parte de abajo de la imagen anterior.</p>
<p>Una vez que el usuario ejecute al búsqueda, si no se encontraron registros que coincidan con los datos buscados, el sistema mostrará dentro del archivo HTML la leyenda &#8220;<em>No se encontraron resultados</em>&#8220;. En caso contrario, el sistema mostrará los resultados de forma similar a la mostrada a continuación:</p>
<div align="center">
<div class="wp-caption aligncenter" style="width: 389px"><a href="http://www.codigometropoli.com/images/screens/proy1image8.jpg" target="_blank"><img alt="Imagen 2: Interfaz del usuario" src="http://www.codigometropoli.com/images/previews/proy1image8.jpg" title="Imagen 3: Resultado de la consulta" width="379" height="267" /></a><p class="wp-caption-text">Imagen 2: Interfaz del usuario</p></div>
</div>
<p>Dicho lo anterior, comenzaremos mostrando la estructura y el código del archivo <em>ConsultaClientes.mxml</em>:</p>
<ul>
<li>El <strong>ID</strong> del <strong>TextInput</strong> Nombre es <em>nombre_txt</em></li>
<li>El <strong>ID</strong> del <strong>TextInput</strong> Correo es <em>correo_txt</em></li>
<li>El <strong>ID</strong> del <strong>TextInput</strong> Teléfono es <em>teléfono_txt</em></li>
<li>El <strong>ID</strong> del componente <strong>HTML</strong> es <em>HTMLLoader</em></li>
</ul>
<p>El código de este  archivo  es el siguiente:</p>
<pre class="brush: as3;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Canvas show=&quot;abreConexion();&quot; xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; width=&quot;100%&quot; height=&quot;100%&quot; backgroundColor=&quot;#FFFFFF&quot;&gt;
	&lt;mx:Script source=&quot;../actionscript/ConsultarCliente.as&quot;/&gt;
	&lt;mx:Label y=&quot;13&quot; text=&quot;Consulta de Clientes&quot; right=&quot;75&quot; left=&quot;55&quot; textAlign=&quot;center&quot; fontWeight=&quot;bold&quot; fontSize=&quot;14&quot; fontFamily=&quot;Verdana&quot; color=&quot;#F64507&quot;/&gt;
	&lt;mx:Label y=&quot;61&quot; text=&quot;Mostrar clientes por:&quot; textAlign=&quot;left&quot; fontWeight=&quot;normal&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; color=&quot;#000000&quot; width=&quot;151&quot; x=&quot;31&quot; textDecoration=&quot;underline&quot;/&gt;
	&lt;mx:Label y=&quot;89&quot; text=&quot;Nombre:&quot; textAlign=&quot;left&quot; fontWeight=&quot;normal&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; color=&quot;#000000&quot; width=&quot;83&quot; x=&quot;62&quot;/&gt;
	&lt;mx:Label y=&quot;119&quot; text=&quot;Correo:&quot; textAlign=&quot;left&quot; fontWeight=&quot;normal&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; color=&quot;#000000&quot; width=&quot;65&quot; x=&quot;62&quot;/&gt;
	&lt;mx:Label y=&quot;89&quot; text=&quot;Teléfono:&quot; textAlign=&quot;left&quot; fontWeight=&quot;normal&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; color=&quot;#000000&quot; width=&quot;74&quot; x=&quot;285&quot;/&gt;
	&lt;mx:Button x=&quot;415&quot; y=&quot;119&quot; label=&quot;Mostrar&quot; click=&quot;generaConsulta();&quot;/&gt;
	&lt;mx:HTML focusEnabled=&quot;false&quot; id=&quot;HTMLLoader&quot; borderStyle=&quot;solid&quot; left=&quot;31&quot; top=&quot;171&quot; right=&quot;31&quot; bottom=&quot;21&quot;/&gt;
	&lt;mx:TextInput y=&quot;89&quot; width=&quot;130&quot; height=&quot;21&quot; id=&quot;nombre_txt&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; x=&quot;123&quot;/&gt;
	&lt;mx:TextInput y=&quot;89&quot; width=&quot;130&quot; height=&quot;21&quot; id=&quot;telefono_txt&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; x=&quot;355&quot;/&gt;
	&lt;mx:TextInput y=&quot;119&quot; width=&quot;130&quot; height=&quot;21&quot; id=&quot;correo_txt&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; x=&quot;123&quot;/&gt;
&lt;/mx:Canvas&gt;
</pre>
<p>Observa en el código anterior que el tag principal de este archivo es <strong>&lt;mx:Canvas&gt;</strong> y no <strong>&lt;mx:WindowedApplication&gt;</strong>, esto es porque todas las interfaces que están dentro del directorio componentes las desplegaremos dentro de la aplicación principal (<em>Sistema_Clientes.mxml</em>); a la propiedad <strong>show</strong> del <strong>Canvas</strong> le estamos especificando que llame a la función  <em>abreConexion() </em>una vez que se haya terminado de mostrar el componente. También observa cómo estamos incluyendo el código de <em>ConsultarCliente.as</em>:</p>
<pre class="brush: as3;">
&lt;mx:Script source=&quot;../actionscript/ConsultarCliente.as&quot;/&gt;
</pre>
<p>Dentro del código del botón <em>Mostrar</em> hacemos la llamada a la función <em>generaConsulta</em> una vez que el usuario haya hecho click en dicho botón. El código de esta función (<em>generaConsulta</em>) y de la función principal (<em>abreConexion</em>) se encuentra dentro del archivo ConsultarCliente.as:</p>
<pre class="brush: as3;">
/* Importamos todas las librerías y clases que necesitamos. La clase HTMLTags la hice para establecer el código de cada elemento del archivo HTML, así como los estilos que usa dicho archivo; esta clase la veremos más adelante. */
import clases.HTMLTags;
	import flash.data.SQLConnection;
	import flash.events.SQLErrorEvent;
	import flash.events.SQLEvent;
	import flash.filesystem.File;
	import flash.html.HTMLLoader;
	import mx.controls.Alert;

/* Es importante establecer el tipo de codficación (encodeType) para que, al momento de escribir y generar el archivo, se muestren los acentos correctamente.  */
	private var _encodeType:String = &quot;iso-8859-1&quot;;
	private var conexion:SQLConnection;
	private var database:File;
	private var stream:FileStream = new FileStream(); /* Declaramos una variable de tipo FileStream para poder crear y escribir en el archivo */
	private var htmlElements:HTMLTags = new HTMLTags();/* Este es un objeto de nuestra clase HTMLTags */
	private var queryStatement:SQLStatement = new SQLStatement();
public function abreConexion():void {
	    database = new File(File.applicationStorageDirectory.nativePath + &quot;\database\clientesDB.sqlite&quot;);
	    conexion = new SQLConnection();
	    conexion.addEventListener(SQLEvent.OPEN, dbAbrirConexion);
	    conexion.addEventListener(SQLErrorEvent.ERROR, dbErrorConexion);
	    conexion.open(database);
	}

	private function dbAbrirConexion(event:SQLEvent):void {

	}

	private function dbErrorConexion():void {
		Alert.show(&quot;No se pudo conectar a la base de datos&quot;);
	}
</pre>
<p>Después de haber importado las librerías necesarias y de haber declarado nuestras variables, escribimos el código de la función <em>abreConexion</em>. Esta función la hemos estado utilizando en las entradas anteriores, por lo que su código no debería causarte ruido.</p>
<p>Antes de ver el código de la función <em>generaConsulta</em>, mostraré el código de la clase HTMLTags:</p>
<pre class="brush: as3;">
package clases
{
	public class HTMLTags
	{
		public function HTMLTags()
		{
		}

		public function getEndTags():String {
			var _texto:String = '&lt;/body&gt;\n&lt;/html&gt;\n';
			return _texto;
		}

		public function getRulerTag():String {
			var _texto:String = '&lt;hr class=&quot;Ruler&quot; /&gt;\n';
			return _texto;
		}

		public function getFirstTags():String {
			var _texto:String = '&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;\n' +
			'&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;\n' +
			'&lt;head&gt;\n' +
			'&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-2&quot; /&gt;\n' +
			'&lt;title&gt;Consulta: Tarjetas&lt;/title&gt;\n' +
			'&lt;style&gt;\n' +
			'body {\n' +
			'	font:Arial, Helvetica, sans-serif;\n' +
			'	font-family:Arial, Helvetica, sans-serif;\n' +
			'	font-size:12px;\n' +
			'	margin-left:30px;\n' +
			'}\n' +
			'hr.Ruler {\n' +
			'	margin-left:-20px !important;\n' +
			'	color:#003366;\n' +
			'	border:1px solid #003366;\n' +
			'	background-color:#003366;\n' +
			'	width:800px;\n' +
			'}\n' +
			'.Estilo3 {\n' +
			'	color: #993300;\n' +
			'	font-weight: bold;\n' +
			'	font-size: 14px;\n' +
			'}\n' +
			'.Estilo4 {font-size: 12px; color: #666666;}\n' +
			'.Tabla_Datos td {\n' +
			'	height:25px;\n' +
			'}\n' +
			'&lt;/style&gt;\n' +
			'&lt;/head&gt;\n' +
			'&lt;body&gt;\n';
			return _texto;
		}

		public function getTitleTags(name:String):String {
			var _texto:String = '&lt;br /&gt;&lt;span class=&quot;Estilo3&quot;&gt;' + name + '&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;\n';
			return _texto;
		}

		public function getTable1Tags(nombre:String, direccion:String):String {
			var _texto:String = '&lt;table class=&quot;Tabla_Datos&quot; width=&quot;700&quot; border=&quot;0&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;\n' +
		'  &lt;tr&gt;\n' +
		'    &lt;td&gt;&lt;strong&gt;Nombre:&lt;/strong&gt;&lt;/td&gt;\n' +
		'    &lt;td&gt;' + nombre + '&lt;/td&gt;\n' +
		'    &lt;td&gt;&lt;strong&gt;Dirección:&lt;/strong&gt;&lt;/td&gt;\n' +
		'    &lt;td&gt;' + direccion + '&lt;/td&gt;\n' +
		'  &lt;/tr&gt;\n';
			return _texto;
		}

		public function getTable2Tags(telefono:String, correo:String):String {
			var _texto:String = '' +
		'  &lt;tr&gt;\n' +
		'    &lt;td&gt;&lt;strong&gt;Teléfono:&lt;/strong&gt;&lt;/td&gt;\n' +
		'    &lt;td&gt;' + telefono + '&lt;/td&gt;\n' +
		'    &lt;td&gt;&lt;strong&gt;Correo:&lt;/strong&gt;&lt;/td&gt;\n' +
		'    &lt;td&gt;' + correo + '&lt;/td&gt;\n' +
		'  &lt;/tr&gt;\n' +
		'&lt;/table&gt;\n';
			return _texto;
		}
	}
}
</pre>
<p>Como pudiste observar en el código anterior, esta clase lo único que hace es regresarnos los tags del documento HTML que vamos a generar. Por ejemplo, la función <em>getFirstTags</em> nos regresa los primeros elementos que debe llevar el archivo HTML (los tags &lt;html&gt;, &lt;head&gt;, &lt;meta&gt; y los estilos que usaremos &lt;style&gt;). La función <em>getTitleTags</em> la mandaremos a llamar cada vez que recorramos un nuevo registro, le pasaremos como parámetro un texto de tipo &#8220;Cliente N&#8221; donde N es el valor de un contador que pondremos en el código (Cliente #1, Cliente #2, etc.) y nos regresará un texto con los tags y estilo que debe llevar. A la función <em>getTable1Tags</em> le estamos pasando como parámetro el nombre y la dirección del cliente, y ésta a su vez nos está regresando la información en forma de tabla con el código en HTML. Lo mismo sucede con la función <em>getTable2Tags</em>. La función <em>getRulerTag</em> nos regresa el tag &lt;hr&gt; para mostrar una línea horizontal. Por último, la función <em>getEndTags</em> nos regresa un texto con los tags que nos faltaban por cerrar (&lt;/body&gt; y &lt;/html&gt;).</p>
<p>Ahora veremos el código de generaConsulta. Presta atención en los comentarios que se encuentran dentro del código:</p>
<pre class="brush: as3;">
private function generaConsulta():void {
		var prep:String = &quot; WHERE &quot;;

		queryStatement.clearParameters();
		queryStatement.sqlConnection = conexion;

		var genericQuery:String = &quot;SELECT * FROM cliente &quot;; /* Seleccionamos todas las columnas del registro */

		if(nombre_txt.text != &quot;&quot;) { /* Si el usuario sí escribió algo en el campo de texto nombre_txt */
			genericQuery += prep + &quot; nombre LIKE '%&quot; + nombre_txt.text + &quot;%'&quot;; /* Adjuntamos al query el valor del campo de texto nombre */
			prep = &quot; AND &quot;;
		}
		if(correo_txt.text != &quot;&quot;) { /* Si el usuario sí escribió algo en el campo de texto correo_txt */
			genericQuery += prep + &quot; email LIKE '%&quot; + correo_txt.text + &quot;%'&quot;; /* Adjuntamos al query el valor del campo de texto correo */
			prep = &quot; AND &quot;;
		}
		if(telefono_txt.text != &quot;&quot;) { /* Si el usuario sí escribió algo en el campo de texto telefono_txt */
			genericQuery += prep + &quot; telefono LIKE '%&quot; + telefono_txt.text + &quot;%'&quot;; /* Adjuntamos al query el valor del campo de texto telefono */
			prep = &quot; AND &quot;;
		}

		genericQuery += &quot; ORDER BY nombre asc&quot;; /* Le especificamos al query que los resultados los ordene de manera ascendente de acuerdo al nombre del cliente */		

		queryStatement.text = genericQuery; // Asignamos la variable del query al SQLStatement

		try {
			queryStatement.execute(); // Ejecutamos la consulta

			/* Este será el archivo HTML que estamos creando. Su nombre es ConsultaCliente.html y se encontrará dentro de la carpeta HTML */
			var htmlFile:File = new File(File.applicationStorageDirectory.nativePath + &quot;/HTML/ConsultaCliente.html&quot;);

			if(stream != null) {
				stream.close(); /* Cerramos el stream si es que existe */
			}
			stream = new FileStream();
			stream.open(htmlFile, FileMode.WRITE); /* Abrimos el stream en modo de escritura */
			stream.addEventListener(IOErrorEvent.IO_ERROR, writeIOErrorHandler); /* Establecemos un listener para detectar el evento */

			var result:SQLResult = queryStatement.getResult(); /* Obtenemos los resultados regresados por la consulta */

			if(result.data != null) { // Si existen resultados...
				var numResults:int = result.data.length; // Determinamos el total de resultados regresados

				stream.writeUTFBytes(htmlElements.getFirstTags()); /* Escribimos en el archivo el texto regresado por la clase HTMLTags en su función getFirstTags */

		    	for (var i:int = 0; i &lt; numResults; i++) // Hacemos un ciclo para recorrer todos los registros obtenidos
			    {
			    	var row:Object = result.data[i];
			    	row.nombre;			    	

		    	/* Esta parte entraría a un ciclo */
					stream.writeMultiByte(htmlElements.getTitleTags(&quot;Cliente #&quot; + (i + 1)), _encodeType);
					stream.writeMultiByte(htmlElements.getTable1Tags(row.nombre, row.direccion), _encodeType);
					stream.writeMultiByte(htmlElements.getTable2Tags(row.telefono, row.email), _encodeType);
					stream.writeUTFBytes(htmlElements.getRulerTag());
				/* Esta parte entraría a un ciclo */
			    }
			    stream.writeUTFBytes(htmlElements.getEndTags());
			}
		    else {
		    	stream.writeUTFBytes(&quot;No se encontraron resultados&quot;);
		    }
		    stream.close();
		}
		catch(error:SQLError) {
			trace(&quot;Error: &quot; + error.toString());
		}

		/* Si todo salió bien, ahora podremos mostrar el archivo html en nuestro HTMLLoader */
		HTMLLoader.location = File.applicationStorageDirectory.nativePath + &quot;/HTML/ConsultaCliente.html&quot;;
	}
</pre>
<p>Observa que al final estamos especificando al control <strong>HTML</strong> (cuyo <strong>ID</strong> es <em>HTMLLoader</em>) el archivo HTML que debe mostrar (ConsultaCliente.html dentro de la carpeta HTML).</p>
<p>Hemos llegado al final de esta cuarta parte y de todas las entregas, no olvides bajar los archivos que se encuentran más abajo.</p>
<div align="center" style="margin-top:0px"><script type="text/javascript"><!--
      google_ad_client = "pub-5808310808246221";
      /* 250x250, Posts */
      google_ad_slot = "8254875600";
      google_ad_width = 250;
      google_ad_height = 250;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></div>
<div style="margin-top:30px; margin-bottom:20px;" align="center">
<table border="0" cellspacing="0" cellpadding="0" width="180">
<tbody>
<tr>
<td valign="top"><a href="http://www.megaupload.com/?d=277H67ZZ" target="_blank"><img src="../images/descargar.png" alt="Descargar Archivo" /></a></td>
</tr>
</tbody>
</table>
</div>
<div style="margin-top:40px; margin-bottom:30px;">
<p><strong>Enlaces recomendados:</strong></p>
<p>» <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=SQL_01.html" target="_blank">Working with local SQL databases</a><br />
» <a href="http://livedocs.adobe.com/flex/3/langref/index.html" target="_blank">Adobe® Flex® 3 Language Reference</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.codigometropoli.com/sistema-de-clientes-parte-iv/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Sistema de Clientes (AIR y SQLite) Parte III (Modificar y Eliminar Registros)</title>
		<link>http://www.codigometropoli.com/sistema-de-clientes-parte-iii/</link>
		<comments>http://www.codigometropoli.com/sistema-de-clientes-parte-iii/#comments</comments>
		<pubDate>Mon, 08 Sep 2008 04:15:49 +0000</pubDate>
		<dc:creator>Carla Macías</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Proyectos]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Proyecto]]></category>
		<category><![CDATA[Sistema]]></category>

		<guid isPermaLink="false">http://www.codigometropoli.com/?p=334</guid>
		<description><![CDATA[Esta es la tercera parte del proyecto &#8220;Sistema de Clientes&#8221; desarrollado en AIR con SQLite como administrador de base de datos. En la entrada anterior vimos cómo insertar registros en la base de datos (clientesDB.sqlite) desde nuestra aplicación en AIR. En esta ocasión veremos cómo editar y eliminar registros de la base de datos; para [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" style="float: right;" src="http://codigometropoli.com/images/air.png" alt="Adobe AIR" width="93" height="93" />Esta es la tercera parte del proyecto &#8220;Sistema de Clientes&#8221; desarrollado en AIR con SQLite como administrador de base de datos. En la <a href="http://www.codigometropoli.com/sistema-de-clientes-parte-ii/" target="_blank">entrada</a> anterior vimos cómo insertar registros en la base de datos (<em>clientesDB.sqlite</em>) desde nuestra aplicación en AIR.<br />
En esta ocasión veremos cómo editar y eliminar registros de la base de datos; para esto mostraremos dentro de un DataGrid todos los registros que tenemos en nuestra base de datos; en este DataGrid usaremos <strong>itemRenderer(s)</strong> para llenar con botones dos columnas, uno de los botones será para editar el registro seleccionado y el otro para eliminarlo.</p>
<p><span id="more-334"></span><span style="color: #ff0000;"><strong>Parte 3: Modificar y eliminar registros en SQLite con AIR</strong></span></p>
<p>Recuerda que para mantener organizado el código de nuestro proyecto y para evitar que se pierdan con toda la información aquí mostrada, dividí el código del proyecto en archivos .as. Estos archivos estarán almacenados en la carpeta actionscript. La estructura de nuestro proyecto será la siguiente:</p>
<div align="center">
<div class="wp-caption aligncenter" style="width: 255px"><img title="Imagen 1: Estructura de la aplicación" src="http://www.codigometropoli.com/wp-content/uploads/2008/08/proy1image1.jpg" alt="Imagen 1: Estructura de la aplicación" width="245" height="373" /><p class="wp-caption-text">Imagen 1: Estructura de la aplicación</p></div>
</div>
<p>Todas las interfaces de este proyecto están incluidas en la carpeta componentes. La interfaz que en esta ocasión veremos es la del archivo <em>EditarBorrarCliente.mxml</em>. Esta interfaz funciona de la siguiente manera:</p>
<div align="center">
<div class="wp-caption aligncenter" style="width: 552px"><a href="http://www.codigometropoli.com/images/screens/proy1image4.jpg" target="_blank"><img title="Imagen 2: Interfaz del usuario" src="http://www.codigometropoli.com/images/previews/proy1image4.jpg" alt="Imagen 2: Interfaz del usuario" width="542" height="255" /></a><p class="wp-caption-text">Imagen 2: Interfaz del usuario</p></div>
</div>
<p>Al seleccionar la opción &#8220;Editar/Eliminar…&#8221; del menú, se mostrará un DataGrid con todos los registros que tenemos dados de alta en nuestra base. En este ejemplo solamente tengo dos registros. Si el usuario hace click al botón de <strong>Modificar</strong> del primer registro, se mostrará lo siguiente:</p>
<div align="center">
<div class="wp-caption aligncenter" style="width: 552px"><a href="http://www.codigometropoli.com/images/screens/proy1image5.jpg" target="_blank"><img title="Imagen 3: Opción Modificar Cliente" src="http://www.codigometropoli.com/images/screens/proy1image5.jpg" alt="Imagen 3: Opción Modificar Cliente" width="542" height="511" /></a><p class="wp-caption-text">Imagen 3: Opción Modificar Cliente</p></div>
</div>
<p>…Un Canvas con los datos de nuestro registro. Si el usuario lo desea, podrá modificar o actualizar los datos de este registro. Por el contrario, si el usuario le da click al botón de <strong>Eliminar</strong> del primer registro, se mostrará un mensaje de alerta pidiéndole que confirme si desea o no borrar el registro.</p>
<div align="center">
<div class="wp-caption aligncenter" style="width: 551px"><a href="http://www.codigometropoli.com/images/screens/proy1image6.jpg" target="_blank"><img title="Imagen 4: Mensaje de confirmación" src="http://www.codigometropoli.com/images/previews/proy1image6.jpg" alt="Imagen 4: Mensaje de confirmación" width="541" height="254" /></a><p class="wp-caption-text">Imagen 4: Mensaje de confirmación</p></div>
</div>
<p>Explicado lo anterior, comenzaremos mostrando la estructura y el código del archivo EditarBorrarCliente.mxml:</p>
<ul>
<li> El <strong>ID</strong> del <strong>DataGrid </strong>donde mostraremos los registros es <em>clientes_dg</em></li>
<li>El <strong>ID </strong>de nuestro <strong>Canvas </strong>en donde mostraremos la información del registro que el usuario puede modificar es <em>Modificar_Cliente</em>
<ul>
<li>El botón de <em>Cambiar</em> que se encuentra dentro del Canvas tiene de <strong>ID </strong><em>guardarBtn</em></li>
<li>El botón con una X tiene de <strong>ID </strong><em>cerrarBtn</em></li>
<li>Los <strong>ID</strong>s de cada una de las áreas de texto son:
<ul>
<li>nombre_txt, direccion_txt (TextArea), telefono_txt, correo_txt</li>
<li>Además, tenemos tres etiquetas cuyo texto es <strong>(*)</strong> y con los cuales le indicaremos al usuario qué dato le faltó por llenar. Estas etiquetas tienen de <strong>ID</strong>: <em>msj1</em>, <em>msj2</em>, <em>msj3</em> y <em>msj4</em>.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>El código de este  archivo  es el siguiente:</p>
<pre class="brush: as3;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Canvas show=&quot;abreConexion();&quot; xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; width=&quot;100%&quot; height=&quot;100%&quot; backgroundColor=&quot;#FFFFFF&quot;&gt;
	&lt;mx:Script source=&quot;../actionscript/EditarBorrarCliente.as&quot;/&gt;
	&lt;mx:Label y=&quot;13&quot; text=&quot;Lista de Clientes&quot; right=&quot;75&quot; left=&quot;55&quot; textAlign=&quot;center&quot; fontWeight=&quot;bold&quot; fontSize=&quot;14&quot; fontFamily=&quot;Verdana&quot; color=&quot;#F64507&quot;/&gt;
	&lt;mx:DataGrid y=&quot;57&quot; width=&quot;600&quot; height=&quot;223&quot; horizontalCenter=&quot;-14&quot; id=&quot;clientes_dg&quot;&gt;
		&lt;mx:columns&gt;
			&lt;mx:DataGridColumn width=&quot;150&quot; textAlign=&quot;left&quot; headerText=&quot;Nombre&quot; dataField=&quot;nombre&quot;/&gt;
			&lt;mx:DataGridColumn width=&quot;120&quot; textAlign=&quot;left&quot; headerText=&quot;Teléfono&quot; dataField=&quot;telefono&quot;/&gt;
			&lt;mx:DataGridColumn width=&quot;165&quot; textAlign=&quot;left&quot; headerText=&quot;Correo&quot; dataField=&quot;correo&quot;/&gt;
			&lt;mx:DataGridColumn sortable=&quot;false&quot; width=&quot;85&quot; textAlign=&quot;center&quot; headerText=&quot;Modificar&quot; dataField=&quot;modificar&quot;&gt;
				&lt;mx:itemRenderer&gt;
				&lt;mx:Component&gt;
					&lt;mx:HBox horizontalAlign=&quot;center&quot;&gt;
						&lt;mx:Button id=&quot;editarBtn&quot; click=&quot;outerDocument.editarCliente(data.id_cliente, data.nombre, data.direccion, data.telefono, data.correo)&quot; label=&quot;&quot; height=&quot;20&quot; width=&quot;30&quot; icon=&quot;@Embed(source='../images/edit.png')&quot;/&gt;
					&lt;/mx:HBox&gt;
				&lt;/mx:Component&gt;
				&lt;/mx:itemRenderer&gt;
			&lt;/mx:DataGridColumn&gt;
			&lt;mx:DataGridColumn sortable=&quot;false&quot; width=&quot;80&quot; textAlign=&quot;center&quot; headerText=&quot;Eliminar&quot; dataField=&quot;eliminar&quot;&gt;
				&lt;mx:itemRenderer&gt;
				&lt;mx:Component&gt;
					&lt;mx:HBox horizontalAlign=&quot;center&quot;&gt;
						&lt;mx:Button id=&quot;borrarBtn&quot; click=&quot;outerDocument.borrarCliente(data.id_cliente)&quot; label=&quot;&quot; height=&quot;20&quot; width=&quot;30&quot; icon=&quot;@Embed(source='../images/remove.png')&quot;/&gt;
					&lt;/mx:HBox&gt;
				&lt;/mx:Component&gt;
				&lt;/mx:itemRenderer&gt;
			&lt;/mx:DataGridColumn&gt;
		&lt;/mx:columns&gt;
	&lt;/mx:DataGrid&gt;
	&lt;mx:Canvas id=&quot;Modificar_Cliente&quot; visible=&quot;true&quot; y=&quot;324&quot; width=&quot;378&quot; height=&quot;255&quot; horizontalCenter=&quot;-15&quot; borderColor=&quot;#ADADAD&quot; backgroundAlpha=&quot;0.0&quot; borderStyle=&quot;solid&quot;&gt;
		&lt;mx:Button id=&quot;guardarBtn&quot; click=&quot;validaForma();&quot; y=&quot;221&quot; label=&quot;Cambiar&quot; width=&quot;100&quot; x=&quot;220&quot;/&gt;
		&lt;mx:Label y=&quot;10&quot; text=&quot;Modificar Cliente:&quot; textAlign=&quot;left&quot; fontWeight=&quot;bold&quot; fontSize=&quot;11&quot; fontFamily=&quot;Verdana&quot; color=&quot;#31384B&quot; width=&quot;213&quot; x=&quot;10&quot; textDecoration=&quot;underline&quot;/&gt;
		&lt;mx:Button id=&quot;cerrarBtn&quot; y=&quot;1&quot; label=&quot;X&quot; width=&quot;32&quot; x=&quot;343.3&quot; click=&quot;Modificar_Cliente.visible = false; reseteaForma();&quot; cornerRadius=&quot;0&quot;/&gt;
		&lt;mx:Text visible=&quot;false&quot; x=&quot;10&quot; y=&quot;86&quot; text=&quot;Por favor introduzca la divisa&quot; fontWeight=&quot;bold&quot; color=&quot;#B80808&quot; fontFamily=&quot;Verdana&quot; fontSize=&quot;10&quot; width=&quot;184&quot; height=&quot;33&quot; id=&quot;msj_nombre&quot;/&gt;
		&lt;mx:TextInput y=&quot;50&quot; width=&quot;212&quot; height=&quot;21&quot; id=&quot;nombre_txt&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; x=&quot;108&quot;/&gt;
		&lt;mx:TextArea y=&quot;81&quot; width=&quot;212&quot; height=&quot;69&quot; id=&quot;direccion_txt&quot; x=&quot;108&quot;/&gt;
		&lt;mx:TextInput y=&quot;161&quot; width=&quot;212&quot; height=&quot;21&quot; id=&quot;telefono_txt&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; x=&quot;108&quot;/&gt;
		&lt;mx:TextInput y=&quot;190&quot; width=&quot;212&quot; height=&quot;21&quot; id=&quot;correo_txt&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; x=&quot;108&quot;/&gt;
		&lt;mx:Label y=&quot;50&quot; text=&quot;Nombre:&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;normal&quot; color=&quot;#000000&quot; width=&quot;80&quot; textAlign=&quot;right&quot; x=&quot;10&quot;/&gt;
		&lt;mx:Label y=&quot;86&quot; text=&quot;Dirección:&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;normal&quot; color=&quot;#000000&quot; width=&quot;80&quot; textAlign=&quot;right&quot; x=&quot;10&quot;/&gt;
		&lt;mx:Label y=&quot;161&quot; text=&quot;Teléfono:&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;normal&quot; color=&quot;#000000&quot; width=&quot;80&quot; textAlign=&quot;right&quot; x=&quot;10&quot;/&gt;
		&lt;mx:Label y=&quot;190&quot; text=&quot;Correo:&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;normal&quot; color=&quot;#000000&quot; width=&quot;80&quot; textAlign=&quot;right&quot; x=&quot;10&quot;/&gt;
		&lt;mx:Label y=&quot;50&quot; text=&quot;(*)&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;bold&quot; color=&quot;#B80808&quot; width=&quot;27&quot; textAlign=&quot;left&quot; id=&quot;msj1&quot; visible=&quot;false&quot; horizontalCenter=&quot;153&quot;/&gt;
		&lt;mx:Label y=&quot;82&quot; text=&quot;(*)&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;bold&quot; color=&quot;#B80808&quot; width=&quot;27&quot; textAlign=&quot;left&quot; id=&quot;msj2&quot; visible=&quot;false&quot; horizontalCenter=&quot;153&quot;/&gt;
		&lt;mx:Label y=&quot;161&quot; text=&quot;(*)&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;bold&quot; color=&quot;#B80808&quot; width=&quot;27&quot; textAlign=&quot;left&quot; id=&quot;msj3&quot; visible=&quot;false&quot; horizontalCenter=&quot;153&quot;/&gt;
		&lt;mx:Label y=&quot;190&quot; text=&quot;(*)&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;bold&quot; color=&quot;#B80808&quot; width=&quot;27&quot; textAlign=&quot;left&quot; id=&quot;msj4&quot; visible=&quot;false&quot; horizontalCenter=&quot;153&quot;/&gt;
	&lt;/mx:Canvas&gt;
&lt;/mx:Canvas&gt;
</pre>
<p>Observa en el código anterior que el tag principal de este archivo es <strong>&lt;mx:Canvas&gt; </strong>y no <strong>&lt;mx:WindowedApplication&gt;</strong>, esto es porque todas las interfaces que están dentro del directorio componentes las desplegaremos dentro de la aplicación principal (<em>Sistema_Clientes.mxml</em>); a la propiedad <strong>show </strong>del <strong>Canvas </strong>le estamos especificando que llame a la función  <em>abreConexion()</em> una vez que se haya terminado de mostrar el componente. También observa cómo estamos incluyendo el código de <em>EditarBorrarCliente.as</em>:</p>
<pre class="brush: as3;">
&lt;mx:Script source=&quot;../actionscript/EditarBorrarCliente.as&quot;/&gt;
</pre>
<p>También presta atención en la forma en que estamos creando los <strong>renderers </strong>para las columnas.</p>
<pre class="brush: as3;">
&lt;mx:DataGridColumn sortable=&quot;false&quot; width=&quot;85&quot; textAlign=&quot;center&quot; headerText=&quot;Modificar&quot; dataField=&quot;modificar&quot;&gt;
&lt;mx:itemRenderer&gt;
		&lt;mx:Component&gt;
			&lt;mx:HBox horizontalAlign=&quot;center&quot;&gt;
			&lt;mx:Button id=&quot;editarBtn&quot; click=&quot;outerDocument.editarCliente(data.id_cliente, data.nombre, data.direccion, data.telefono, data.correo)&quot; label=&quot;&quot; height=&quot;20&quot; width=&quot;30&quot; icon=&quot;@Embed(source='../images/edit.png')&quot;/&gt;
			&lt;/mx:HBox&gt;
		&lt;/mx:Component&gt;
	&lt;/mx:itemRenderer&gt;
&lt;/mx:DataGridColumn&gt;
</pre>
<p>Dentro de los tags  <strong>&lt;mx:itemRenderer&gt; </strong>y  <strong>&lt;/mx:itemRenderer&gt; </strong>estamos usando como <em>layout </em>el <strong>HBox </strong>(HorizontalBox), aunque en realidad no afecta mucho ya que sólo estamos poniendo un componente por cada celda (en caso de que pongamos más elementos en esa celda, estos elementos se mostrarán uno tras otro de izquierda a derecha). El componente que estamos insertando en cada celda es un botón; este botón en el momento de hacer <strong>click</strong> sobre él llamará a la función <em>editarCliente</em>, el cual recibe como parámetros el ID, nombre, dirección, teléfono y correo del cliente en cuyo registro hicimos click. La palabra reservada <strong>outerDocument </strong>nos permite acceder a elementos que se encuentran fueran del alcance del item renderer. Además, al botón le estamos asignando el icono edit.png (<img align="absmiddle" src="http://www.codigometropoli.com/images/screens/edit.png" alt="" width="16" height="16" />) que está dentro de nuestra carpeta <em>images</em>. Importante: Observa cómo a esta columna del DataGrid le estamos especificando que no se pueda ordenar (sortable = false). Esto es porque en realidad no le estamos asignando valor alguno a cada celda, por lo tanto si intentáramos ordenar los registros de acuerdo a esta columna, Flex nos desplegaría un error.</p>
<p>El código para la columna que llevará los botones de <em>Eliminar </em>es el siguiente:</p>
<pre class="brush: as3;">
&lt;mx:DataGridColumn sortable=&quot;false&quot; width=&quot;80&quot; textAlign=&quot;center&quot; headerText=&quot;Eliminar&quot; dataField=&quot;eliminar&quot;&gt;
	&lt;mx:itemRenderer&gt;
	&lt;mx:Component&gt;
		&lt;mx:HBox horizontalAlign=&quot;center&quot;&gt;
			&lt;mx:Button id=&quot;borrarBtn&quot; click=&quot;outerDocument.borrarCliente(data.id_cliente)&quot; label=&quot;&quot; height=&quot;20&quot; width=&quot;30&quot; icon=&quot;@Embed(source='../images/remove.png')&quot;/&gt;
		&lt;/mx:HBox&gt;
	&lt;/mx:Component&gt;
	&lt;/mx:itemRenderer&gt;
&lt;/mx:DataGridColumn&gt;
</pre>
<p>El código es similar al mostrado más arriba, lo único que cambia es que en esta ocasión el botón mandará a llamar a la función <em>borrarCliente</em>, pasándole como parámetro el ID del cliente. Además, el icono para este botón es remove.png (<img align="absmiddle" src="http://www.codigometropoli.com/images/screens/remove.png" alt="" width="16" height="16" />).</p>
<p>Antes de ver el código de las funciones <em>editarCliente </em>y <em>borrarCliente</em>, veremos cómo mostrar los registros de nuestra base de datos en el DataGrid. Para eso, el código que pegaré a continuación forma parte del archivo <strong>EditarBorrarCliente.as</strong>.</p>
<p>Primero, importamos las clases y declaramos las variables  que necesitamos. En el arreglo <em>data_provider</em> almacenaremos los datos obtenidos de nuestra consulta y lo asignaremos como <strong>dataProvider </strong>de nuestro DataGrid (<em>clientes_dg</em>). La variable <em>id_selected</em> nos servirá para almacenar el ID del registro seleccionado y posteriormente eliminarlo de la base de datos.</p>
<pre class="brush: as3;">
// ActionScript file

	import flash.data.SQLConnection;
	import flash.events.SQLErrorEvent;
	import flash.events.SQLEvent;

	import mx.controls.Alert;
	import mx.events.CloseEvent;
	import mx.events.ListEvent;

	private var conexion:SQLConnection;
	private var database:File;
	private var queryStatement:SQLStatement = new SQLStatement();
	[Bindable]
	private var data_provider:Array;
	private var id_selected:Number = 0;
</pre>
<p>La primera función que es llamada en esta sección es <em>abrirConexion</em>:</p>
<pre class="brush: as3;">
public function abreConexion():void {
	reseteaForma();
	Modificar_Cliente.visible = false;
	reiniciaVariables();
	clientes_dg.addEventListener(ListEvent.CHANGE, dgChangeHandler);

	database = new File(File.applicationStorageDirectory.nativePath + &quot;\database\clientesDB.sqlite&quot;);
	conexion = new SQLConnection();
	conexion.addEventListener(SQLEvent.OPEN, dbAbrirConexion);
	conexion.addEventListener(SQLErrorEvent.ERROR, dbErrorConexion);
	queryStatement.sqlConnection = conexion;
	conexion.open(database);
}
</pre>
<p>Dentro de <em>abreConexion </em>llamamos a la función <em>reseteaForma</em>, la cual se encarga de borrar los datos de la forma para la modificación de los datos.</p>
<pre class="brush: as3;">
private function reseteaForma():void {
	nombre_txt.text = &quot;&quot;;
	direccion_txt.text = &quot;&quot;;
	telefono_txt.text = &quot;&quot;;
	correo_txt.text = &quot;&quot;;
	escondeMensajes();
}
</pre>
<p>Después de llamar a la función <em>reseteaForma</em>, ocultamos el canvas <em>Modificar_Cliente</em> y llamamos a la función <em>reiniciaVariables</em>, la cual se encargará de resetear los arreglos para eliminar su contenido previo.</p>
<pre class="brush: as3;">
private function reiniciaVariables():void {
	clientes_dg.dataProvider = new Array();	// Reiniciamos el arreglo para eliminar su contenido
	data_provider = new Array(); // Reiniciamos el arreglo para eliminar su contenido
}
</pre>
<p>Posteriormente le asignamos al datagrid <em>clientes_dg</em> el listener del evento <strong>CHANGE</strong>. Este evento es lanzado cuando el usuario hace click en alguno de los registros del DataGrid. Cuando se genere este evento, el programa se encargará de esconder el cambas <em>Modificar_Cliente</em> (es posible que previamente el usuario le haya dado click al botón de <span style="text-decoration: underline;">Editar</span> en alguno de los registros, es por eso que nos aseguramos de esconder el Canvas). Además, almacenamos en la vaiable <em>id_selected</em> el <strong>ID</strong> del registro seleccionado; y, por último, escondemos los posibles mensajes que se le mostraron al usuario para que, cuando vuelva a darle click al botón <span style="text-decoration: underline;">Editar</span>, no se le muestren.</p>
<pre class="brush: as3;">
private function dgChangeHandler(event:ListEvent):void {
escondeMensajes();
	Modificar_Cliente.visible = false;
	id_selected = event.target.selectedItem.id_cliente;
}
</pre>
<p>El resto del código de la función <em>abreConexion</em> ya lo conoces de las entradas anteriores.<br />
Si no hubo ningún problema en la conexión a la base de datos, llamamos a la función <em>getClientes</em> para llenar el DataGrid con nuestros registros:</p>
<pre class="brush: as3;">
private function dbAbrirConexion(event:SQLEvent):void {
	getClientes();
}

private function getClientes():void {
	queryStatement.clearParameters();
	queryStatement.text = &quot;SELECT * FROM cliente ORDER BY nombre asc&quot;;

	try {
		queryStatement.execute();

		var result:SQLResult = queryStatement.getResult();
		if(result.data != null) {
		    var numResults:int = result.data.length;

		    for (var i:int = 0; i &lt; numResults; i++)
		    {
		    	var row:Object = result.data[i];

			data_provider.push({nombre:row.nombre, id_cliente:row.id, direccion:row.direccion, correo:row.email, telefono:row.telefono});
		    }

		    clientes_dg.dataProvider = data_provider;
		}
	}
	catch(error:SQLError) {
		trace(&quot;Error: &quot; + error.toString());
	}
}
</pre>
<p>Dentro del código de <em>getClientes</em> haremos la consulta a la tabla <span style="text-decoration: underline;">cliente</span> para obtener todos los registros de nuestra base. Nuestro query es muy sencillo, en él estamos seleccionando (SELECT)  todas las columnas (*) de la tabla <em>cliente </em>y le estamos diciendo que lo ordene (ORDER BY) de forma ascendente (asc)  de acuerdo a la columna <em>nombre</em>.</p>
<pre class="brush: sql;">
SELECT * FROM cliente ORDER BY nombre asc
</pre>
<p>Una vez que ejecutamos la consulta (queryStatement.execute()) obtenemos el resultado con la función <em>getResult</em>. Comprobamos que el resultado no sea vacío (result.data!= null) y obtenemos el total de registros obtenidos por medio de la propiedad <em>length</em>. Como ya sabemos cuántos registros nos regresó la consulta, haremos un ciclo <strong>for</strong> para almacenar los registros en nuestro arreglo <em>data_provider</em>. Finalmente estamos asignando el arreglo <em>data_provider</em> a la propiedad <strong>dataProvider </strong>del DataGrid. Importante: Si no comprendes esta parte donde llenamos el arreglo y se lo asignamos al DataGrid te recomiendo visitar la entrada sobre el <a href="http://www.codigometropoli.com/componente-datagrid/" target="_blank">Componente DataGrid</a> que publiqué anteriormente.</p>
<p>Hemos terminado la explicación de cómo realizar la consulta a la base de datos y mostrar los resultados en el DataGrid. Ahora veremos las funciones que habíamos dejado pendientes: <em>editarCliente </em>y <em>borrarCliente</em>.<br />
Como lo mencioné anteriormente, cuando el usuario hace click en el botón de Editar de alguno de los registros, la función <em>editarCliente </em>es llamada:</p>
<pre class="brush: as3;">
public function editarCliente(id_cliente:Number, nombre:String, direccion:String, telefono:String, correo:String):void {
	id_selected = id_cliente;
	nombre_txt.text = nombre;
	direccion_txt.text = direccion;
	telefono_txt.text = telefono;
	correo_txt.text = correo;
	Modificar_Cliente.visible = true;
}
</pre>
<p>Esta función recibe como parámetros el ID del cliente, su nombre, dirección, teléfono y correo, para posteriormente mostrarlo en el formulario del canvas <em>Modificar_Cliente</em>. Si el usuario hace click en el botón de <em>Cambiar</em>, la función es <em>validaForma </em>es ejecutada:</p>
<pre class="brush: as3;">
private function validaForma():void {
	escondeMensajes();
	if(nombre_txt.text == &quot;&quot;) {
		msj1.visible = true;
		nombre_txt.setFocus();
	}
	else if(direccion_txt.text == &quot;&quot;) {
		msj2.visible = true;
		direccion_txt.setFocus();
	}
	else if(telefono_txt.text == &quot;&quot;) {
		msj3.visible = true;
		telefono_txt.setFocus();
	}
	else if(correo_txt.text == &quot;&quot; || !mail(correo_txt.text)) {
		msj4.visible = true;
		correo_txt.setFocus();
	}
	else {
		updateCliente(id_selected);
	}
}
</pre>
<p>Esta función es similar a la que usamos en la <a href="http://www.codigometropoli.com/sistema-de-clientes-parte-ii/" target="_blank">entrada</a> anterior, simplemente estamos verificando que todos los datos fueron llenados y, en caso positivo, llamamos a la función <em>updateCliente</em>.</p>
<pre class="brush: as3;">
private function updateCliente(idCliente:Number):void {
	queryStatement.clearParameters();
	var sql:String = &quot;UPDATE `cliente` SET nombre = :nombre, direccion = :direccion, telefono = :telefono, email = :correo WHERE id = :idCliente&quot;;
	queryStatement.parameters[&quot;:nombre&quot;] = nombre_txt.text;
	queryStatement.parameters[&quot;:direccion&quot;] = direccion_txt.text;
	queryStatement.parameters[&quot;:telefono&quot;] = telefono_txt.text;
	queryStatement.parameters[&quot;:correo&quot;] = correo_txt.text;
	queryStatement.parameters[&quot;:idCliente&quot;] = idCliente;
	queryStatement.text = sql;

	try {
		queryStatement.execute();
		abreConexion();
	}
	catch(error:SQLError){
		trace(&quot;Error: &quot; + error.toString());
	}
}
</pre>
<p>Esta función recibe como parámetro el ID del registro seleccionado, crea el query para actualizar los datos del registro y los nuevos valores son pasados como parámetros a la sentencia SQL. Una vez que se ejecuta la sentencia llamamos nuevamente a la función <em>abreConexion </em>para que muestre todos los registros (incluyendo los nuevos) en el DataGrid.</p>
<p>La función <em>borrarCliente </em>es llamada cuando el usuario hace click en el botón de <em>Eliminar</em>:</p>
<pre class="brush: as3;">
public function borrarCliente(id_cliente:Number):void {
	id_selected = id_cliente;
	Alert.yesLabel = &quot;Sí&quot;;
	Alert.noLabel = &quot;No&quot;;
Alert.show(&quot;¿Desea eliminar este cliente?&quot;, &quot;Importante&quot;, 3, this, alertClickHandler);
}
</pre>
<p>Esta función recibe como parámetro el ID del registro seleccionado por el usuario. Además, muestra un mensaje de alerta pidiéndole al usuario que confirme si desea eliminar el registro. Observa que al método <em>show </em>le pasamos como parámetro el manejador de eventos que debe considerar (<em>alertClickHandler</em>). Este manejador de eventos revisa si la respuesta del usuario fue positiva o negativa. En caso de que el usuario haya hecho click en el botón de Sí, llamamos a la función <em>delCliente </em>pasándole como parámetro el ID del registro seleccionado.</p>
<pre class="brush: as3;">
private function alertClickHandler(event:CloseEvent):void {
if (event.detail == Alert.YES)
      	delCliente(id_selected);
}
</pre>
<p>La función <em>delCliente </em>se encarga de ejecutar el query para borrar el registro de la base de datos. A este query le estamos pasando el ID del registro que hay que eliminar. Después de ejecutar la sentencia llamamos nuevamente a la función <em>abreConexion </em>para mostrar todos los registros restantes de la base de datos en el DataGrid.</p>
<pre class="brush: as3;">
private function delCliente(id_cliente:Number):void {
	queryStatement.clearParameters();
	queryStatement.text = &quot;DELETE FROM cliente WHERE id = :id_cliente&quot;;
	queryStatement.parameters[&quot;:id_cliente&quot;] = id_cliente;

	try {
		queryStatement.execute();
		abreConexion();
	}
	catch(error:SQLError) {
		trace(&quot;Error: &quot; + error.toString());
	}
}
</pre>
<p>Hemos llegado al final de esta tercera parte; ya nada más nos queda pendiente la cuarta y última entrega.</p>
<div align="center" style="margin-top:0px"><script type="text/javascript"><!--
      google_ad_client = "pub-5808310808246221";
      /* 250x250, Posts */
      google_ad_slot = "8254875600";
      google_ad_width = 250;
      google_ad_height = 250;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></div>
<div style="margin-top:40px; margin-bottom:30px;">
<p><strong>Enlaces recomendados:</strong></p>
<p>» <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=SQL_01.html" target="_blank">Working with local SQL databases</a><br />
» <a href="http://livedocs.adobe.com/flex/3/langref/index.html" target="_blank">Adobe® Flex® 3 Language Reference</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.codigometropoli.com/sistema-de-clientes-parte-iii/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Sistema de Clientes (AIR y SQLite) Parte II (Insertar Registros)</title>
		<link>http://www.codigometropoli.com/sistema-de-clientes-parte-ii/</link>
		<comments>http://www.codigometropoli.com/sistema-de-clientes-parte-ii/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 16:47:38 +0000</pubDate>
		<dc:creator>Carla Macías</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Proyectos]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Proyecto]]></category>
		<category><![CDATA[Sistema]]></category>

		<guid isPermaLink="false">http://www.codigometropoli.com/?p=312</guid>
		<description><![CDATA[Esta es la segunda parte del proyecto &#8220;Sistema de Clientes&#8221; desarrollado en AIR con SQLite como administrador de base de datos. En la entrada anterior vimos cómo crear la base de datos (clientesDB.sqlite), y cómo llenar con algunos registros por default la tabla cliente. Esta entrada forma parte de un proyecto y los archivos de [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" style="float: right;" src="http://codigometropoli.com/images/air.png" alt="Adobe AIR" width="93" height="93" />Esta es la segunda parte del proyecto &#8220;Sistema de Clientes&#8221; desarrollado en AIR con SQLite como administrador de base de datos. En la <a href="http://www.codigometropoli.com/sistema-de-clientes-parte-i/" target="_blank">entrada</a> anterior vimos cómo crear la base de datos (<em>clientesDB.sqlite</em>), y cómo llenar con algunos registros por default la tabla cliente.<br />
Esta entrada forma parte de un proyecto y los archivos de éste los encontrarás cuando termine de publicar todas las partes (entradas). Recuerda que para este proyecto estamos usando Flex Builder 3, del cual puedes bajarte una versión de prueba del Flex Builder 3 <a href="https://www.adobe.com/cfusion/tdrc/index.cfm?product=flex" target="_blank">aquí</a>.<br />
<span id="more-312"></span></p>
<p>Como lo comenté en el post <a href="http://www.codigometropoli.com/sistema-de-clientes-parte-i/" target="_blank">anterior </a>, aquí mostraré solamente la información más importante y sobre la cual trata el tema, sin embargo el archivo fuente del proyecto está completo y tiene integrado todo lo que se mostrará en esta entrada, la <a href="http://www.codigometropoli.com/sistema-de-clientes-parte-i/" target="_blank">anterior</a> y en las siguientes, para así formar un proyecto completo. Dicho lo anterior, a continuación iniciaré la explicación sobre cómo insertar registros en una base SQLite.</p>
<p><span style="color: #ff0000;"><strong>Parte 2: Insertar registros en SQLite con AIR</strong></span></p>
<p>Recuerda que para mantener organizado el código de nuestro proyecto y para evitar que se pierdan con toda la información aquí mostrada, dividí el código del proyecto en archivos .as. Estos archivos estarán almacenados en la carpeta <em>actionscript</em>. La estructura de nuestro proyecto será la siguiente:</p>
<div align="center">
<div id="attachment_270" class="wp-caption aligncenter" style="width: 255px"><a href="http://www.codigometropoli.com/wp-content/uploads/2008/08/proy1image1.jpg"><img class="size-full wp-image-270" title="proy1image1" src="http://www.codigometropoli.com/wp-content/uploads/2008/08/proy1image1.jpg" alt="Imagen 1" width="245" height="373" /></a><p class="wp-caption-text">Imagen 1</p></div></div>
<p>Todas las interfaces de este proyecto están incluidas en la carpeta <em>componentes</em>. La interfaz para dar de alta un nuevo cliente está en el archivo <em>AltaCliente.mxml</em>. Esta interfaz será la siguiente:</p>
<div align="center"><div id="attachment_270" class="wp-caption aligncenter" style="width: 344px"><a href="http://www.codigometropoli.com/images/screens/proy1image3.jpg"><img class="size-full wp-image-270" title="proy1image1" src="http://www.codigometropoli.com/images/screens/proy1image3.jpg" alt="Imagen 1" width="334" height="274" /></a><p class="wp-caption-text">Imagen 2</p></div></div>
<p>Los IDs de cada uno de estos elementos son:</p>
<ul>
<li> nombre_txt</li>
<li>dirección_txt</li>
<li>telefono_txt</li>
<li>correo_txt</li>
</ul>
<p>El código del archivo <em>AltaCliente.mxml</em> es el siguiente:</p>
<pre class="brush: as3;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;mx:Canvas show=&quot;abreConexion()&quot; xmlns:mx=&quot;http://www.adobe.com/2006/mxml&quot; width=&quot;100%&quot; height=&quot;100%&quot;&gt;
	&lt;mx:Script source=&quot;../actionscript/AltaCliente.as&quot;/&gt;
	&lt;mx:Label y=&quot;16&quot; text=&quot;Alta de Clientes&quot; textAlign=&quot;center&quot; fontWeight=&quot;bold&quot; fontSize=&quot;14&quot; fontFamily=&quot;Verdana&quot; color=&quot;#F64507&quot; width=&quot;212&quot; horizontalCenter=&quot;48&quot;/&gt;
	&lt;mx:TextInput y=&quot;57&quot; width=&quot;212&quot; height=&quot;21&quot; id=&quot;nombre_txt&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; horizontalCenter=&quot;48&quot;/&gt;
	&lt;mx:TextArea y=&quot;88&quot; width=&quot;212&quot; height=&quot;69&quot; id=&quot;direccion_txt&quot; horizontalCenter=&quot;48&quot;/&gt;
	&lt;mx:TextInput y=&quot;168&quot; width=&quot;212&quot; height=&quot;21&quot; id=&quot;telefono_txt&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; horizontalCenter=&quot;48&quot;/&gt;
	&lt;mx:TextInput y=&quot;197&quot; width=&quot;212&quot; height=&quot;21&quot; id=&quot;correo_txt&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; horizontalCenter=&quot;48&quot;/&gt;
	&lt;mx:Label y=&quot;57&quot; text=&quot;Nombre:&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;normal&quot; color=&quot;#000000&quot; width=&quot;101&quot; textAlign=&quot;right&quot; horizontalCenter=&quot;-127&quot;/&gt;
	&lt;mx:Label y=&quot;93&quot; text=&quot;Dirección:&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;normal&quot; color=&quot;#000000&quot; width=&quot;101&quot; textAlign=&quot;right&quot; horizontalCenter=&quot;-127&quot;/&gt;
	&lt;mx:Label y=&quot;168&quot; text=&quot;Teléfono:&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;normal&quot; color=&quot;#000000&quot; width=&quot;101&quot; textAlign=&quot;right&quot; horizontalCenter=&quot;-127&quot;/&gt;
	&lt;mx:Label y=&quot;197&quot; text=&quot;Correo:&quot; fontSize=&quot;12&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;normal&quot; color=&quot;#000000&quot; width=&quot;101&quot; textAlign=&quot;right&quot; horizontalCenter=&quot;-127&quot;/&gt;
	&lt;mx:Button y=&quot;230&quot; label=&quot;Aceptar&quot; width=&quot;100&quot; horizontalCenter=&quot;104&quot; click=&quot;{validaForma();}&quot;/&gt;
	&lt;mx:Label y=&quot;57&quot; text=&quot;(*)&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;bold&quot; color=&quot;#B80808&quot; width=&quot;27&quot; textAlign=&quot;left&quot; id=&quot;msj1&quot; visible=&quot;false&quot; horizontalCenter=&quot;171&quot;/&gt;
	&lt;mx:Label y=&quot;89&quot; text=&quot;(*)&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;bold&quot; color=&quot;#B80808&quot; width=&quot;27&quot; textAlign=&quot;left&quot; id=&quot;msj2&quot; visible=&quot;false&quot; horizontalCenter=&quot;171&quot;/&gt;
	&lt;mx:Label y=&quot;168&quot; text=&quot;(*)&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;bold&quot; color=&quot;#B80808&quot; width=&quot;27&quot; textAlign=&quot;left&quot; id=&quot;msj3&quot; visible=&quot;false&quot; horizontalCenter=&quot;171&quot;/&gt;
	&lt;mx:Label y=&quot;197&quot; text=&quot;(*)&quot; fontSize=&quot;10&quot; fontFamily=&quot;Verdana&quot; fontWeight=&quot;bold&quot; color=&quot;#B80808&quot; width=&quot;27&quot; textAlign=&quot;left&quot; id=&quot;msj4&quot; visible=&quot;false&quot; horizontalCenter=&quot;171&quot;/&gt;
&lt;/mx:Canvas&gt;
</pre>
<p>Observa en el código anterior que el tag principal de este archivo es  <strong>&lt;mx:Canvas&gt;</strong> y no <strong>&lt;mx:WindowedApplication&gt;</strong>, esto es porque todas las interfaces que están dentro del directorio <em>componentes </em>las desplegaremos dentro de la aplicación principal (<em>Sistema_Clientes.mxml</em>); a la propiedad <strong>show </strong>del <strong>Canvas </strong>le estamos especificando que llame a la función  <em>abreConexion()</em> una vez que se haya terminado de mostrar el componente. También observa cómo estamos incluyendo el código de <em>AltaCliente.as</em>:</p>
<pre class="brush: as3;">
&lt;mx:Script source=&quot;../actionscript/AltaCliente.as&quot;/&gt;
</pre>
<p>Otro punto importante a destacar del código anterior es el botón que tiene de etiqueta “Aceptar”, cuando se produce un click en este botón llamaremos a la función <em>validaForma()</em> para asegurarnos que todos los datos requeridos sean llenados.</p>
<pre class="brush: as3;">
&lt;mx:Button y=&quot;230&quot; label=&quot;Aceptar&quot; width=&quot;100&quot; horizontalCenter=&quot;104&quot; click=&quot;{validaForma();}&quot;/&gt;
</pre>
<p>A continuación está la explicación del código del archivo <strong>AltaCliente.as</strong>:</p>
<pre class="brush: as3;">
import flash.data.SQLConnection;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
import mx.controls.Alert; /* Haremos uso de los mensajes de alerta, por lo que de una vez añadimos la clase */

private var conexion:SQLConnection; // Nuestro objeto de la clase SQLConnection
private var database:File; /* Aquí guardaremos la referencia de nuestro archivo .sqlite que es nuestra base de datos */
private var queryStatement:SQLStatement = new SQLStatement(); /* Creamos una variable de tipo SQLStatement en la cual estableceremos los queries y parámetros de nuestras consultas */

public function abreConexion():void {
	nombre_txt.setFocus();
	database = new File(File.applicationStorageDirectory.nativePath + &quot;\database\clientesDB.sqlite&quot;);
	conexion = new SQLConnection();
	conexion.addEventListener(SQLEvent.OPEN, dbAbrirConexion);
	conexion.addEventListener(SQLErrorEvent.ERROR, dbErrorConexion);
	conexion.open(database);
	queryStatement.sqlConnection = conexion;
}
</pre>
<p>Del código anterior, las seis primeras líneas no cambian en nada con respecto al código mostrado en el primer post. Cuando se llame la función <em>abreConexion</em> posicionaremos el cursor dentro del campo de texto nombre_txt, establecemos cuál es el archivo de la base de datos e intentamos abrirla; si existiera algún error es llamada la función dbErrorConexion; en caso contrario, es llamada la función dbErrorConexion.</p>
<p>En esta ocasión, la función <strong>abreConexion</strong> será llamada desde la intefaz que mostré más arriba (desde el archivo <em>AltaCliente.mxml</em>).</p>
<p>Como lo señalé más arriba, una vez que el usuario introduzca los datos y haga click en el botón de Aceptar, la función <em>validaForma()</em> será llamada, el código de esta función te lo presento a continuación:</p>
<pre class="brush: as3;">
private function validaForma():void {
	escondeMensajes();
	if(nombre_txt.text == &quot;&quot;) {
		msj1.visible = true;
		nombre_txt.setFocus();
	}
	else if(direccion_txt.text == &quot;&quot;) {
		msj2.visible = true;
		direccion_txt.setFocus();
	}
	else if(telefono_txt.text == &quot;&quot;) {
		msj3.visible = true;
		telefono_txt.setFocus();
	}
	else if(correo_txt.text == &quot;&quot; || !mail(correo_txt.text)) {
		msj4.visible = true;
		correo_txt.setFocus();
	}
	else
		compruebaCliente();
}
</pre>
<p>Dentro del código de <em>AltaCliente.mxml</em> están unas etiquetas con IDs <em>msj1</em>, <em>msj2</em>, <em>msj3</em>, etc. y cuyo texto es <strong>(*)</strong>; estas etiquetas nos permitirán mostrarle al usuario qué información le faltó por llenar. Como su nombre lo indica, la función <em>escondeMensajes</em> se encarga de &#8220;esconder&#8221; (visible = false) éstos mensajes y así mostrar solamente los que son necesarios.</p>
<p>En este ejemplo, tenemos cuatro sentencias <em>if</em> encargadas de verificar que la información en los campos de texto <em>nombre_txt</em>, <em>dirección_txt</em>, <em>telefono_txt</em> y <em>correo_txt</em> sean distintos de vacío. Además, nos aseguramos que el formato del correo electrónico sea correcto creando la función mail.</p>
<p>Finalmente, si ninguna de las cuatro condicionales <em>if</em> se cumple (es decir, toda la información requerida fue introducida) llamamos a la función <em>compruebaCliente</em> y verificar si el correo electrónico proporcionado ya existe en la base de datos.</p>
<p>A continuación, te muestro el código de las funciones <em>escondeMensajes</em>, <em>mail</em> y <em>compruebaCliente</em>:</p>
<pre class="brush: as3;">
private function escondeMensajes():void {
	msj1.visible = false;
	msj2.visible = false;
	msj3.visible = false;
	msj4.visible = false;
}

private function mail(email:String):Boolean
{
	var res:Boolean = false;
	if(email.indexOf(&quot;@&quot;)&gt;0 &amp;&amp; email.indexOf(&quot;@&quot;) == email.lastIndexOf(&quot;@&quot;))
	{
		if(email.lastIndexOf(&quot;.&quot;)&gt;email.indexOf(&quot;@&quot;) &amp;&amp; email.lastIndexOf(&quot;.&quot;)&lt;email.length-1)
		{
			res = true;
		}
	}
	return res;
}

private function compruebaCliente():void {
	var correo:String = correo_txt.text;

	queryStatement.clearParameters();
	queryStatement.text = &quot;SELECT 1 FROM cliente WHERE email = :correo LIMIT 1&quot;;
	queryStatement.parameters[&quot;:correo&quot;] = correo;

	try {
		query.execute();

		var result:SQLResult = query.getResult();

		if(result.data != null)
			Alert.show(&quot;Esa cuenta de correo ya existe&quot;);
		else
	       	insertaCliente();

	} catch(error:SQLError) {
		Alert.show(&quot;Error: “ + error.toString());
	}
}
</pre>
<p>Observa que dentro de la función <em>compruebaCliente</em> estamos declarando la variable <em>correo</em> y asignándole el valor del cuadro de texto <em>correo_txt</em>. Esta variable la pasaremos como parámetro a la consulta para verificar que esa cuenta de correo electrónico no exista en la base de datos. Con la función <strong>clearParameters</strong> de nuestro objeto <strong>SQLStatement</strong> estamos eliminando los posibles parámetros que hayamos asignado con anterioridad, de no hacer esto el programa generará un error indicándonos que la cantidad de parámetros establecidos en el query no concuerda con los parámetros del <strong>SQLStatement</strong>. A esta variable le indicamos a su propiedad <em>text</em> el <em>query</em> o la consulta que debe realizar. Además, le especificamos (dentro del query) que llevará el parámetro <em>:correo</em> y le asignamos a ese parámetro el valor de la variable <em>correo</em>.<br />
Por último, realizamos la ejecución de la consulta y verificamos si el resultado obtenido es distinto de vacío (nulo – null). Si el resultado es distinto de vacío quiere decir que sí existe un registro con esa cuenta de correo y por lo tanto mostramos un mensaje de alerta informándole al usuario; en caso contrario, llamamos a la función <em>insertaCliente()</em>:</p>
<pre class="brush: as3;">
private function insertaCliente():void {
	var sql:String = &quot;INSERT INTO `cliente` (nombre, direccion, telefono, email)&quot;;
	sql += &quot; VALUES (:nombre, :direccion, :telefono, :email) &quot;;
	queryStatement.clearParameters();
	queryStatement.parameters[&quot;:nombre&quot;] = nombre_txt.text;
	queryStatement.parameters[&quot;:direccion&quot;] = direccion_txt.text;
	queryStatement.parameters[&quot;:telefono&quot;] = telefono_txt.text;
	queryStatement.parameters[&quot;:email&quot;] = correo_txt.text;
	queryStatement.text = sql;

	try {
		queryStatement.execute();
		Alert.show(&quot;Sus datos han sido almacenados&quot;);
		restableceForma();
	}
	catch(error:SQLError){
		trace(&quot;Error: &quot; + error.toString());
	}
}
</pre>
<p>Creamos la variable sql y le asignamos un string con nuestra consulta y los parámetros que recibirá (recuerda que los parámetros son especificados con dos puntos &#8211; : -). Llamamos a la función <strong>clearParameters</strong> y posteriormente le asignamos al <strong>SQLStatement</strong> los valores de los cuatro parámetros (estos valores son obtenidos de nuestros campos de texto).  Ejecutamos la sentencia, le mostramos un mensaje al usuario informándole que sus datos han sido almacenados y por último llamamos a la función <em>restableceForma</em> para borrar la información de los campos de texto.</p>
<pre class="brush: as3;">
private function restableceForma():void {
	nombre_txt.text = &quot;&quot;;
	direccion_txt.text = &quot;&quot;;
	telefono_txt.text = &quot;&quot;;
	correo_txt.text = &quot;&quot;;
}
</pre>
<p>Hemos llegado al final de esta segunda parte. Si te perdiste la primera <a href="http://www.codigometropoli.com/sistema-de-clientes-parte-i/" target="_blank">parte</a> de este tutorial, te recuerdo que…  como recomendación y para que te asegures de que tu base de datos, la tabla y el registro fueron creados, puedes bajar el complemento para Firefox llamado <a href="https://addons.mozilla.org/es-ES/firefox/addon/5817" target="_blank"><strong>SQLite Manager</strong></a>, el cual es un pequeño y simple administrador de bases SQLite.</p>
<div align="center" style="margin-top:0px"><script type="text/javascript"><!--
      google_ad_client = "pub-5808310808246221";
      /* 250x250, Posts */
      google_ad_slot = "8254875600";
      google_ad_width = 250;
      google_ad_height = 250;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></div>
<div style="margin-top:40px; margin-bottom:30px;"><strong>Enlaces recomendados:</strong><br />
<br />
» <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=SQL_01.html" target="_blank">Working with local SQL databases</a><br />
» <a href="http://livedocs.adobe.com/flex/3/langref/index.html" target="_blank">Adobe® Flex® 3 Language Reference</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.codigometropoli.com/sistema-de-clientes-parte-ii/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Sistema de Clientes (AIR y SQLite) Parte I (Crear Base de datos)</title>
		<link>http://www.codigometropoli.com/sistema-de-clientes-parte-i/</link>
		<comments>http://www.codigometropoli.com/sistema-de-clientes-parte-i/#comments</comments>
		<pubDate>Tue, 26 Aug 2008 01:01:32 +0000</pubDate>
		<dc:creator>Carla Macías</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Proyectos]]></category>
		<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[Proyecto]]></category>
		<category><![CDATA[Sistema]]></category>

		<guid isPermaLink="false">http://www.codigometropoli.com/?p=269</guid>
		<description><![CDATA[Esta es la primera parte del proyecto &#8220;Sistema de Clientes&#8221; desarrollado en AIR con SQLite como administrador de base de datos. Para este proyecto usaremos Flex Builder 3, del cual puedes bajarte una versión de prueba del Flex Builder 3 aquí. Si requieres más información sobre qué es AIR y qué puedes hacer con él [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" style="float: right;" src="http://codigometropoli.com/images/air.png" alt="Adobe AIR" width="93" height="93" />Esta es la primera parte del proyecto &#8220;Sistema de Clientes&#8221; desarrollado en AIR con SQLite como administrador de base de datos. Para este proyecto usaremos Flex Builder 3, del cual puedes bajarte una versión de prueba del Flex Builder 3 <a href="https://www.adobe.com/cfusion/tdrc/index.cfm?product=flex" target="_blank">aquí</a>. Si requieres más información sobre qué es AIR y qué puedes hacer con él visita esta entrada. Los archivos de este proyecto los encontrarás al terminar de publicar todas las partes (entradas) de este proyecto.<br />
<span id="more-269"></span><br />
Para este proyecto, abre Flex Builder 3 y crea un nuevo proyecto de AIR (File -&gt; New -&gt; Flex Project. Como nombre de proyecto (Project name) ponle <strong>Sistema_Clientes</strong>; en la sección de <em>Application type</em> selecciona la opción <strong>Desktop application</strong> (runs in Adobe AIR) y haz click en el botón <em>Finish</em>.<br />
Como lo comenté en la sección de <a href="http://www.codigometropoli.com/proyectos/">Proyectos</a>, aquí mostraré solamente la información más importante y sobre la cual trata el tema, sin embargo el archivo fuente del proyecto está completo y tiene integrado todo lo que se mostrará en esta entrada y en las siguientes, para así formar un proyecto completo. Dicho lo anterior, a continuación iniciaré la explicación sobre cómo crear una base de datos en SQLite.</p>
<p><span style="color: #ff0000;"><strong>Parte 1: Crear Base de Datos en SQLite con AIR<br />
</strong></span><br />
Para mantener organizado el código de nuestro proyecto y para evitar que se pierdan con toda la información aquí mostrada, vamos a dividir el código del proyecto en archivos .as. Estos archivos estarán almacenados en la carpeta <em>actionscript</em>. La estructura de nuestro proyecto será la siguiente:</p>
<div align="center"><div id="attachment_270" class="wp-caption aligncenter" style="width: 255px"><a href="http://www.codigometropoli.com/wp-content/uploads/2008/08/proy1image1.jpg"><img class="size-full wp-image-270" title="proy1image1" src="http://www.codigometropoli.com/wp-content/uploads/2008/08/proy1image1.jpg" alt="Imagen 1" width="245" height="373" /></a><p class="wp-caption-text">Imagen 1</p></div></div>
<p>Comenzamos con el archivo <strong>CrearBaseDatos</strong>.as:</p>
<p>Necesitamos de las siguientes librerías para poder tener acceso a los métodos de conexión con la base de datos, la ejecución de los queries, etc. Las clases que usaremos son SQLConnection, SQLErrorEvent y SQL Event:</p>
<pre class="brush: as3;">
import flash.data.SQLConnection;
import flash.events.SQLErrorEvent;
import flash.events.SQLEvent;
import mx.controls.Alert; /* Haremos uso de los mensajes de alerta, por lo que de una vez añadimos la clase */
</pre>
<p>Ahora vamos a crear los objetos de estas clases y las variables que requeriremos a lo largo de este archivo:</p>
<pre class="brush: as3;">
private var conexion:SQLConnection; // Nuestro objeto de la clase SQLConnection
private var database:File; /* Aquí guardaremos la referencia de nuestro archivo .sqlite que es nuestra base de datos */
private var existeBD:Boolean = false; /* Variable booleana en la cual guardaremos el valor de true si existe la base de datos y false en caso contrario */
private var queryStatement:SQLStatement = new SQLStatement(); /* Creamos una variable de tipo SQLStatement en la cual estableceremos los queries y parámetros de nuestras consultas */
</pre>
<p>Para crear las sentencias de SQL, necesitamos de un objeto de la clase <strong>SQLStatement</strong>, a este objeto lo llamamos <em>queryStatement</em>.</p>
<p>La función <strong>abreConexion </strong>(que mostraremos a continuación) será llamada desde la aplicación principal, es decir desde el archivo <em>Sistema_Clientes.mxml</em> (recuerda que al crear un nuevo proyecto, Flex Builder construye automáticamente un archivo MXML con el nombre del proyecto y el cual es el punto de partida de nuestra aplicación). Esta función se encargará de verificar si existe la base de datos la cual la pasamos como parámetro del constructor de la clase <strong>File</strong>.  Si no existiera la base de datos la aplicación se encargará de crearla. En caso contrario, se establecería la conexión con la base de datos.  El nombre de nuestra base de datos será <strong>clientesDB.sqlite</strong>, presta atención a la primera línea de nuestra función:</p>
<pre class="brush: as3;">
private function abreConexion():void {
	/* Asignamos a nuestra variable database el archivo de nuestra base de datos */
	database = new File(File.applicationStorageDirectory.nativePath + &quot;\database\clientesDB.sqlite&quot;);
	/* Inicializamos nuestra variable conexion */
	conexion = new SQLConnection();
	/* Creamos el listener que será llamado cuando se abra la conexión a la base de datos */
	conexion.addEventListener(SQLEvent.OPEN, dbAbrirConexion);
	/* Creamos el listener que será llamado cuando exista algún error en la conexión a la bd */
conexion.addEventListener(SQLErrorEvent.ERROR, dbErrorConexion);
queryStatement.sqlConnection = conexion; /* Le asignamos a su propiedad sqlConnection la variable conexion que creamos al inicio del archivo  */ 

	if(!database.exists) { // Comprobamos si existe o no la base de datos
		existeBD = false; // No existe la bd, por lo tanto le asignamos a existeBD el valor de falso
	    	conexion.open(database); // Abrimos la conexión a la bd
	}
	else {
	    	conexion.open(database); // Abrimos la conexión a la bd
	}
}
</pre>
<p>Observa que al constructor de la clase <strong>File </strong>le estamos pasando como parámetro el URL de donde estará almacenada nuestra base de datos. Para construir este URL estamos usando la propiedad <strong>applicationStorageDirectory</strong>, la cual hace referencia al directorio privado donde se encuentra la aplicación. Además, estamos usando la propiedad <strong>nativePath </strong>la cual nos regresa la ruta completa de acuerdo al sistema operativo donde se encuentra el sistema. A grandes rasgos, esta línea crea un directorio con el nombre de la aplicación (en este caso el directorio se llama <strong>Sistema_Clientes</strong>) dentro de la carpeta de Application Data (Datos de programa). Esta carpeta es donde los programas que tenemos instalados guardan información o las preferencias del usuario de la computadora. En Windows Vista, el directorio donde está almacenada la base de datos es C:\Users\Nombre_Usuario\AppData\Roaming\Sistema_Clientes. En Windows XP, el directorio es: C:\Documents and Settings\Nombre_Usuario\Datos de programa\Sistema_Clientes.</p>
<p>Al hacer la llamada a la función <strong>open</strong>, la función <strong>dbAbrirConexion </strong>será llamada en caso de que no exista error; en caso contrario la función <strong>dbErrorConexion </strong>será llamada. El código de estas funciones se muestra a continuación:</p>
<pre class="brush: as3;">
private function dbAbrirConexion(event:SQLEvent):void {
	if(!existeBD) { /* Si no existe la base de datos, llamamos a la función createTBLCliente */
		createTBLCliente();
	}
}

private function dbErrorConexion():void {
	Alert.show(&quot;No se pudo conectar a la base de datos&quot;); /* Mostramos un mensaje de error*/
}
</pre>
<p>Nuestra base de datos estará conformada por solamente una tabla (sólo para fines del ejercicio, ya que no es común que una base de datos esté formada por sólo una tabla). Nuestra tabla se llama <strong>cliente </strong>y sus elementos son los siguientes:</p>
<div align="center"><div id="attachment_272" class="wp-caption aligncenter" style="width: 390px"><a href="http://www.codigometropoli.com/wp-content/uploads/2008/08/proy1image2.jpg"><img class="size-full wp-image-272" title="proy1image2" src="http://www.codigometropoli.com/wp-content/uploads/2008/08/proy1image2.jpg" alt="Imagen 2" width="380" height="226" /></a><p class="wp-caption-text">Imagen 2</p></div></div>
<p>De la imagen anterior podemos determinar que el query para crear esta tabla es:</p>
<pre class="brush: sql;">
CREATE TABLE `cliente` (`id` INTEGER PRIMARY KEY  NOT NULL, `nombre` TEXT, `direccion` TEXT, `telefono` TEXT, `email` TEXT)
</pre>
<p>Este query lo usaremos en la función <strong>createTBLCliente</strong>, el cual es llamado desde <strong>dbAbrirConexion</strong>.</p>
<pre class="brush: as3;">
private function createTBLCliente():void {
	queryStatement.clearParameters();
	var sql:String = &quot;CREATE TABLE `cliente` &quot;;
	sql += &quot;(`id` INTEGER PRIMARY KEY  NOT NULL, `nombre` TEXT, `direccion` TEXT &quot;;
	sql += &quot;, `telefono` TEXT, `email` TEXT)&quot;;
	queryStatement.text = sql;
	try {
		queryStatement.execute();
		insertDefaultData();
	}
	catch(error:SQLError) {
		Alert.show(&quot;Error al insertar el registro: &quot; + error.toString());
	}
}
</pre>
<p>Para crear las sentencias de SQL, necesitamos de un objeto de la clase <strong>SQLStatement</strong>, a este objeto lo llamamos <em>queryStatement </em>y lo declaramos al inicio del programa. Para asegurarnos de que no tengamos parámetros asignados a este SQLStatement, usamos la función <strong>clearParameters</strong>, de no hacer esto el programa generará un error indicándonos que la cantidad de parámetros establecidos en el query no concuerda con los parámetros del <strong>SQLStatement</strong>. Posteriormente declaramos una variable <em>sql </em>de tipo <em>String</em> que contiene el query de crear la tabla de cliente.<br />
La propiedad <strong>text </strong>de la clase <strong>SQLStatement </strong>nos permite asignarle la sentencia SQL, por lo que le asignamos la variable <em>sql</em>.</p>
<p>Para poder &#8220;cachar&#8221; cualquier error que ocurra al ejecutar la sentencia, colocamos la llamada a la función <strong>execute </strong>dentro del bloque <strong>try</strong>. Cualquier error que ocurra será detectado y administrador en el bloque <strong>catch</strong>. En caso de que no exista ningún error al llamar a la función <strong>execute</strong>, llamaremos a la función <em>insertDefaultData </em>para insertar algunos registros por default.</p>
<p>A continuación pego el código de la función <em>insertDefaultData:</em></p>
<pre class="brush: as3;">
private function insertDefaultData():void {
	queryStatement.clearParameters();
	var sql:String = &quot;INSERT INTO `cliente` (nombre, direccion, telefono, email) VALUES (:nombre, :direccion, :telefono, :email)&quot;;
	queryStatement.parameters[&quot;:nombre&quot;] = 'Ernesto Trujillo';
	queryStatement.parameters[&quot;:direccion&quot;] = 'Avenida Importante #33';
	queryStatement.parameters[&quot;:telefono&quot;] = '55667788';
	queryStatement.parameters[&quot;:email&quot;] = 'etrujillo@email.com';
	queryStatement.text = sql;
	try {
		queryStatement.execute();
	}
	catch(error:SQLError) {
		Alert.show(&quot;Error al crear la tabla cliente: &quot; + error.toString());
	}
}
</pre>
<p>Este código es similar al de la función <em>createTBLCliente </em>en cuanto a la creación de la variable del <strong>SQLStatement</strong>, la creación del query y su asignación a la propiedad <strong>text</strong>. Sin embargo, presta atención en la forma en cómo se le pasan los valores al query; esto es usando dos puntos seguidos de un nombre cualquiera que quieras asignarle. Posteriormente debes establecer el valor de estos parámetros usando la propiedad <strong>parameters </strong>la cual recibe un arreglo asociativo con los valores del parámetro especificado.</p>
<p>Como recomendación y para que te asegures de que tu base de datos, la tabla y el registro fueron creados, puedes bajar el complemento para Firefox llamado <a href="https://addons.mozilla.org/es-ES/firefox/addon/5817" target="_blank"><strong>SQLite Manager</strong></a>, el cual es un pequeño y simple administrador de bases  SQLite.</p>
<div align="center" style="margin-top:0px"><script type="text/javascript"><!--
      google_ad_client = "pub-5808310808246221";
      /* 250x250, Posts */
      google_ad_slot = "8254875600";
      google_ad_width = 250;
      google_ad_height = 250;
// --></script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script></div>
<div style="margin-top:40px; margin-bottom:30px;"><strong>Enlaces recomendados:</strong><br />
<br />
» <a href="http://livedocs.adobe.com/flex/3/html/help.html?content=SQL_01.html" target="_blank">Working with local SQL databases</a><br />
» <a href="http://livedocs.adobe.com/flex/3/langref/index.html" target="_blank">Adobe® Flex® 3 Language Reference</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.codigometropoli.com/sistema-de-clientes-parte-i/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Crear archivo en AIR con Flex Builder 3</title>
		<link>http://www.codigometropoli.com/crear-archivo-en-air-con-flex-builder-3/</link>
		<comments>http://www.codigometropoli.com/crear-archivo-en-air-con-flex-builder-3/#comments</comments>
		<pubDate>Mon, 02 Jun 2008 07:26:52 +0000</pubDate>
		<dc:creator>Carla Macías</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Adobe AIR]]></category>
		<category><![CDATA[crear archivo en AIR]]></category>
		<category><![CDATA[FileStream]]></category>

		<guid isPermaLink="false">http://www.codigometropoli.com/?p=18</guid>
		<description><![CDATA[Adobe AIR permite a los desarrolladores web, crear aplicaciones de escritorio con todo lo que una aplicación web puede proveer. Estas aplicaciones pueden ser ejecutadas en cualquier sistema operativo. Para instalar AIR necesitas tener instalado el Flex Builder 3 (o bien bajarte el SDK de Adobe AIR). En esta entrada aprenderemos a crear un archivo [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright" style="float: right;" src="http://codigometropoli.com/images/air.png" alt="Adobe AIR" width="93" height="93" />Adobe AIR permite a los desarrolladores web, crear aplicaciones de escritorio con todo lo que una aplicación web puede proveer. Estas aplicaciones pueden ser ejecutadas en cualquier sistema operativo. Para instalar AIR necesitas tener instalado el Flex Builder 3 (o bien bajarte el SDK de Adobe AIR). En esta entrada aprenderemos a crear un archivo HTML con Adobe AIR.<span id="more-18"></span>Puedes bajarte una versión de prueba del Flex Builder 3 <a href="https://www.adobe.com/cfusion/tdrc/index.cfm?product=flex" target="_blank">aquí</a>. Además, deberás bajar Adobe AIR de <a href="http://get.adobe.com/air/" target="_blank">aquí</a>. Una vez instalado estas dos aplicaciones inicia Flex Builder y haz click en el menú File -&gt; New -&gt; Flex Project. Te aparecerá una ventana en la cual deberás establecer el nombre del proyecto y el tipo de aplicación. En este caso deberás seleccionar la opción de <em>Desktop application (runs in Adobe AIR)</em>. Como nombre de proyecto le pondremos <em>AIRCreateFile</em>. <em></em></p>
<p style="text-align: center;"><a title="Figura 1: Nuevo proyecto de Adobe AIR en Flex" href="../images/screens/ps5sc1.png" target="_blank"><img style="vertical-align: middle;" src="../images/previews/ps5sc1.png" alt="Figura 1: Nuevo proyecto de Adobe AIR en Flex" width="334" height="300" /></a></p>
<p style="text-align: left;">Después de poner los datos anteriores y de hacer click en el botón de <em>Finish</em>, observarás del lado derecho (Flex Navigator) la lista de archivos y proyectos que tenemos dentro de Flex Builder. El icono rojo al lado del nombre del proyecto inidica que se trata de un proyecto de Adobe AIR. Dentro de la carpeta <em>src</em> (source) se almacenarán los archivos de nuestro proyecto, si observas, el programa Flex ya nos creó nuestro primer archivo (el cual será el punto de arranque de la aplicación) el cual se llama igual que nuestro proyecto.</p>
<p style="text-align: left;">Adobe AIR no sólo nos creo el archivo AIRCreateFile.mxml sino que también nos lo abrió (en la ventana grande de la derecha) y está listo para que empecemos a programar.</p>
<p style="text-align: center;"><a title="Figura 2: Nuestro proyecto de AIR en Flex Builder 3" href="../images/screens/ps5sc2.png" target="_blank"><img style="vertical-align: middle;" src="../images/previews/ps5sc2.png" alt="Figura 2: Nuestro proyecto de AIR en Flex Builder 3" /></a></p>
<p>Como puedes observar en el código, el componente <em>WindowedApplication</em> es el componente padre de nuestra aplicación en AIR. Dentro de estos tags &lt;WindowedApplication&gt; y &lt;/WindowedApplication&gt; debemos escribir todo nuestro código. Comenzaremos haciendo unos cambios al diseño de la aplicación, posteriormente veremos el código necesario para crear el archivo y cargarlo con el componente <em>HTML</em> de Adobe AIR.</p>
<p>Si observas la imagen anterior, arriba del editor de código está el botón de <em>Source</em> (Fuente) y el botón de <em>Design</em> (diseño). Ahorita estamos en la vista del código fuente, por lo tanto el botón de <em>Source</em> está activado. Para realizar los cambios en el diseño de la aplicación lo haremos directamente desde la vista <em>Design</em>, por lo tanto da click en ese botón. Al darle click al botón de diseño, los paneles laterales cambian (En esta vista podemos ver del lado derecho el panel <em>Flex Properties</em> (Propiedades de Flex), el panel <em>States</em> (Estados), <em>Components</em> (Componentes), entre otros. En el panel <em>Style</em>, dentro de la sección <em>Fill</em>, al hacer click en el primer botón (el de una cubeta de pintura) podemos cambiar el color de fondo de la aplicación. Para este ejercicio cambia el botón de fondo a blanco (#FFFFFF).</p>
<p>En el panel <em>Components</em> dentro de la sección de <em>Controls</em>, arrastra al área de diseño el item que dice <em>Label</em>. Da click sobre él y escribe &#8220;Crear archivo HTML en AIR&#8221;; dale el formato que quieras y dentro de la sección <em>Layout</em> del panel de propiedades da click en el botón de enmedio horizontal que está debajo de <em>Constraints</em>. Este botón permite que la etiqueta (Label) que acabamos de poner siempre está centrada horizontalmente cuando se ejecuta la aplicación.</p>
<p style="text-align: center;"><a title="Figura 3: Panel Flex Properties" href="../images/screens/ps5sc4.png" target="_blank"><img style="vertical-align: middle;" src="../images/previews/ps5sc4.png" alt="Figura 3: Panel Flex Properties" width="535" height="423" /></a></p>
<p>En el mismo panel de componentes, se encuentra como penéltima categoría los componentes de Adobe AIR, busca el componente <em>HTML</em> y arrástralo al área de diseño. Selecciona el componente que acabas de arrastrar y pon los siguientes valores en la sección de <em>Layout</em> del panel de propiedades:</p>
<p style="text-align: center;"><a title="Figura 4: Definiendo las propiedades de nuestro componente HTML" href="../images/screens/ps5sc5.png" target="_blank"><img style="vertical-align: middle;" src="../images/previews/ps5sc5.png" alt="Figura 4: Definiendo las propiedades de nuestro componente HTML" width="535" height="423" /></a></p>
<p>Da click en el botón de <em>Source</em> y observa cómo Flex Builder fue creando el código referente a los cambios de layout y diseño del archivo mxml.  Como esta va a ser una pequeña aplicación de ejemplo, vamos a poner todo el código en este archivo; sin embargo, es recomendable para aplicaciones más grandes tener nuestro código organizado en clases y archivos .AS para poder reutilizarlos y para poder actualizarlos fácilmente cuando se requieran cambios. Agrega estos elementos a los siguientes tags:</p>
<pre class="brush: as3;">
/* Una vez que se haya creado la ventana de la aplicación, se mandará a llamar la función init(); */
&lt;mx:WindowedApplication creationComplete=&quot;init();&quot;
/* Le estamos asignando el id de HTMLLoader al componente HTML */
&lt;mx:HTML id=&quot;HTMLLoader&quot;
</pre>
<p>Dentro de los tags &lt;WindowedApplication&gt; introduce esta línea de código y presiona la tecla Enter:</p>
<pre class="brush: as3;">
&lt;mx:Script&gt;
</pre>
<p>Verás que Flex Builder te completará el código cerrando el tag:</p>
<p style="text-align: center;"><a title="Figura 6: Estableciendo los tags de Script para poner nuestro código ActionScript" href="../images/screens/ps5sc3.png" target="_blank"><img style="vertical-align: middle;" src="../images/previews/ps5sc3.png" alt="Figura 6: Estableciendo los tags de Script para poner nuestro código ActionScript" width="334" height="300" /></a></p>
<p>Dentro del CDATA de nuestro tag <em>Script</em> deberá ir todo nuestro código ActionScript que necesitemos. Para poder crear un archivo desde AIR necesitamos importar la librería File:</p>
<pre class="brush: as3;">
// Importar las siguientes librerías:
import flash.filesystem.File;
import flash.html.HTMLLoader; // Esta librería la usaremos más adelante para mostrar en nuestra aplicación el archivo HTML que generamos
</pre>
<p>Además, crearemos estas variables que usaremos más adelante:</p>
<pre class="brush: as3;">
private var _encodeType:String = &quot;iso-8859-1&quot;; /* Tipo de codificación para que nos permita acentos en el archivo */
private var stream:FileStream = new FileStream(); /* Estamos declarando una variable de tipo FileStream para poder crear y escribir en el archivo */
</pre>
<p>Debajo del código anterior escribe las siguientes funciones:</p>
<pre class="brush: as3;">
/* Esta es la primera función que mandamos a llamar en creationComplete */
public function init() {
     this.maximize(); /* Cuando ejecutamos la aplicación la ventana estará maximizada */
     var htmlFile:File = new File(File.applicationStorageDirectory.nativePath + &quot;/miArchivo.html&quot;); /* Una referencia al archivo HTML que vamos a crear, en ese caso nuestro archivo se llamará miArchivo.html */
     if(stream != null) { /* Si ya existe un stream abierto hay que cerrarlo */
          stream.close();
     }
     stream = new FileStream();
     stream.open(htmlFile, FileMode.WRITE); /* Abrimos el archivo en modo de escritura */
     stream.addEventListener(IOErrorEvent.IO_ERROR, writeIOErrorHandler); /* Asignamos un listener al stream para ver si hubo error de lectura o escritura de archivo */

     stream.writeMultiByte(getFirstTags(), _encodeType); /* Escribimos en nuestro archivo el texto (que en nuestro caso es el código HTML de nuestro ejemplo) que nos regresa la función getFirstTags() declarada más adelante, con codificación ISO para los acentos */
     stream.writeMultiByte(getDataTable(), _encodeType); /* Escribimos en nuestro archivo el texto que nos regresa la función getDataTable */
     stream.writeMultiByte(getEndTags(), _encodeType);  /* Escribimos en nuestro archivo el texto que nos regresa la función getEndTags*/

     stream.close(); /* Cerramos nuestro stream */

     HTMLLoader.location = File.applicationStorageDirectory.nativePath + &quot;/miArchivo.html&quot;; /* Mostramos en el componente HTML el archivo que acabamos de crear */
}
public function getFirstTags():String {
     var _texto:String = '&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;\n' +
				'&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;\n' +
				'&lt;head&gt;\n' +
				'&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-2&quot; /&gt;\n' +
				'&lt;title&gt;Crear archivo HTML en Adobe AIR&lt;/title&gt;\n' +
				'&lt;style&gt;\n' +
				'body {\n' +
				'	font:Arial, Helvetica, sans-serif;\n' +
				'	font-family:Arial, Helvetica, sans-serif;\n' +
				'	font-size:12px;\n' +
				'	margin-left:30px;\n' +
				'}\n' +
				'hr.Ruler {\n' +
				'	margin-left:-20px !important;\n' +
				'	color:#003366;\n' +
				'	border:1px solid #003366;\n' +
				'	background-color:#003366;\n' +
				'	width:800px;\n' +
				'}\n' +
				'.Estilo3 {\n' +
				'	color: #993300;\n' +
				'	font-weight: bold;\n' +
				'	font-size: 14px;\n' +
				'}\n' +
				'.Estilo4 {font-size: 12px; color: #666666;}\n' +
				'a:hover, a:link, a:visited, a:active {font-size: 12px; color: #666666; text-decoration:none; }\n' +
				'.Tabla_Datos td {\n' +
				'	height:25px;\n' +
				'}\n' +
				'&lt;/style&gt;\n' +
				'&lt;/head&gt;\n' +
				'&lt;body&gt;\n';
				return _texto;
}

private function getEndTags():String {
     var _texto:String = '&lt;/body&gt;&lt;/html&gt;';
     return _texto;
}

private function writeIOErrorHandler(event:Event):void {
     trace(&quot;Error al abrir o escribir el archivo&quot;);
}
</pre>
<p>¿Te perdiste? No te preocupes, aquí va el código completo:</p>
<pre class="brush: as3;">
&lt;![CDATA[
	import flash.filesystem.File;
	import flash.html.HTMLLoader;

	private var _encodeType:String = &quot;iso-8859-1&quot;;
	private var stream:FileStream = new FileStream();

	public function init() {
		this.maximize();

		var htmlFile:File = new File(File.applicationStorageDirectory.nativePath + &quot;/miArchivo.html&quot;);
		if(stream != null) {
			stream.close();
		}
		stream = new FileStream();
		stream.open(htmlFile, FileMode.WRITE);
		stream.addEventListener(IOErrorEvent.IO_ERROR, writeIOErrorHandler);

		stream.writeMultiByte(getFirstTags(), _encodeType);
		stream.writeMultiByte(getDataTable(), _encodeType);
		stream.writeMultiByte(getEndTags(), _encodeType);	

		stream.close();

		HTMLLoader.location = File.applicationStorageDirectory.nativePath + &quot;/miArchivo.html&quot;;
	}

	public function getFirstTags():String {
		var _texto:String = '&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;\n' +
		'&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;\n' +
		'&lt;head&gt;\n' +
		'&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=iso-8859-2&quot; /&gt;\n' +
		'&lt;title&gt;Crear archivo HTML en Adobe AIR&lt;/title&gt;\n' +
		'&lt;style&gt;\n' +
		'body {\n' +
		'	font:Arial, Helvetica, sans-serif;\n' +
		'	font-family:Arial, Helvetica, sans-serif;\n' +
		'	font-size:12px;\n' +
		'	margin-left:30px;\n' +
		'}\n' +
		'hr.Ruler {\n' +
		'	margin-left:-20px !important;\n' +
		'	color:#003366;\n' +
		'	border:1px solid #003366;\n' +
		'	background-color:#003366;\n' +
		'	width:800px;\n' +
		'}\n' +
		'.Estilo3 {\n' +
		'	color: #993300;\n' +
		'	font-weight: bold;\n' +
		'	font-size: 14px;\n' +
		'}\n' +
		'.Estilo4 {font-size: 12px; color: #666666;}\n' +
		'a:hover, a:link, a:visited, a:active {font-size: 12px; color: #666666; text-decoration:none; }\n' +
		'.Tabla_Datos td {\n' +
		'	height:25px;\n' +
		'}\n' +
		'&lt;/style&gt;\n' +
		'&lt;/head&gt;\n' +
		'&lt;body&gt;\n';
		return _texto;
	}

	private function getDataTable():String {
		var _texto:String = '&lt;br /&gt;\n' +
		'&lt;span class=&quot;Estilo3&quot;&gt;Archivo HTML en Adober AIR&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span class=&quot;Estilo4&quot;&gt;&lt;a href=&quot;http://codigometropoli.com&quot;&gt;(http://codigometropoli.com)&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;\n' +
		'&lt;br /&gt;\n' +
		'&lt;table class=&quot;Tabla_Datos&quot; width=&quot;700&quot; border=&quot;0&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;\n' +
		'  &lt;tr&gt;\n' +
		'    &lt;td width=&quot;138&quot;&gt;&lt;strong&gt;Nombre:&lt;/strong&gt;&lt;/td&gt;\n' +
		'    &lt;td width=&quot;237&quot;&gt;Juan Carlos&lt;/td&gt;\n' +
		'    &lt;td width=&quot;169&quot;&gt;&lt;strong&gt;Fecha de Nacimiento:&lt;/strong&gt;&lt;/td&gt;\n' +
		'    &lt;td width=&quot;156&quot;&gt;20/03/1981&lt;/td&gt;\n' +
		'  &lt;/tr&gt;\n' +
		'  &lt;tr&gt;\n' +
		'    &lt;td&gt;&lt;strong&gt;Pa&amp;iacute;s:&lt;/strong&gt;&lt;/td&gt;\n' +
		'    &lt;td&gt;M&amp;eacute;xico&lt;/td&gt;\n' +
		'    &lt;td&gt;&lt;strong&gt;Ciudad:&lt;/strong&gt;&lt;/td&gt;\n' +
		'    &lt;td&gt;Distrito Federal&lt;/td&gt;\n' +
		'  &lt;/tr&gt;\n' +
		'  &lt;tr&gt;\n' +
		'    &lt;td&gt;&lt;strong&gt;N&amp;uacute;mero de Cliente: &lt;/strong&gt;&lt;/td&gt;\n' +
		'    &lt;td&gt;541232&lt;/td&gt;\n' +
		'    &lt;td&gt;&amp;nbsp;&lt;/td&gt;\n' +
		'    &lt;td&gt;&amp;nbsp;&lt;/td&gt;\n' +
		'  &lt;/tr&gt;\n' +
		'&lt;/table&gt;\n' +
		'&lt;hr class=&quot;Ruler&quot; /&gt;';
		return _texto;
	}

	private function getEndTags():String {
		var _texto:String = '&lt;/body&gt;&lt;/html&gt;';
		return _texto;
	}

	private function writeIOErrorHandler(event:Event):void
	{
		trace(&quot;Error al abrir o escribir el archivo&quot;);
	}
]]&gt;
</pre>
<p>El resultado final se muestra en la siguiente imagen:</p>
<p style="text-align: center;"><a title="Figura 7: Nuestra aplicación de Adobe AIR en acción" href="../images/screens/ps5sc6.png" target="_blank"><img style="vertical-align: middle;" src="../images/previews/ps5sc6.png" alt="Figura 7: Nuestra aplicación de Adobe AIR en acción" width="334" height="300" /></a></p>
<div style="margin-top:0px; margin-bottom:20px;" align="center">
<table border="0" cellspacing="0" cellpadding="0" width="180">
<tbody>
<tr>
<td valign="top"><a href="http://www.megaupload.com/?d=RXYN7VI1" target="_blank"><img src="../images/descargar.png" alt="Descargar Archivo" /></a></td>
</tr>
</tbody>
</table>
</div>
<div style="margin-top:0px;" align="center">
<script type="text/javascript"><!--
      google_ad_client = "pub-5808310808246221";
      /* 250x250, Posts */
      google_ad_slot = "8254875600";
      google_ad_width = 250;
      google_ad_height = 250;
     //-->
</script><br />
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>
</div>
<div style="margin-top:30px; margin-bottom:30px;">
<p><strong>Enlaces recomendados:</strong></p>
<p>» <a href="http://www.adobe.com/devnet/air/flex/quickstart/building_text_editor.html" target="_blank">Building a text-file editor</a><br />
» <a href="http://livedocs.adobe.com/flex/3/langref/index.html" target="_blank">Adobe® Flex® 3 Language Reference</a>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.codigometropoli.com/crear-archivo-en-air-con-flex-builder-3/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

