Sistema de Clientes (AIR y SQLite) Parte III (Modificar y Eliminar Registros)

Adobe AIREsta es la tercera parte del proyecto "Sistema de Clientes" 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 esto mostraremos dentro de un DataGrid todos los registros que tenemos en nuestra base de datos; en este DataGrid usaremos itemRenderer(s) para llenar con botones dos columnas, uno de los botones será para editar el registro seleccionado y el otro para eliminarlo.

Parte 3: Modificar y eliminar registros en SQLite con AIR

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:

Imagen 1: Estructura de la aplicación

Imagen 1: Estructura de la aplicación

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 EditarBorrarCliente.mxml. Esta interfaz funciona de la siguiente manera:

Imagen 2: Interfaz del usuario

Imagen 2: Interfaz del usuario

Al seleccionar la opción "Editar/Eliminar…" 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 Modificar del primer registro, se mostrará lo siguiente:

Imagen 3: Opción Modificar Cliente

Imagen 3: Opción Modificar Cliente

…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 Eliminar del primer registro, se mostrará un mensaje de alerta pidiéndole que confirme si desea o no borrar el registro.

Imagen 4: Mensaje de confirmación

Imagen 4: Mensaje de confirmación

Explicado lo anterior, comenzaremos mostrando la estructura y el código del archivo EditarBorrarCliente.mxml:

El código de este archivo es el siguiente:

