Mostrando entradas con la etiqueta MVC. Mostrar todas las entradas
Mostrando entradas con la etiqueta MVC. Mostrar todas las entradas

miércoles, 7 de octubre de 2015

Resaltar uno o varias filas según valor (jqGrid)


En este artículo quiero tratar el tema sobre cómo cambiar el color de una fila o varias de ellas en un jqGrid según el valor que tenga en algún campo en específico.
Supón que, en tu sitio tienes un jqGrid en el que muestras todos tus usuarios con los distintos campos que tienen en la base de datos nombre, apellidos, sexo, etc, y uno de estos es el estado del usuario Activo o Inactivo y quieres que los inactivos resalten sus filas de un color o con algún estilo en específico.
La solución que a continuación te muestro se hace completamente a nivel de vista en el modelo MVC (Modelo Vista Controlador), es decir se ejecuta en lenguaje del lado del de cliente, en este caso jquery.

Para hacer lo antes comentado se crea un arreglo.
var rowsToColor = [];

Después en la columna que se desea evaluar el valor se le añade la propiedad formatter seguido del nombre de la función que tendremos comprobando la condición necesaria para aplicar el estilo deseado a la fila.
{name:'ENABLE', index:'ENABLE', width:90, align:’left’, formatter: rowcolor},

Si tienes en el campo alguna función ya declarada en el formatter puedes incluir el código en tu función o declarar otra vez dicha columna y ponerle la propiedad hidden a true, para que no se muestre. En este caso el nombre de la función es rowcolor y debajo un ejemplo de cómo luciría.
function rowcolor(cellValue, options, rowObject) {
        if (cellValue == 0)
            rowsToColor[rowsToColor.length] = options.rowId;
        return cellValue;
}

En este caso evalúa el valor que viene en cellValue que no es más que el valor de la celda en cuestión y si es igual a 0, es decir, el usuario que está verificando esta desactivado guarda en la última posición del arreglo que declaramos el id de la fila para utilizarlo cuando el jqGrid esté completamente cargado, para ello se utiliza la propiedad loadComplete del componente.
loadComplete: function() {                       
                        for (var i = 0; i < rowsToColor.length; i++) {
                                $("#" + rowsToColor[i]).find("td").css("background-color", "#FF7F7F");
                                $("#" + rowsToColor[i]).find("td").css("color", "black");
                             }
                    }

En esta función se pueden hacer todas las demás cosas que se necesiten hacer cuando esté completamente cargado el jqGrid.
Este ciclo lo que hace es recorrer la variable que se declaró en un principio como arreglo y luego según la condición se fueron guardando los id de los <tr> entonces se selecciona el componente con ese id ya que jQuey cuando crea la tabla (jqGrid) le pone al tr la propiedad id que fuimos capturando con la condición ya una vez seleccionado con la función find acompañada de css se le aplica el estilo necesario.
Nota:
Es importante tener en cuenta que si en la misma vista se está utilizando más de un jqGrid es necesario especificar en el selector que tabla se desea personalizar con este css ej.
$("#nombre_tabla #" + rowsToColor[i]).find("td").css("background-color", "#FF7F7F");

Espero les haya servido de ayuda.
{ Leer Más }


miércoles, 5 de febrero de 2014

Cómo mostrar Popup utilizando Jquery sobre CodeIgniter.

En algunas aplicaciones web a veces es deseado mostrar una apariencia de aplicación de escritorio donde al dar clic sobre las acciones que deseamos realizar, en lugar de cargar páginas nuevas con la información deseada, nos mantenemos en la misma vista y lo que mostramos son ventanas emergentes (Popup) que podemos manipular siempre desde la misma vista principal.

En este artículo estaremos mostrando como mostrar esos Popup utilizando Jquery y a través de Ajax traemos la información necesaria para ello.

Lo primero que hay que tener es desde donde vamos a dar clic para que salga nuestra nueva ventana, por ejemplo algún link de este tipo:

<a href="#" class="mi_popup">Nueva Ventana</a>

Notar como hemos definido la clase “mi_popup” que es la que vamos a utilizar posteriormente para invocar la llamada a la controladora y nos traiga la información deseada.

Luego tendríamos que tener algún componente html vacío para poner en él la vista que vamos a traer desde nuestra controladora, sería algo como:

<div id="dialog_mi_popup" style="display: none" title="Nueva Ventana"></div>

En la controladora tendríamos la función en la que llamamos la vista, con la característica que hacemos un echo a la función $this->load->view('mi_ventana', '', true):

public function mostrar_ventana()
{
echo $this->load->view('mi_ventana', '', true);
}