Actionscript:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Canvas show="abreConexion();" xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" backgroundColor="#FFFFFF">
  3.     <mx:Script source="../actionscript/EditarBorrarCliente.as"/>
  4.     <mx:Label y="13" text="Lista de Clientes" right="75" left="55" textAlign="center" fontWeight="bold" fontSize="14" fontFamily="Verdana" color="#F64507"/>
  5.     <mx:DataGrid y="57" width="600" height="223" horizontalCenter="-14" id="clientes_dg">
  6.         <mx:columns>
  7.             <mx:DataGridColumn width="150" textAlign="left" headerText="Nombre" dataField="nombre"/>
  8.             <mx:DataGridColumn width="120" textAlign="left" headerText="Teléfono" dataField="telefono"/>
  9.             <mx:DataGridColumn width="165" textAlign="left" headerText="Correo" dataField="correo"/>
  10.             <mx:DataGridColumn sortable="false" width="85" textAlign="center" headerText="Modificar" dataField="modificar">
  11.                 <mx:itemRenderer>
  12.                 <mx:Component>
  13.                     <mx:HBox horizontalAlign="center">
  14.                         <mx:Button id="editarBtn" click="outerDocument.editarCliente(data.id_cliente, data.nombre, data.direccion, data.telefono, data.correo)" label="" height="20" width="30" icon="@Embed(source='../images/edit.png')"/>
  15.                     </mx:HBox>
  16.                 </mx:Component>
  17.                 </mx:itemRenderer>
  18.             </mx:DataGridColumn>
  19.             <mx:DataGridColumn sortable="false" width="80" textAlign="center" headerText="Eliminar" dataField="eliminar">
  20.                 <mx:itemRenderer>
  21.                 <mx:Component>
  22.                     <mx:HBox horizontalAlign="center">
  23.                         <mx:Button id="borrarBtn" click="outerDocument.borrarCliente(data.id_cliente)" label="" height="20" width="30" icon="@Embed(source='../images/remove.png')"/>
  24.                     </mx:HBox>
  25.                 </mx:Component>
  26.                 </mx:itemRenderer>
  27.             </mx:DataGridColumn>
  28.         </mx:columns>
  29.     </mx:DataGrid> 
  30.     <mx:Canvas id="Modificar_Cliente" visible="true" y="324" width="378" height="255" horizontalCenter="-15" borderColor="#ADADAD" backgroundAlpha="0.0" borderStyle="solid">
  31.         <mx:Button id="guardarBtn" click="validaForma();" y="221" label="Cambiar" width="100" x="220"/>
  32.         <mx:Label y="10" text="Modificar Cliente:" textAlign="left" fontWeight="bold" fontSize="11" fontFamily="Verdana" color="#31384B" width="213" x="10" textDecoration="underline"/>
  33.         <mx:Button id="cerrarBtn" y="1" label="X" width="32" x="343.3" click="Modificar_Cliente.visible = false; reseteaForma();" cornerRadius="0"/>
  34.         <mx:Text visible="false" x="10" y="86" text="Por favor introduzca la divisa" fontWeight="bold" color="#B80808" fontFamily="Verdana" fontSize="10" width="184" height="33" id="msj_nombre"/>
  35.         <mx:TextInput y="50" width="212" height="21" id="nombre_txt" fontSize="10" fontFamily="Verdana" x="108"/>
  36.         <mx:TextArea y="81" width="212" height="69" id="direccion_txt" x="108"/>
  37.         <mx:TextInput y="161" width="212" height="21" id="telefono_txt" fontSize="10" fontFamily="Verdana" x="108"/>
  38.         <mx:TextInput y="190" width="212" height="21" id="correo_txt" fontSize="10" fontFamily="Verdana" x="108"/>
  39.         <mx:Label y="50" text="Nombre:" fontSize="12" fontFamily="Verdana" fontWeight="normal" color="#000000" width="80" textAlign="right" x="10"/>
  40.         <mx:Label y="86" text="Dirección:" fontSize="12" fontFamily="Verdana" fontWeight="normal" color="#000000" width="80" textAlign="right" x="10"/>
  41.         <mx:Label y="161" text="Teléfono:" fontSize="12" fontFamily="Verdana" fontWeight="normal" color="#000000" width="80" textAlign="right" x="10"/>
  42.         <mx:Label y="190" text="Correo:" fontSize="12" fontFamily="Verdana" fontWeight="normal" color="#000000" width="80" textAlign="right" x="10"/>
  43.         <mx:Label y="50" text="(*)" fontSize="10" fontFamily="Verdana" fontWeight="bold" color="#B80808" width="27" textAlign="left" id="msj1" visible="false" horizontalCenter="153"/>
  44.         <mx:Label y="82" text="(*)" fontSize="10" fontFamily="Verdana" fontWeight="bold" color="#B80808" width="27" textAlign="left" id="msj2" visible="false" horizontalCenter="153"/>
  45.         <mx:Label y="161" text="(*)" fontSize="10" fontFamily="Verdana" fontWeight="bold" color="#B80808" width="27" textAlign="left" id="msj3" visible="false" horizontalCenter="153"/>
  46.         <mx:Label y="190" text="(*)" fontSize="10" fontFamily="Verdana" fontWeight="bold" color="#B80808" width="27" textAlign="left" id="msj4" visible="false" horizontalCenter="153"/>
  47.     </mx:Canvas>
  48. </mx:Canvas>

Observa en el código anterior que el tag principal de este archivo es <mx:Canvas> y no <mx:WindowedApplication>, esto es porque todas las interfaces que están dentro del directorio componentes las desplegaremos dentro de la aplicación principal (Sistema_Clientes.mxml); a la propiedad show del Canvas le estamos especificando que llame a la función abreConexion() una vez que se haya terminado de mostrar el componente. También observa cómo estamos incluyendo el código de EditarBorrarCliente.as:

Actionscript:
  1. <mx:Script source="../actionscript/EditarBorrarCliente.as"/>

También presta atención en la forma en que estamos creando los renderers para las columnas.

Actionscript:
  1. <mx:DataGridColumn sortable="false" width="85" textAlign="center" headerText="Modificar" dataField="modificar">
  2. <mx:itemRenderer>
  3.         <mx:Component>
  4.             <mx:HBox horizontalAlign="center">
  5.             <mx:Button id="editarBtn" click="outerDocument.editarCliente(data.id_cliente, data.nombre, data.direccion, data.telefono, data.correo)" label="" height="20" width="30" icon="@Embed(source='../images/edit.png')"/>
  6.             </mx:HBox>
  7.         </mx:Component>
  8.     </mx:itemRenderer>
  9. </mx:DataGridColumn>

Dentro de los tags <mx:itemRenderer> y </mx:itemRenderer> estamos usando como layout el HBox (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 click sobre él llamará a la función editarCliente, 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 outerDocument 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 () que está dentro de nuestra carpeta images. 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.

El código para la columna que llevará los botones de Eliminar es el siguiente:

Actionscript:
  1. <mx:DataGridColumn sortable="false" width="80" textAlign="center" headerText="Eliminar" dataField="eliminar">
  2.     <mx:itemRenderer>
  3.     <mx:Component>
  4.         <mx:HBox horizontalAlign="center">
  5.             <mx:Button id="borrarBtn" click="outerDocument.borrarCliente(data.id_cliente)" label="" height="20" width="30" icon="@Embed(source='../images/remove.png')"/>
  6.         </mx:HBox>
  7.     </mx:Component>
  8.     </mx:itemRenderer>
  9. </mx:DataGridColumn>

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 borrarCliente, pasándole como parámetro el ID del cliente. Además, el icono para este botón es remove.png ().

Antes de ver el código de las funciones editarCliente y borrarCliente, 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 EditarBorrarCliente.as.

Primero, importamos las clases y declaramos las variables que necesitamos. En el arreglo data_provider almacenaremos los datos obtenidos de nuestra consulta y lo asignaremos como dataProvider de nuestro DataGrid (clientes_dg). La variable id_selected nos servirá para almacenar el ID del registro seleccionado y posteriormente eliminarlo de la base de datos.

Actionscript:
  1. // ActionScript file
  2.  
  3.     import flash.data.SQLConnection;
  4.     import flash.events.SQLErrorEvent;
  5.     import flash.events.SQLEvent;
  6.    
  7.     import mx.controls.Alert;
  8.     import mx.events.CloseEvent;
  9.     import mx.events.ListEvent;
  10.    
  11.     private var conexion:SQLConnection;
  12.     private var database:File;
  13.     private var queryStatement:SQLStatement = new SQLStatement();   
  14.     [Bindable]
  15.     private var data_provider:Array;
  16.     private var id_selected:Number = 0;

La primera función que es llamada en esta sección es abrirConexion:

Actionscript:
  1. public function abreConexion():void {
  2.     reseteaForma();
  3.     Modificar_Cliente.visible = false;
  4.     reiniciaVariables();
  5.     clientes_dg.addEventListener(ListEvent.CHANGE, dgChangeHandler);
  6.        
  7.     database = new File(File.applicationStorageDirectory.nativePath + "\database\clientesDB.sqlite");
  8.     conexion = new SQLConnection();
  9.     conexion.addEventListener(SQLEvent.OPEN, dbAbrirConexion);
  10.     conexion.addEventListener(SQLErrorEvent.ERROR, dbErrorConexion);
  11.     queryStatement.sqlConnection = conexion;                 
  12.     conexion.open(database);        
  13. }

Dentro de abreConexion llamamos a la función reseteaForma, la cual se encarga de borrar los datos de la forma para la modificación de los datos.

Actionscript:
  1. private function reseteaForma():void {
  2.     nombre_txt.text = "";
  3.     direccion_txt.text = "";
  4.     telefono_txt.text = "";
  5.     correo_txt.text = "";
  6.     escondeMensajes();
  7. }

Después de llamar a la función reseteaForma, ocultamos el canvas Modificar_Cliente y llamamos a la función reiniciaVariables, la cual se encargará de resetear los arreglos para eliminar su contenido previo.

Actionscript:
  1. private function reiniciaVariables():void {
  2.     clientes_dg.dataProvider = new Array()// Reiniciamos el arreglo para eliminar su contenido
  3.     data_provider = new Array(); // Reiniciamos el arreglo para eliminar su contenido   
  4. }

Posteriormente le asignamos al datagrid clientes_dg el listener del evento CHANGE. 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 Modificar_Cliente (es posible que previamente el usuario le haya dado click al botón de Editar en alguno de los registros, es por eso que nos aseguramos de esconder el Canvas). Además, almacenamos en la vaiable id_selected el ID 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 Editar, no se le muestren.

Actionscript:
  1. private function dgChangeHandler(event:ListEvent):void {
  2. escondeMensajes();
  3.     Modificar_Cliente.visible = false;
  4.     id_selected = event.target.selectedItem.id_cliente
  5. }

El resto del código de la función abreConexion ya lo conoces de las entradas anteriores.
Si no hubo ningún problema en la conexión a la base de datos, llamamos a la función getClientes para llenar el DataGrid con nuestros registros:

Actionscript:
  1. private function dbAbrirConexion(event:SQLEvent):void {
  2.     getClientes();
  3. }
  4.  
  5. private function getClientes():void {      
  6.     queryStatement.clearParameters();
  7.     queryStatement.text = "SELECT * FROM cliente ORDER BY nombre asc";
  8.        
  9.     try {
  10.         queryStatement.execute();
  11.        
  12.         var result:SQLResult = queryStatement.getResult();
  13.         if(result.data != null) {
  14.             var numResults:int = result.data.length;
  15.         
  16.             for (var i:int = 0; i <numResults; i++)
  17.             {
  18.                 var row:Object = result.data[i];
  19.                     
  20.             data_provider.push({nombre:row.nombre, id_cliente:row.id, direccion:row.direccion, correo:row.email, telefono:row.telefono});
  21.             }
  22.                 
  23.             clientes_dg.dataProvider = data_provider;
  24.         }
  25.     }
  26.     catch(error:SQLError) {
  27.         trace("Error: " + error.toString());
  28.     }      
  29. }

Dentro del código de getClientes haremos la consulta a la tabla cliente para obtener todos los registros de nuestra base. Nuestro query es muy sencillo, en él estamos seleccionando (SELECT) todas las columnas (*) de la tabla cliente y le estamos diciendo que lo ordene (ORDER BY) de forma ascendente (asc) de acuerdo a la columna nombre.

SQL:
  1. SELECT * FROM cliente ORDER BY nombre ASC

Una vez que ejecutamos la consulta (queryStatement.execute()) obtenemos el resultado con la función getResult. Comprobamos que el resultado no sea vacío (result.data!= null) y obtenemos el total de registros obtenidos por medio de la propiedad length. Como ya sabemos cuántos registros nos regresó la consulta, haremos un ciclo for para almacenar los registros en nuestro arreglo data_provider. Finalmente estamos asignando el arreglo data_provider a la propiedad dataProvider 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 Componente DataGrid que publiqué anteriormente.

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: editarCliente y borrarCliente.
Como lo mencioné anteriormente, cuando el usuario hace click en el botón de Editar de alguno de los registros, la función editarCliente es llamada:

Actionscript:
  1. public function editarCliente(id_cliente:Number, nombre:String, direccion:String, telefono:String, correo:String):void {
  2.     id_selected = id_cliente;
  3.     nombre_txt.text = nombre;
  4.     direccion_txt.text = direccion;
  5.     telefono_txt.text = telefono;
  6.     correo_txt.text = correo;
  7.     Modificar_Cliente.visible = true;
  8. }

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 Modificar_Cliente. Si el usuario hace click en el botón de Cambiar, la función es validaForma es ejecutada:

Actionscript:
  1. private function validaForma():void {
  2.     escondeMensajes();
  3.     if(nombre_txt.text == "") {
  4.         msj1.visible = true;
  5.         nombre_txt.setFocus();
  6.     }
  7.     else if(direccion_txt.text == "") {
  8.         msj2.visible = true;
  9.         direccion_txt.setFocus();
  10.     }
  11.     else if(telefono_txt.text == "") {
  12.         msj3.visible = true;
  13.         telefono_txt.setFocus();
  14.     }
  15.     else if(correo_txt.text == "" || !mail(correo_txt.text)) {
  16.         msj4.visible = true;
  17.         correo_txt.setFocus();
  18.     }
  19.     else {
  20.         updateCliente(id_selected);
  21.     }
  22. }

Esta función es similar a la que usamos en la entrada anterior, simplemente estamos verificando que todos los datos fueron llenados y, en caso positivo, llamamos a la función updateCliente.

Actionscript:
  1. private function updateCliente(idCliente:Number):void {
  2.     queryStatement.clearParameters();
  3.     var sql:String = "UPDATE `cliente` SET nombre = :nombre, direccion = :direccion, telefono = :telefono, email = :correo WHERE id = :idCliente";
  4.     queryStatement.parameters[":nombre"] = nombre_txt.text;
  5.     queryStatement.parameters[":direccion"] = direccion_txt.text;
  6.     queryStatement.parameters[":telefono"] = telefono_txt.text;
  7.     queryStatement.parameters[":correo"] = correo_txt.text;
  8.     queryStatement.parameters[":idCliente"] = idCliente;
  9.     queryStatement.text = sql;
  10.    
  11.     try {
  12.         queryStatement.execute();         
  13.         abreConexion();
  14.     }
  15.     catch(error:SQLError){
  16.         trace("Error: " + error.toString());
  17.     }
  18. }

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 abreConexion para que muestre todos los registros (incluyendo los nuevos) en el DataGrid.

La función borrarCliente es llamada cuando el usuario hace click en el botón de Eliminar:

Actionscript:
  1. public function borrarCliente(id_cliente:Number):void {
  2.     id_selected = id_cliente;
  3.     Alert.yesLabel = "Sí";
  4.     Alert.noLabel = "No";
  5. Alert.show("¿Desea eliminar este cliente?", "Importante", 3, this, alertClickHandler);
  6. }

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 show le pasamos como parámetro el manejador de eventos que debe considerar (alertClickHandler). 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 delCliente pasándole como parámetro el ID del registro seleccionado.

Actionscript:
  1. private function alertClickHandler(event:CloseEvent):void {
  2. if (event.detail == Alert.YES)
  3.         delCliente(id_selected);
  4. }

La función delCliente 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 abreConexion para mostrar todos los registros restantes de la base de datos en el DataGrid.

Actionscript:
  1. private function delCliente(id_cliente:Number):void {
  2.     queryStatement.clearParameters();
  3.     queryStatement.text = "DELETE FROM cliente WHERE id = :id_cliente";
  4.     queryStatement.parameters[":id_cliente"] = id_cliente;
  5.    
  6.     try {
  7.         queryStatement.execute();         
  8.         abreConexion()
  9.     }
  10.     catch(error:SQLError) {
  11.         trace("Error: " + error.toString());
  12.     }
  13. }

Hemos llegado al final de esta tercera parte; ya nada más nos queda pendiente la cuarta y última entrega.


Enlaces recomendados:

» Working with local SQL databases
» Adobe® Flex® 3 Language Reference

Tags: , , , ,

Si te gustó esta entrada anímate a escribir un comentario o suscribirte al feed y obtener los artículos futuros en tu lector de feeds.

Comentarios

[...] "Sistema de Clientes" 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 [...]

Los datos almacenados en l abase de datos, donde se encuentran, o sea, en que archivo (si lo crea) lo guarda en la Pc. Desde muy amabla.

Hola Claudio,

En la primera parte de este tutorial escribí:
"... A grandes rasgos, esta línea crea un directorio con el nombre de la aplicación (en este caso el directorio se llama Sistema_Clientes) 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."

Saludos.

Escribe un comentario

Nota: Es posible que tu comentario requiera autorización, si es así tu comentario será publicado a la brevedad. Gracias.

(requerido)

(requerido)