En esta función, para este ejemplo tan sencillo no estamos trayendo a la vista datos desde la controladora en el segundo parámetro de la función, y definimos finalmente el último parámetro en true para traer los datos como una cadena, incluso después podemos hacer algún procesamiento con estos datos antes de mostrarlos.

En el código script, básicamente debemos realizar dos cosas, una: definir las propiedades del Popup que vamos a mostrar, que si nos fijamos es el componente html vacío que definimos anteriormente, y otra en el evento clic del link definido hacer la llamada controladora/función que hemos definido y finalmente con esta información mostrar el Popup.

$(document).ready(function()
{
//definiendo las propiedades del popup
$("#dialog_mi_popup").dialog({
autoOpen: false,
height: 550,
width: 650,
modal: true
});

//mostrando el popup en el evento click del link
$(document).on('click', '.mi_popup', function(ev)
{
ev.preventDefault();
$.post('<?php echo site_url().'controladora/mostrar_ventana/'; ?>',
function(data){

$("#dialog_mi_popup").html(data);

$("#dialog_mi_popup").dialog( "open" );
});

});
}

A la función que estamos llamando se le pueden pasar valores, muy útil para cuando la vista que deseamos mostrar en la nueva ventana depende de valores seleccionados en la vista general, como por ejemplo cuando seleccionamos un elemento de un grid y veremos más detalles del elemento en la ventana Popup.

$.post('<?php echo site_url().'controladora/mostrar_ventana/'; ?>', {valor:valor_seleccionado},

Donde por ejemplo valor_seleccionado se alimenta de algún id que estamos guardando en algún componente visual que tenemos oculto…

var valor_seleccionado = $('#id').val();

Tenemos que tener en cuenta entonces que esos valores tienen que ser recibidos en la función de la controladora que estamos llamando de la siguiente forma:

$id = $this->input->post('valor');

Con estos sencillos pasos tendremos nuestros Popup funcionando, hay otros elementos que tenemos que tener en cuenta, como por ejemplo si estamos mostrando un formulario en la ventana Popup y realizando las validaciones en el servidor, se “perdería” la ventana que estamos mostrando al hacer el envío del formulario cuando este falla, ese efecto podríamos evitarlo haciendo las validaciones de nuestro formulario desde el código script. Lo otro que tendríamos que tener en cuenta es que si estamos abriendo y cerrando continuamente varios Popup desde la misma ventana principal, tenemos todo un mismo código html y puede dar conflictos si tenemos variables con el mismo nombre en las diferentes vistas que estamos cargando.

Es todo, espero haya sido de utilidad.

{ Leer Más }


martes, 9 de julio de 2013

Implementando el patrón MVVM con ZK. II

En la entrada anterior  habíamos creado un proyecto Maven de ZK y mostrábamos el patrón MVVM a través de sus características y ventajas y dijimos que íbamos a implementar nuevamente un ejemplo que ya teníamos en MVC pero ahora usando el patrón MVVM.

Para realizar esto partimos del proyecto inicialmente creado, como pueden ver a continuación.

clip_image001

Como estaremos reutilizando mucho código copiaremos tanto las vistas como los modelos implementados usando spring + hibernate. Y lo que realizaremos será cambiar el controlador por un viewmodel que nos enlace todo.

Llegado este momento ya se han copiado los paquetes de los dao, modelo y servicios y el proyecto se puede ver como sigue:

clip_image002

Claro también se han resuelto los temas de las dependencias de spring e hibernate que tienen las clases importadas incluyendo las dependencias en el fichero pom.xml.

La clase MyViewModel la pueden ver a continuación:

clip_image003

Y es sobre la que estaremos trabajando para implementar el MVVM.

Recordemos la UI de este ejemplo:

clip_image005

Vean que se permiten las operaciones CRUD básicas sobre los datos de una persona.

Lo primero es ver la definición de los atributos de la clase viewmodel:

clip_image006

Como se puede apreciar creo variables para cada atributo de la persona que voy a gestionar en la UI.

Luego como sé que debo mostrar un listado de las personas, creo otro atributo para este fin.

Como permitiré que se seleccione un elemento del listado, creo un atributo current de tipo Persona.

Y por último creo un atributo vacío para mostrar un label con información de si algún campo está vacío o no.

Veamos entonces como en la UI capturo los datos de un usuario:

Lo primero es que vean como window usa el BindComposer y se le asocia el viewmodel que se ha implementado.

clip_image008

Resaltado aparece la sección de código que nos interesa, vean como se dice que el valor del textbox nombre será @bind(vm.current.nombre). O sea estoy diciendo que todo lo que escriba ahí será guardado en una instancia del current.nombre que definí en el viewmodel y lo mismo para los otros atributos.

Si recuerdan que en la entrada anterior decíamos que las acciones sobre la vista se mapearían con métodos Command en el viewmodel, en el código se puede ver así:

clip_image009

De esta manera cuando quiera hacer un Adicionar en el viewmodel solo tengo que implementar lo siguiente:

clip_image010

Vean como anoto el método con @Command y luego con @NotifyChange.

Eso se debe a que este método se mapea con un comando que genera la UI y que cuando se ejecute debe actualizar los elementos “listPersona”, “current” y “vacio” en la UI.

Veamos quien es listPersona:

clip_image011

Como ven el listbox que uso para mostrar el listado de las personas recibe sus datos del modelo vm.listPersonas, es por eso que cada vez que añado una nueva persona notifico para que se actualice. El mecanismo de actualización se realiza a través de los get/set de cada elemento que están definidos en el viewmodel.

Aquí también pueden ver como capturo cada elemento del listado devuelto de la siguiente forma: each.atributo.

Lo otro que pueden observar es que defino el elemento selectedItem, esto implica que cuando pincho sobre un elemento de la lista los valores de ese elemento son añadidos al elemento vm.current y por lo tanto mostrados en el grid del inicio. Esto se hace por si se desea modificar o eliminar alguno de los elementos del listado.

Realmente la mayor diferencia entre MVVM y MVC está en el control que se tiene sobre los diferentes elementos de la UI del framework ZK, y claro las ventajas listadas en la entrada anterior.

Les dejo adjunto  el código fuente para que hagan sus pruebas.

 


{ Leer Más }


jueves, 4 de julio de 2013

Implementando el patrón MVVM con ZK. I

En esta entrada veremos cómo crear un proyecto de ZK con Maven y comenzaremos la introducción del patrón MVVM para luego en otra entrada mostrar cómo implementar una aplicación web de ejemplo con ZK usando el patrón MVVM (Model View View-Model).

Lo primero es crearnos una aplicación en el Eclipse STS, ustedes pueden usar otra variante del IDE siempre que tengan un plugin de Maven instalado.

En el STS seguimos estos pasos descritos en el sitio de ZK para poder añadir un arquetipo de Maven a nuestro IDE.

Luego creamos un proyecto Maven.

clip_image001[4]

Y seleccionamos el id del arquetipo a usar:

clip_image003[4]

Seleccionamos el arquetipo y damos Next.

clip_image005[4]

Damos finish y listo. Ya tenemos el proyecto creado. Vean su estructura.

clip_image006[4]

Como ven nos ha creado ya una primera clase, nos ha descargado todas las dependencias necesarias para el trabajo con ZK y nos ha creado una página index.zul sobre la cual podemos empezar a trabajar.

Para acelerar el trabajo se usará el mismo ejemplo que ya desarrollamos en ZK para el patrón MVC y lo llevaremos entonces a MVVM en la siguiente entrada.

Explicamos a continuación las características de este patrón que luego se verán a nivel de código en la siguiente entrada de esta serie:

1. MVVM es un patrón que se originó en Microsoft y constituye una especialización del patrón “Presentation Model” creado por Martin Fowler como una variante del patrón MVC. Este patrón tiene 3 roles: View, Model y ViewModel.

2. La vista y el modelo juegan el mismo rol que en el patrón MVC, mientras que el elemento ViewModel se puede considerar como una especialización de un Controlador, donde puede extraer información de una o más clases modelos para ser mostradas en las vistas. Esta información es expuesta a través de métodos get/set como propiedades JavaBeans.

3. Se dice que el ViewModel es un modelo de una vista, aunque esto hay que explicarlo bien porque aunque contiene el estado de las vistas asociadas no contiene ninguna referencia a los componentes de una vista, por lo que no puede acceder a ella directamente.

4. La restricción del punto 3 impone la existencia de un mecanismo que sincronice la información entre vistas y viewmodel, y es llamado databinding. Una vez que el desarrollador establece este mecanismo, el mismo se encarga de mantener la información sincronizada entre ambos elementos como se puede apreciar en la siguiente imagen.

clip_image008

5. Se dice también que los viewmodel actual como controladores en MVC. Ya que el mecanismo databinding reenvía eventos a manejadores en el viewmodel. Estos manejadores son métodos con anotaciones java específicas. Estos métodos no son otra cosa que patrones Command, los cuales se encargan de manipular datos y notificar a través de los databinding de cambios en los datos, como se aprecia en esta imagen.

clip_image010

6. Los elementos viewmodel pueden ser clases POJO, y no conocer nada de las vistas que son usadas para enviarle eventos y mostrar los datos, lo que aumenta su reutilización.

7. Como los mecanismos de databinding son los encargados de mantener una sincronización entre las vistas y los viewmodel los desarrolladores tienen que especificar los comandos y las dependencias de datos en los viewmodel lo cual se hace usando anotaciones. Un ejemplo de estas anotaciones se puede mostrar en la siguiente imagen.

clip_image011[4]

Como pueden ver se ha definido un atributo de la clase con sus métodos get/set y un método anotado como @Command y con @NotifyChange para indicar los elementos a notificar.

8. La forma de enlazar un viewmodel desde una vista es la siguiente:

clip_image013

Lo importante es ver como al componente Windows se le aplica el binder org.zkoss.bind.BindComposer el que permite instanciar el viewmodel foo.MyViewModel identificándolo a partir de ese momento con el id = vm.

Luego pueden ver que se accede a los atributos del viewmodel usando esta sintaxis @bind(vm.name) y a los métodos usando @command('newOrder')

Las ventajas de este patrón son las siguientes:

· Encaja muy bien cuando se desea que los equipos de diseño de las vistas y de los viewmodel trabajen en paralelo. Solo se debe definir el contrato respecto a la información a intercambiar y listo. Cada uno trabaja por su parte.

· Presenta un bajo acoplamiento con la lista, ya que los viewmodel no conocen nada acerca de la vista con la cual son enlazados.

· Se mejora mucho la reusabilidad, al poder usarse un mismo viewmodel para diferentes vistas.

· Se mejora la prueba del sistema, si se quiere usar un método guiado por pruebas. Esto se debe a que al no existir una dependencia respecto a las vistas, los viewmodel pueden ser probados usando junit por ejemplo sin necesidad de tener las UI.

Por ultimo les dejo estas imágenes:

Aquí pueden ver una vista general de la arquitectura de este patrón:

clip_image015

Y se puede apreciar como el binding crea el mecanismo de comunicación entre las vistas y el viewmodel.

Y en esta otra imagen tienen un ejemplo sobre cómo sería el flujo de eventos en una llamada al sistema.

clip_image017

En la siguiente entrada de la serie veremos la continuación del proyecto creado al inicio y la implementación de este patrón, para mostrar las diferencias respecto al patrón MVC.

{ Leer Más }


viernes, 14 de junio de 2013

Desarrollo de una aplicación web MVC en JAVA con ZK, Spring e Hibernate.

Ya en otras entradas hemos visto los temas introductorios a ZK como framework JAVA para el desarrollo de la capa de presentación y también hemos visto el uso de Spring e Hibernate para el desarrollo de la capa de negocio y de persistencia.

En esta entrada veremos a través de un ejemplo práctico como combinar estos frameworks para implementar un CRUD (Patrón de caso de uso con las funcionalidades de añadir, modificar, eliminar, listar).

El proyecto será una aplicación web en Maven por lo que comenzaremos por el fichero pom.xml donde pondremos los repositorios que usaremos y las dependencias a incluir en el proyecto. De esta forma Maven las gestionará por nosotros.

El pom lo pueden ver aquí.

<pre class="brush:xml;">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>GestUsuariosZK</groupId>
<artifactId>GestUsuariosZK</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>GestUsuariosZK</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<org.springframework.version>3.2.0.RELEASE</org.springframework.version>
<zk.version>6.5.0</zk.version>
<zkel.version>1.1.0</zkel.version>
</properties>

<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.8</version>
<configuration>
<wtpversion>2.0</wtpversion>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>


<!-- dependencias de ZK -->

<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zk</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zul</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zhtml</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.common</groupId>
<artifactId>zcommon</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zkforge.el</groupId>
<artifactId>zcommons-el</artifactId>
<version>${zkel.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.common</groupId>
<artifactId>zweb</artifactId>
<version>${zk.version}</version>
</dependency>
<dependency>
<groupId>org.zkoss.zk</groupId>
<artifactId>zkplus</artifactId>
<version>${zk.version}</version>
</dependency>


<!-- dependencias comunes -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>



<!-- dependencias de Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${org.springframework.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${org.springframework.version}</version>
</dependency>

<!-- dependencias para el acceso a datos -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.9.Final</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>zk repository</id>
<url>http://mavensync.zkoss.org/maven2</url>
</repository>
</repositories>
</project>
</pre>

Básicamente la aplicación es una implementación del patrón de arquitectura MVC o Modelo Vista Controlador.

· Tendremos las vistas que serán las páginas .zul.

· Tendremos los modelos que serán las clases encargadas del modelado de las entidades de nuestro sistema, tal y como vimos en las entradas relacionadas con la persistencia.

· Tendremos los controladores que son las clases que se encargan de coordinar las acciones entre las vistas y los modelos. Básicamente recibe eventos de las vistas y actualiza los modelos así como obtienen datos de los modelos y cambian la representación de dichos datos en las vistas.

De esta manera se logra una separación de responsabilidades eficiente. La idea general la pueden ver en la siguiente imagen.

clip_image001

La estructura del proyecto es la siguiente:

clip_image002

En el paquete org.desarrollo.ejemplo1.web se tiene la clase controladora.

En el paquete org.desarrollo.ejemplo1.servicio se tiene la interfaz que me enlaza con el modelo y su implementación así como un localizador del servicio que se encarga de obtener una sesión y cargar el bean de la implementación del modelo.

En el paquete org.desarrollo.ejemplo1.modelo se tiene la clase modelo con su mapeo a hibernate en este caso usando un fichero de configuración y no anotaciones como habíamos visto hasta ahora.

En el paquete org.desarrollo.ejemplo1.dao tengo la implementación del DAO genérico con todo el código de acceso a los datos que puede ser reutilizable.

La interfaz de la aplicación refleja las acciones de caso de uso típico CRUD:

clip_image004

Pueden usar el editor gráfico de ZK como se explica en esta entrada para que puedan visualizar la UI.

Como pueden ver tiene operaciones para:

· adicionar una persona,

· actualizar los datos a partir de la selección de la persona en el listado,

· buscar una persona a partir de uno de sus datos,

· borrar una persona previa selección de la misma en el listado.

La interfaz se diseña en un XML que es el formato usado por ZK para representar sus componentes UI (user interface) o Interfaz de Usuario en español.

La pueden ver aquí:

<pre class="brush:xml;">

<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit"?>
<window id="win" apply="org.desarrollo.ejemplo1.web.PersonasController" width="1024px" title="gestion de datos" border="normal">

<groupbox>
<caption label="Operaciones CRUD:" width="580px" />
<label id="label1" value="sdsd"/>
<grid>
<columns sizable="true">
<column width="100px"/>
<column width="370px"/>
</columns>
<rows>
<row>
<label value="Nombre:"/>
<textbox id="nombre" value="@{win$composer.current.nombre}" width="350px"/>
</row>
<row>
<label value="1er Apellido:"/>
<textbox id="apellido1" value="@{win$composer.current.apellido1}" width="350px"/>
</row>
<row>
<label value="2do Apellido:"/>
<textbox id="apellido2" value="@{win$composer.current.apellido2}" width="350px"/>
</row>
</rows>
</grid>
<button id="add" label="Adicionar" />
<button id="update" label="Actualizar" />
<button id="search" label="Buscar" />
<button id="delete" label="Borrar" />
</groupbox>
<listbox id="box" multiple="true" selectedItem="@{win$composer.current}" emptyMessage="No hay personas a mostrar">
<listhead>
<listheader label="Nombre:"/>
<listheader label="1er Apellido:"/>
<listheader label="2do Apellido:"/>
</listhead>
<template name="model">
<listitem width="680px">
<listcell label="${each.nombre}" />
<listcell label="${each.apellido1}" />
<listcell label="${each.apellido2}" />
</listitem>
</template>
</listbox>
</window>
</pre>

Como pueden observar lo primero es definir un grupo donde pondré varios componentes, para eso uso el componente “groupbox”.

Dentro de este componente pongo un “grid” que me permite tal como si usara un listbox ubicar columnas (columns) y filas (rows) para mostrar la primera parte de la UI.

Luego pongo una serie de botones usando el componente “button”.

Al salir del “groupbox” utilizo otro componente para mostrar el listado de las personas, que representan las tuplas en la BD, se trata de “listbox” lo más importante de este componente es el uso de otro componente dentro que se llama “template” y es el que me permite visualizar automáticamente los resultados en función de las acciones sobre la vista y la respuesta de la controladora.

NOTA: es importante que se fijen que todos los componentes tienen un id que me permite referenciarlos en la clase controladora.

Los principales atributos de la clase controladora reflejan los componentes en la UI, como pueden ver en la siguiente imagen.

clip_image005

Como ven uso una anotación Wire para obtener los componentes con esos nombres en la UI.

Igual uso la anotación @Listen para los métodos que se enlazan con los botones de la UI.

clip_image007

Vean como utilizo el evento onClick sobre el componente para relacionarlo con la operación en la clase controladora. Es como si dijera: cada vez que se genere el evento onClick sobre el componente “update” se debe llamar al método update.

Lo demás es muy típico del trabajo con Spring e Hibernate así que les dejo el código fuente  del proyecto para que lo compilen con Maven y lo desplieguen en el servidor de su preferencia.

La tabla que se usó es realmente sencilla y este es su DDL:

CREATE TABLE public.persona (

id BIGINT NOT NULL,

nombre VARCHAR NOT NULL,

apellido1 VARCHAR NOT NULL,

apellido2 VARCHAR NOT NULL

) WITHOUT OIDS;

Para crear el .war de esta aplicación deben pararse en la raíz del proyecto, suponiendo que tengan Maven ya instalado y configurado.

Bastan con ejecutar este comando “mvn clean package”, verán cómo se descargan todas las dependencias del proyecto, se compila, se ejecutan las pruebas, en este caso no hay, y en la carpeta target del proyecto se les creará un .war que deben desplegar en un servidor como tomcat y listo.



.
{ Leer Más }


jueves, 16 de mayo de 2013

CodeIgniter y el Modelo Vista Controlador

Cuando se desea desarrollar un sistema informático, ya sea de mediana o gran envergadura, se impone utilizar alguna metodología de desarrollo, y poner en práctica patrones arquitectónicos y de software. Los patrones son modelos de diseño y desarrollo propuestos debido a la cantidad de aplicaciones informáticas que tienen características similares, y basados en experiencias y buenas prácticas de desarrolladores de todos los tiempos.

En el desarrollo web, uno de los patrones de uso recurrente es el patrón arquitectónico Modelo-Vista-Controlador[1] (MVC, del inglés Model-View-Controller ), el cual separa la lógica de la aplicación de su representación al usuario y la comunicación al modelo, como se representa en la figura 1.

clip_image002

Figura 1 Representación del patrón de arquitectura Modelo-Vista-Controlador (MVC).

Para este patrón la Vista es la representación de todos los elementos de interacción con los usuarios, es decir, la página web visualizada en el navegador del usuario, con los componentes de formularios, etc. El Modelo encierra las funcionalidades para interactuar con los datos, generalmente de tipo persistente, en este caso, en esta capa se ubican las funciones de interacción con la base de datos. El Controlador por su parte, maneja las entradas de la Vista, abstrayendo su procesamiento para finalmente aplicar los cambios en el modelo. Esto permite hacer cambios en el control sin afectar los elementos que conforman la Vista y el Modelo.

En otras palabras, un código como el siguiente no debería estar en un único fichero.php. Fíjese que he capturado un valor de la vista, he consultado la base de datos y he mostrado los resultados, todo en un mismo segmento de código:

<?php
$connection = pg_connect("dbname=usurios port=5432 user=postgres password=postgres");

$name = $_POST['userName'];
$sentence = "select * from usuarios where nombre = '".$name."'";
$query = pg_Exec($connection, $sentence);
$num_rows = pg_num_rows($query);

echo '<span style="font-weight: bold;"> Se encontraron '.$num_rows.' usuarios con ese nombre.</span>';
?>

Según el MVC debería existir un modelo que haga la consulta, una vista que muestre el resultado, y un controlador que capture el post de la vista, pase el valor al modelo, reciba el resultado de la consulta y la pase a la vista para ser mostrado.

Pues bien, el CodeIgniter (un framework o conjunto de herramientas para desarrollo de sitios web usando PHP), permite no solo desarrollar proyectos mucho más rápido que lo que podría hacer si escribiera el código desde cero, sino que además se basa en el modelo-vista-controlador, permitiendo una buena separación entre lógica y presentación, y permitiendo que las páginas web contengan un mínimo de codificación. En CodeIgniter las clases del modelo no son requeridas.

Veamos el ejemplo anterior, pero usando clases de CodeIgniter, en tres ficheros diferentes:

//en el fichero users_model.php
class Users_model extends Model {
function get_users_quantity($name)
{
$this->db->where('nombre', $name);
$query = $this->db->get('usuarios');

return $query->num_rows();
}

}

 

//en el fichero users.php
class Users extends Controller {
function quantity()
{
$name = $this->input->post('userName');
$this->load->model('users_model');
$data['quantity'] = $this->users_model-> get_users_quantity($name);
$this->load->view('public_view', $data);
}

}

 

//en el fichero public_view.php


echo '<span style="font-weight: bold;"> Se encontraron '.$quantity.' usuarios con ese nombre.</span>';



Bueno, hemos dividido el código en tres partes correspondientes al modelo, al controlador y a la vista. Como pueden ver, en la clase Users_model se hace la consulta a la base de datos; la clase controladora Users actúa como interfaz entre el modelo y la vista, pidiendo al modelo un resultando y cargando la vista, a la cual se le pasa el quantity dentro del arreglo data; y en el fichero public_view.php correspondiente a la vista se muestran los resultados, con una total abstracción de la lógica de control y la interacción con la base de datos.

Con esta arquitectura, nunca verás una página .php en la barra de direcciones de tu navegador, sino el nombre del controlador y la función, por ejemplo, el caso anterior sería accesible por la dirección:

http://sitio/users/quantity

Los ficheros con las clases deben ser colocadas en carpetas específicas dentro del directorio del sitio de CodeIgniter, como se muestra en la figura 2.

clip_image002[4]

Figura 2 Estructura de carpetas de CodeIgniter.

Bueno, en este artículo he comentado las ventajas de usar Codeigniter para proyectos web medianos y grandes, donde es necesario mantener una organización del código y una estructura que garantice rapidez y seguridad, así como la comodidad que brinda para implementar nuestro sitio siguiendo la arquitectura MVC. En próximos artículos comentaré otras ventajas de usar CodeIgniter.





[1] Bahsoon, R. y W Emmerich: Evaluating software architectures: development, stability and evolution. Julio 2003


{ Leer Más }


miércoles, 24 de abril de 2013

Desarrollar una aplicación web usando el patrón MVC con ZK.

El presente artículo tiene el objetivo de iniciarle en el desarrollo de aplicaciones web, usando el patrón MVC (modelo-vista-controlador) con el framework ZK. Le permitirá aprender a manejar los componentes de la vista manualmente e implementar la lógica necesaria para que funcione nuestra aplicación.

Importar y ejecutar la aplicación de ejemplo.

Se provee un proyecto eclipse, en un fichero zip, que contiene el código fuente completo de la aplicación de ejemplo; usted puede descargar e importarlo para su Eclipse, para que no tenga que iniciar desde cero.

Para usar la aplicación de ejemplo, siga los siguientes pasos:

Declarando una Clase de Dominio

Lo siguiente es la clase de dominio que representa a un carro.

Extraído de Car.java:

public class Car {

   private Integer id;

   private String name;

   private String company;

   private String preview;

   private String description;

   private Integer price;

   //omit getter and setter for brevity

}

Para ver el código completo de la clase puedes ir a continuación, a la sección de referencias [3].

Ahora definimos una interfaz para implementarla en una clase de servicio que contendrá la lógica de negocio necesaria en el ejemplo, como buscar los carros.

Extraído de CarService.java:

public interface CarService {

   /**

    * Retrieve all cars in the catalog.

    * @return all cars

    */

   public List findAll();

   /**

    * search cars according to keyword in name and company.

    * @param keyword for search

    * @return list of car that match the keyword

    */

   public List search(String keyword);

}

En este ejemplo, hemos definido la clase CarServeImpl que implementa la interfaz anterior. Para simplificar, usamos una lista estática de objetos como modelo de datos. Puedes reescribirla para que se conecte a una base de datos en una aplicación real. Los detalles de la implementación no están cubiertos en el ámbito de este artículo, puedes echar una ojeada a continuación en la sección de referencias [4].

Creando la Interfaz de Usuario

Diseñar la interfaz de usuario es un buen comienzo para crear una aplicación, además de que te ayuda a definir el alcance de tu aplicación.

ZK nos provee de cientos de componentes, listos para ser usados en el interfaz del usuario, por lo tanto un desarrollador puede crear la interfaz de usuario que desee combinando y mezclando esos componentes sin tener que crearlos desde 0.

En ZK puedes usar el ZK Markup Language para la creación del Interfaz del usuario (ZUML) [5], que es un lenguaje estructurado como un XML, que te permite definir la Interfaz del Usuario.

La convención que se utiliza en ZK es que para los ficheros en formato ZUML utilicemos la extensión .zul como sufijo. En los ficheros zul, podemos representar un componente como un elemento del XML (tag) y configurarlo (estilo, comportamiento, funcionalidad) mediante los atributos del elemento XML. [6]

En el caso de esta aplicación de ejemplo, primero, queremos diseñar una ventana con un título específico y bordes normales, como si fuera el borde exterior (marco) de la aplicación.

Extraído de search.zul:

<window title="Search" width="600px" border="normal">
   <!-- put child components inside a tag's body -->
</window>

Como "window" es el componente que contiene al resto, lo llamamos componente raíz o "root". El componente "window" (ventana) normalmente se usa como contenedor de otros componentes, porque en esencia, simplemente muestra una ventana vacía como en una aplicación de escritorio tradicional, y en esta podemos añadir los componentes que queramos.

Los componentes dentro de la ventana los llamaremos hijos o "child", y deben estar dentro del cuerpo del elemento "window".

Por ejemplo, hacemos que aparezca el título de la ventana estableciendo texto en el atributo "title" del elemento "window", y hacemos visible el borde de la ventana estableciendo el atributo "border". En el caso del ancho, usaremos el atributo "width", pero en este caso estableceremos el valor de la propiedad CSS, es decir "800px" o "60%".

Básicamente, el interfaz de usuario de nuestra aplicación de ejemplo se divide en 3 áreas dentro de la ventana ("window"), que son (de arriba a abajo): área del buscador, área de listado de los carros y área de detalles del carro.


Área del buscador

Trabajar con los componentes de ZK es como trabajar construir bloques de código, puedes combinar y mezclar componentes que existan (incluso crear los tuyos propios) para crear la interfaz de usuario que desees.

Para permitir a los usuarios buscar, necesitamos un componente que les permita escribir el texto, es decir un "input", y un botón para lanzar la búsqueda.

A continuación vemos un ejemplo de cómo podemos usar algunos componentes simples para cubrir estos requisitos.

Extraído de search.zul:

<hbox align="center">
   Keyword:
   <textbox id="keywordBox" />
   <button id="searchButton" label="Search" image="/img/search.png" />
</hbox>

hbox es un componente contenedor, que ordena horizontalmente los componentes que contenga. Seguro que has adivinado, la "h" de "hbox" significa horizontal. Como los componentes hijos o "child", tienen diferentes tamaños, establecemos el atrubuto "align" con valor "center" para que se alineen, entre ellos sobre su línea central.

En algunos componentes del ejemplo también especificamos un atributo "id", esto nos permitirá referirnos a ellos y por lo tanto poder controlarlos usando el "id". Si quieres convertir el botón en un botón con imagen solo tienes que especificar el path de la imagen en el atributo "image" del mismo.

Área de listado de los coches

ZK dispone de muchos componentes para mostrar un conjunto de datos, como por ejemplo los componentes de lista "listbox", malla "grid" y árbol "tree". En este ejemplo, hemos elegido usar una lista "listbox" para mostrar un listado de coches, con tres columnas: Nombre, Compañía y Precio.

Establecemos el atributo "height", de forma que se mostrarán tantas filas como quepan; puedes navegar con la barra de scroll para ver el resto de filas.

El atributo "emptyMessage" se usa para mostrar un mensaje cuando la lista no contiene elementos.

Puesto que el componente de lista "listbox" también es un componente contenedor puedes añadirle un componente "listhead" para mostrar y definir los nombres de las columnas. También puedes añadirle un componente "listitem" para mostrar los datos, y dentro de este componente "listcell", tantos como columnas hayas definido (en el "listhead" por ejemplo).

En el siguiente código de ejemplo usamos "listcell" con contenido estático (3 listcells) para mostrar la estructura de un componente "listitem", pero a continuación, te mostramos cómo crear un listitem dinámicamente, de acuerdo a los datos que recibe.

Extraído de search.zul:

<listbox id="carListbox" height="160px" emptyMessage="No car found in the result">
   <listhead>
       <listheader label="Name" />
       <listheader label="Company" />
       <listheader label="Price" width="20%"/>
   </listhead>
   <listitem>
       <listcell label="product name"></listcell>
       <listcell label="company"></listcell>
       <listcell>$<label value="price" /></listcell>
   </listitem>
</listbox>

Área de detalles del coche

Al igual que el "hbox", "vbox" es un componente que distribuye los componentes hijos "child", pero en este caso en vertical. Combinando estos 2 componentes contenedores, podemos mostrar más información en la pantalla. El atributo "style" permite personalizar el estilo del componente escribiendo en él CSS directamente.

Extraído de search.zul

<hbox style="margin-top:20px">
   <image id="previewImage" width="250px" />
   <vbox>
       <label id="nameLabel" />
       <label id="companyLabel" />
       <label id="priceLabel" />
       <label id="descriptionLabel"/>
   </vbox>
</hbox>

Para ver el fichero search.zul diríjase a la sesión de referencias [7].

Manipulando la lógica de la UI.

El próximo paso después de construir una UI (Interfaz Gráfica de Usuario) es hacer que responda al usuario. A continuación realizaremos una aproximación al mecanismo para controlar los componentes de la UI por ti mismo. Este mecanismo puede ser clasificado en el patrón de diseño  Modelo-Vista-Controlador (MVC) [8]. Este patrón divide la aplicación en tres partes:

El Modelo consiste en los datos de la aplicación y las reglas del negocio. CarService y otras clases usadas por ella representan esta parte de la aplicación de ejemplo.

La Vista representa la interfaz de usuario. La página zul que contiene los componentes ZK representa esta parte. La interacción del usuario con los componentes genera eventos que son lanzados a los controladores.

El Controlador juega el papel de coordinador entre la Vista y el Modelo. Recibe los eventos desde la Vista para actualizar el Modelo y busca datos en el modelo para cambiar la presentación de la Vista.


Referencias:

{ Leer Más }


IconIconIcon