Professional Documents
Culture Documents
Internet
con GeneXus
Versión 9.0
Enero 2007
www.genexus.com/training
Para poder realizar el curso debe contar con la versión 9.0 de GeneXus. El curso consta de los
conceptos teóricos necesarios para el desarrollo de una aplicación web, así como la puesta en
práctica de los mismos en una aplicación ejemplo. El desarrollo de esta aplicación podrá ser
visualizado paso a paso a lo largo del curso mediante videos incluidos en el mismo. La idea es que
Ud. vaya realizando esta aplicación en paralelo (a medida que avanza capítulo por capítulo en forma
ordenada).
En caso de estar interesado en consultar a un docente del curso las dudas que le vayan surgiendo,
y/o dar un examen final de forma tal de obtener (en caso de aprobación) un certificado de haberlo
realizado en modalidad no presencial, diríjase a nuestro sitio de capacitación a distancia:
INTRODUCCIÓN
En este capítulo intentamos ofrecer una orientación básica sobre el curso y su logística.
Incluye información acerca de la estructura del curso, cómo navegar a través del mismo, cómo
comunicarse con un instructor y cómo obtener información de interés para el correcto desarrollo del
mismo.
Metas y objetivos
Este curso lo va a capacitar en el desarrollo de aplicaciones para Internet utilizando GeneXus 9.0.
El curso está dividido en capítulos, cada uno de los cuáles tiene una introducción que establece los
temas que serán abordados dentro del mismo y en algunos casos sugerencias acerca de cómo leerlo.
Para facilitar el aprendizaje, los conceptos teóricos van acompañados de ejemplos prácticos y de
videos demostrativos, que complementan lo explicado, de manera tal que el alumno pueda obtener
una profunda comprensión de los temas tratados.
A medida que se avanza en los capítulos se va desarrollando una aplicación bien simple que pone en
práctica los conceptos más importantes que se van estudiando y que permite que el alumno pueda
comenzar a interactuar con la herramienta reproduciendo lo realizado en los videos primeramente,
y realizando los ejercicios prácticos propuestos, luego.
Al finalizar el curso Ud. será capaz de desarrollar aplicaciones para Internet de la vida real utilizando
la metodología GeneXus y haciendo uso de la potencia que ofrece la herramienta.
Asimismo este material podrá ser utilizado como manual de consulta en una etapa posterior, de
manera de poder refrescar algún tema en particular, o profundizar en detalles no considerados en
una primera instancia.
Los primeros ocho capítulos constituyen el corazón del curso, y deben ser seguidos con
detenimiento. Estos capítulos transmiten la esencia del desarrollo de aplicaciones para Internet con
GeneXus. Los demás capítulos tienen distintos grados de importancia, pero podrían ser
eventualmente omitidos en una primera lectura si lo que se busca es comenzar rápidamente a
desarrollar este tipo de aplicaciones.
Cualquier sugerencia que desee realizar, con gusto la recibiremos en la siguiente dirección de correo
electrónico training@genexus.com.
Prerrequisitos
Existen dos requisitos fundamentales que es necesario satisfacer antes de comenzar este curso. Ellos
son tener conocimientos de GeneXus (preferentemente la versión 9.0) y conocimientos de Internet.
El primero de los requisitos es excluyente: el curso está dirigido a personas con conocimientos de
GeneXus que hayan desarrollado aplicaciones con la herramienta. De no contar con estos
conocimientos, la dificultad para alcanzar un nivel de comprensión aceptable será importante.
Las diferencias inherentes a las versiones de GeneXus pueden dificultar también la comprensión del
curso por lo que se recomienda realizar una actualización previa a la versión 9.0.
El segundo de los requisitos, si bien no es excluyente, debe alcanzarse antes de comenzar el curso.
Para ello se incluye un capítulo como anexo, de Introducción a Internet que establece la
terminología y conceptos necesarios para entender este ambiente. Quién no cuente con dichos
conocimientos, deberá comenzar por ese capítulo y no continuar hasta no haber asimilado todos los
conceptos allí vertidos.
Requerimientos computacionales
Debe contar con GeneXus versión 9.0 full. En el presente curso desarrollaremos una aplicación de
ejemplo generando para una plataforma .NET, utilizando como DBMS (DataBase Management
System) el SQL Server 2005 Express Edition.
Está disponible en nuestro sitio todo el software necesario para poder desarrollar la aplicación de
entrenamiento en la plataforma mencionada. No obstante ello, si Ud. cuenta con otra plataforma de
desarrollo de las soportadas por GeneXus y desea realizar la parte práctica del curso utilizándola en
lugar de la que ofrecemos, puede hacerlo. Deberá tener en cuenta que en tal caso pueden haber
diferencias con lo que verá en los videos, pues cada plataforma tiene características propias, y
habrán configuraciones particulares que deberá realizar de forma distinta a la mostrada.
El manual de instalación se encuentra disponible para ser bajado de nuestro Download Center:
http://www2.gxtechnical.com/portal/hgxpp001.aspx?15,8,77,O,S,0,,1924;4;4;;/%20%20/;/%20%20/;
M
A continuación se presenta una lista del hardware y software necesario para ejecutar GeneXus y las
aplicaciones generadas en una plataforma .NET contra SQL Server 2005 Express Edition:
ADO.NET
1
El .NET Framework 1.1 Redistributable Package puede ser bajado del sitio web de Microsoft:
http://msdn.microsoft.com/netframework/downloads/framework1_1redist/
2
El Visual J# Distribution Package 1.1 puede ser bajado del sitio web de Microsoft:
http://msdn.microsoft.com/vjsharp/downloads/howtoget/default.aspx
3
Se recomienda tener instalado el "Microsoft SQL Server Management Studio Express", el cual
puede ser bajado del sitio web de Microsoft:
http://www.microsoft.com/downloads/details.aspx?FamilyId=C243A5AE-4BD1-4E3D-94B8-
5A0F62BF7796&DisplayLang=en
4
Puede bajarlo de nuestro Download Center:
http://www.gxtechnical.com/main/hdcenter.aspx?2,5,36,1183
Necesitará contar con algún reproductor de archivos multimedia para poder ver los videos incluidos
en el curso, que son archivos de extensión AVI.
El video debe reproducirse con el mismo tamaño del original (size 100%) pues de lo contrario la
imagen puede degradarse y no verse con nitidez.
Asimismo, antes de reproducir la primera de las demos, deberá haber ejecutado en su máquina el
archivo TSCC.EXE que viene junto con el curso. TSCC es el codificador que se utilizó al producir los
videos de este curso, para compactar los videos sin perder calidad de imagen. Debe estar instalado
en toda máquina en la que se vayan a visualizar los videos del curso.
En el documento Problemas con la reproducción de los videos tiene la solución a algunos de los
problemas que se le podrían presentar al intentar reproducir los videos incluidos en el curso. Allí se
indica también de dónde se pueden bajar reproductores en forma gratuita.
Recomendamos una resolución de pantalla de 800x600, para poder ver los videos correctamente.
Elaboramos este curso intentando por un lado no aburrir al alumno con detalles innecesarios en una
primera lectura, pero por otro brindando información completa de los temas tratados.
Una forma de alcanzar estos objetivos sería postergar la complejidad y/o los detalles para capítulos
más avanzados dentro del curso. Si bien de esta manera lograríamos los dos objetivos anteriores, un
mismo tema estaría desperdigado en muchos capítulos, dificultando así una consulta posterior.
Con la intención de que el material sea utilizado tanto en la etapa de aprendizaje como en una
etapa de consulta posterior -a modo de libro de referencia- aparece pues un tercer objetivo: que los
temas estén tan auto-contenidos como sea posible, de modo de facilitar la consulta posterior.
En la mayoría de los casos estos objetivos se tornan contrapuestos, por lo que buscamos una
solución de equilibrio.
Intentamos dejar los temas lo más encapsulados posible en capítulos, sin perder de vista los
aspectos didácticos. Para ello, establecimos una simbología que incluimos en los documentos para
orientar visualmente al lector discriminando qué partes de la documentación pueden excluirse en
una primera lectura, qué partes son de fundamental importancia y deben convocar toda su
atención, etc. Asimismo establecimos una simbología análoga a nivel del índice –árbol- del curso. En
las tablas que aparecen al final de esta página listamos estos símbolos y sus significados.
Es así que el curso se divide en capítulos, cada uno de los cuales contiene una introducción que
resume los puntos que se tratarán dentro del mismo, brindando sugerencias al lector acerca de
cómo leerlo. Los capítulos contienen documentos de distintos tipos, así como subcapítulos.
Este curso está pensado para ser seguido fundamentalmente de manera secuencial. Algunas veces
se podrán producir desviaciones a ese orden, tanto por decisión del lector, como por alguna
sugerencia explícita dentro del curso. Normalmente se comienza con la introducción de un capítulo,
y luego se pasa a leer el documento que le sigue en orden dentro del índice.
Si bien los documentos están ordenados de modo de ser leídos secuencialmente, pueden, no obstante,
contener links que los relacionen con otros documentos de otras partes que están más adelante o más atrás
en el curso.
Aconsejamos seguir los links “hacia adelante” solo cuando se está realizando una “referencia posterior”, es
decir, cuando ya se ha dado una primera lectura a todo, y se está consultando un tema específico. La razón
es que el lector ya llegará a esos temas cuando siga secuencialmente con el curso, y de hacerlo en el
momento en que encuentra el link corre el riesgo de perder el foco de lo que estaba estudiando.
Los que son “hacia atrás” sí pueden utilizarse en la primera lectura, pues posibilitan refrescar o
recordar temas, conceptos, ideas, etc. vistos recientemente y aún no suficientemente afianzados.
Del texto que se despliega al pasar el mouse sobre del link se desprenderá claramente el tipo del link
-si es “hacia adelante” o “hacia atrás”.
Lea las tablas de símbolos que figuran a continuación para entender el significado de los símbolos
que aparecerán a lo largo de todo el curso.
Símbolo Significado
Sugerimos tener GeneXus abierto mientras se está siguiendo el curso, de manera tal de poder ir
viendo en la herramienta los elementos que se van mencionando e ir probando en la aplicación de
ejemplo.
Como el propósito de este curso es que el alumno pueda desarrollar aplicaciones de la vida real para
Internet utilizando GeneXus, elegimos una aplicación de ejemplo bien simple para ir poniendo en
práctica a lo largo del curso los conceptos que se vayan incorporando.
La aplicación que hemos elegido es una simplificación de una aplicación real: un sistema para una
agencia de viajes que permite la búsqueda de pasajes y servicios turísticos.
A grandes rasgos: la agencia contará con un sitio en Internet donde permitirá a los clientes realizar
búsquedas de destinos, los vuelos existentes y los diferentes servicios brindados. Incluirá también
todo el back-end para el mantenimiento de la información relacionada.
Utilizamos las convenciones de sintaxis de los comandos, reglas, eventos, etc. del lenguaje que se utilizan en
el Help de GeneXus, por lo que recomendamos leer el documento “Syntax Conventions” del Help.
Con el objetivo de brindar a los desarrolladores una fuente única de información potenciada con una
“ingeniería de búsqueda” que les permita acceder rápida y fácilmente a la información técnica
(release notes, manuales, tips, whitepapers, etc.) sobre los diferentes productos que desarrolla
ARTech, se creó la GXDL, GeneXus Developer Library, una biblioteca que centraliza toda esta
información técnica.
Puede ser consultada online o puede ser utilizada en forma local mediante una sencilla instalación.
http://www.gxtechnical.com/gxdl
Podrá crearse un usuario en nuestro sitio web GxTechnical, http://www.gxtechnical.com, y bajar del
Download Center todo el material permitido según el nivel de su usuario. En el Download Center
encontrará productos, cursos, ejemplos, manuales, release notes, GXDL, utilitarios, technical papers,
etc.
A continuación mencionaremos los temas que están relacionados con el curso para que el lector
pueda recurrir a la GXDL en caso de tener interés en abordarlos por su cuenta.
Ellos son:
Introducción a “Business Intelligence” (Data Warehousing)
Los videos son archivos con extensión .avi. Debe configurar su máquina para que los abra siempre
con el reproductor con el que cuente.
Los videos que se utilizan en este curso son producidos utilizando un codificador, TSCC, que permite
comprimir los archivos sin degradar la calidad de la imagen. Este codificador debe estar instalado en
toda máquina en la que se vayan a visualizar los videos.
El archivo TSCC.EXE que incluimos junto con el curso, debe ser ejecutado en su sistema de manera
de instalar el codificador TSCC en su máquina. Esta acción solo debe realizarse una vez.
Para Windows NT/2000/XP los usuarios deben tener permisos de administrador para realizar la
instalación.
http://www.techsmith.com/download/studiodefault.asp
Si se escala el video en la aplicación que lo está reproduciendo el video se verá borroso. Los videos
deben reproducirse con su tamaño original, sin ser escalados.
Si el video se está reproduciendo en Media Player 7, 8 o 9 y ud. no logra ver la imagen nítidamente,
el problema probablemente sea de que el video no se está reproduciendo al 100% del tamaño
original. Es un problema que tienen estas versiones del Media Player en sus “skins” mode
predeterminados. Por defecto escalan los videos durante la reproducción a un tamaño menor,
dando como resultado la degradación de la calidad de la imagen. Muchas veces el seleccionar
View/Video Size/100% no tiene el menor efecto.
La solución es configurar el Media Player para que no escale las imágenes. Hay varias formas de
hacerlo:
1. Configurar Media Player para que utilice “Classic skin”. Presionar el botón “Skin Chooser” y
seleccionar “Classic”.
http://www.microsoft.com/windows/windowsmedia/en/download/default.asp
Otra opción es utilizar el TechSmith Camtasia AVI Player, que puede bajarse libremente de:
Crearemos una base de conocimiento para implementar una aplicación para una agencia de viajes
que iremos desarrollando gradualmente a lo largo del curso.
Además, entraremos a GeneXus para dar los primeros pasos en el desarrollo de una aplicación Web
y comenzaremos a trabajar con el editor GeneXus para estos objetos.
Por un lado se tiene la red de la empresa (Intranet), donde se tiene un Servidor Web en el cual se
publican las páginas Web.
Este servidor puede ser también el servidor de base de datos, o se puede tener un servidor
específico para realizar esta tarea.
Los usuarios de Internet tendrán acceso a las páginas que sean públicas y podrán acceder a los datos
almacenados en la empresa a través de páginas dinámicas.
Por otro lado, los usuarios de la empresa (Intranet) podrán acceder a las páginas públicas y a las
páginas privadas de la empresa.
Alternativas para el desarrollo de aplicaciones Web con GeneXus
Java y .NET son los generadores disponibles en GeneXus para desarrollar aplicaciones Web.
Las aplicaciones podrán ejecutar con un servidor Web Windows, UNIX o ISeries y podrán usar
cualquier manejador de base de datos, dentro de las plataformas soportadas por cada uno de los
generadores GeneXus.
Dependiendo del sistema operativo del servidor de Base de Datos y del servidor Web a utilizar, es el
generador GeneXus que puede seleccionarse. En varias plataformas se plantean varias alternativas.
La decisión del generador a utilizar se tomará principalmente por los requerimientos adicionales o
interacciones con otras aplicaciones, ya que el ‘look and feel’ de la aplicación será el mismo
independientemente del generador que se utilice.
Servidor de Base de datos Servidor Web Generador .NET Generador Java
Windows Windows SI SI
Windows Unix NO SI
Unix Windows SI SI
Unix Unix NO SI
ISeries Windows SI SI
ISeries ISeries NO NO
Como es sabido, la primera tarea cuando se comienza a desarrollar una aplicación con GeneXus es
crear la base de conocimiento que representará e implementará al sistema. Lo mismo ocurre
cuando la aplicación a desarrollar es Web.
Puede ocurrir, que la base de conocimiento ya exista (por ejemplo con interfaz Win) y lo que deba
crearse en ese caso es solamente un nuevo modelo en esa base de conocimiento.
Puede ocurrir también, que se quiera agregar en un modelo existente algunos objetos Web. En ese
caso, deberá definirse solamente un ambiente Web.
Lo importante es que la interfase elegida (en File / Edit Model / Environment / User Interface) sea
Web form. De esta manera se podrán definir en GeneXus los objetos para desarrollar aplicaciones
Web (Web Panels y Transacciones Web).
En modelos de Prototipo o Producción con ambiente Web, el tipo de objeto que se propone al crear
un nuevo objeto es Web Panel.
Práctico: Creación de una base de conocimiento
1. Entraremos a GeneXus y crearemos una base de conocimiento para comenzar el desarrollo del
sistema para la Agencia de viajes.
Le sugerimos que utilice la versión de GeneXus 9.0 y cree su propia base de conocimiento en el
directorio que estime conveniente. Esta base de conocimiento será la que utilizará a lo largo del curso,
tanto para reproducir las demos, como para hacer los ejercicios prácticos que se vayan indicando.
4. Al realizar el impacto, GeneXus nos informará de las nuevas tablas que creará en la base de datos.
Confirme y ejecute dicha creación.
5. Ahora, está en condiciones de copiar los datos que se encuentran en Agency.bak del cd1.
6. Ahora, deberemos especificar y generar todos los objetos. Para confirmar que todas las propiedades
del modelo quedaron bien configuradas, conviene ejecutar un objeto del modelo.
7. Compile el Developer Menu2 y ejecute por ejemplo la transacción Country.
8. Se recomienda utilizar un directorio virtual específico para el práctico. Por ejemplo:
http://localhost/practico. De esta forma estamos definiendo un directorio virtual específico para
nuestra aplicación y evitando tener un único directorio virtual para distintas bases de conocimiento
activas.
Se entiende que el alumno cuenta con conocimientos en GeneXus por lo cual los pasos aquí descriptos
son sencillos y no requieren del apoyo de un video para llevarlos a cabo.
1
El archivo Agency.bak, es un Back up de la base de datos. Para poder copiar los datos deberá realizar un
Restore de la base de datos Agency.
2
El Developer Menu implementado para aplicaciones Web, al ejecutarlo desde el menú de GeneXus
Build/Run (F5), abrirá una página en el navegador: <VirtualDirectory>/execute.xml. La misma
tiene links a todos los objetos Web, estos son: Web Panels, Transacciones con Web form, Procedimientos con
call protocol = http y Reportes con call protocol = http.
Editor de Objetos Web
Para editar los objetos Web se cuenta con un editor “WYSIWYG” (What you see is what you get)
similar al Front Page de Microsoft, que fue diseñado siguiendo el estándar de las herramientas
Microsoft Office, lo que permite que los usuarios puedan utilizarlo rápidamente y en forma intuitiva.
Es un editor orientado a páginas, lo que significa que la posición de los controles que se encuentran
dentro del form en diseño es relativa al tamaño de la ventana que contenga la página.
Este editor provee el manejo de tablas, característica fundamental a la hora de diseñar páginas Web.
Esta facilidad habilita al usuario a diseñar mejores páginas, así como le permite manipular la
alineación de los controles dentro de los objetos Web.
Complementando este editor, existe el Editor de Temas (que veremos más adelante), que permite
configurar de una forma sencilla las propiedades de estos controles (definiendo clases para los
mismos), simplificando así el desarrollo y mantenimiento de las aplicaciones Web.
Podemos clasificar los controles que se pueden utilizar dentro de los objetos Web en dos grupos:
Atributos
Variables
Botones
2. Los que son propios de los objetos Web, o tienen un comportamiento diferente que en el resto
de los objetos:
Imágenes
Grid
Texto
Text Block
Tabla
Error viewer
Web Components
Embedded Pages
Para trabajar con objetos Web se dispone de dos barras de herramientas: una habilita las
funcionalidades del editor, mientras que la otra permite la inserción de los controles. A continuación
se documentan las operaciones que se pueden realizar con cada una de ellas, así como las
características de los controles disponibles en objetos Web.
Para insertar controles en el form del objeto Web se puede utilizar la opción Insert del menú de
GeneXus o la barra de herramientas denominada Pallete.
Attribute
Text
Table
Grid
Button
Image Inserta una imagen en el Web form. Se
despliega un diálogo, desde el cual se
selecciona la imagen a insertar.
Web Component
Embedded Page
Esta barra de herramientas permite realizar las operaciones estándares de edición y formateo de
texto.
Una de las opciones destacables relacionada con objetos Web es , que permite visualizar los
bordes de las tablas cuya propiedad Border esté con valor 0. De esta forma, se pueden ver en diseño
los bordes de las tablas aún cuando éstos no se vean en ejecución.
Otra opción interesante es que facilita el trabajo con controles de tipo Text Block.
Cuando se visualiza el form de un objeto Web, se pueden observar varias secciones en el borde
inferior de la pantalla, entre ellas el ‘Web Form’.
Si se presiona el botón derecho del mouse dentro del formulario del objeto Web, además de la
opción Properties (que permite configurar las propiedades del form) se visualizan dos opciones:
‘View Source’ y ‘Edit HTML Source’.
Al seleccionar la opción ‘View Source’ se abre una ventana donde se puede visualizar el código
HTML que se va a generar al ejecutar dicho objeto. Al cerrarla, se vuelve al formulario del objeto
Web.
Si se selecciona la opción ‘Edit HTML Source’, se puede modificar el código HTML o agregar código,
de forma tal que el cambio se mantiene en el objeto y se genera posteriormente. En este caso, el
código se visualiza dentro de la ventana del objeto Web y para volver al formulario, es necesario
volver a presionar el botón derecho del mouse y seleccionar la opción ‘Edit Web Form’.
La opción “Edit HTML Source” se usa para cualquier caso en el que sea necesario agregar código
HTML manualmente, por ejemplo, agregar código javascript (si bien esto se puede hacer de otras
formas). Todo el HTML que se agregue queda entre los Tags <Body></Body> del objeto generado.
Normalmente, se diseña el objeto Web sin requerir editar el código HTML, pero en caso de
necesitarse esta es la forma de hacerlo.
En este capítulo iremos viendo los diferentes controles de los objetos Web y las propiedades de cada
uno de ellos.
Esta asignación puede hacerse en tiempo de diseño y para algunas de las propiedades pueden
modificarse en tiempo de ejecución (programando los eventos del objeto). Cualquier cambio,
requerirá generar y compilar el objeto.
En este capítulo se verá una introducción al objeto Tema y el Editor de Temas, y más adelante en el
curso, se verá en detalle el funcionamiento de ambos.
Por detalles de la forma de asignar las propiedades de los controles, referirse a: Orden de
precedencia de las propiedades
¿Qué es un Tema?
Un Tema es un objeto GeneXus, mediante el cual se pueden definir clases para los diferentes
controles Web GeneXus, y asignar propiedades a dichas clases.
Una vez asociado un Tema a un objeto (mediante la propiedad “Theme”), los controles de ese objeto
podrán ser asociados a alguna clase del Tema.
Al asociar una clase a un control éste pasa a heredar la configuración de las propiedades dada en la
clase.
Los Web Panels y las Transacciones son los objetos a los que se les puede asignar un Tema.
Cómo asociar un tema a un objeto
Las formas de asociar un tema a los objetos GeneXus son tres: asignarla a nivel de la base de
conocimiento, del modelo o específicamente del objeto. Este es el orden también para la
precedencia: si está asignada a nivel de objeto, se considera ese valor, sino el del modelo y si no está
asignado, el de la base de conocimiento.
Para asociarlo al objeto directamente, se debe configurar la propiedad Theme perteneciente a las
“Object Properties”.
Para asociarlo al modelo, se debe configurar la propiedad “Theme” disponible en el grupo “Web
Information” (File / Edit Model / Properties).
Para asociarlo a la base de conocimiento, se debe configurar la propiedad Theme del modelo de
diseño (File / Edit Model / Properties / Theme)
Este mismo orden de precedencia se utiliza para determinar los valores por defecto de la propiedad
“Theme”: el valor por defecto de la propiedad de un objeto es el valor de la propiedad del modelo y
el del modelo es el valor de la misma propiedad de la base de conocimiento.
La propiedad Theme del modelo, está asociada por defecto al Tema “Default”, por lo cual, por
defecto los objetos de la base de conocimiento están asociados al mismo Tema.
La forma de asociar una Clase de un Tema a un control, es a través de la propiedad “Class”. La propiedad
Class es una propiedad del control, y es posible también cambiarla en tiempo de ejecución.
Los temas se modifican utilizando un Editor especial, que es de libre distribución y puede ser
ejecutado independientemente de GeneXus. Esto permite a los diseñadores del sitio Web trabajar
en el diseño del sitio en forma independiente al ambiente GeneXus.
Los controles ‘Text Block’ pueden ser vistos como texto insertado directamente en el form, con la
ventaja que en forma dinámica (en ejecución) se puede modificar el mismo. Para insertar un Text
Los text blocks no pueden ser editados directamente desde el form y tienen que ser modificados
desde las propiedades del Menú contextual (botón derecho, properties).
En la barra de herramientas para el form HTML se incluye un botón que facilita el trabajo con
controles de tipo Text Block. Al presionar el botón mencionado, se visualizan los TAG’s que lo
definen permitiendo detectar cualquier problema en diseño.
Caption
ControlName
Class La propiedad Class solo se encuentra disponible si el control está en el form de un objeto
que tiene un Tema asociado.
Format: El valor por defecto para Text Blocks es Text, y se puede cambiar a través de la
propiedad “Default HTML Format(Textblocks only)” del modelo de diseño.
Fill
ForeColor
Font
OnClickEvent
ReturnOnClick
BackColor
Visible
Enabled
Link
LinkTarget
Format
Además de estas propiedades mencionadas, en la clase Textblock (o alguna clase derivada de ella) de un
Tema, se pueden configurar otras propiedades para los Text blocks. Ver Clase Textblock.
Comenzaremos creando un Web Panel donde el usuario deberá registrarse. El nombre del objeto
será Login.
En este objeto, le pediremos que ingrese un usuario y una contraseña y validaremos la información
con la base de datos donde se almacenan los usuarios registrados en el sitio.
Para que pueda ingresar un valor para el usuario y la contraseña, definiremos dos variables en el
form.
Para que no se visualice lo que escribe mientras ingresa la contraseña, es decir, que aparezcan
asteriscos, se debe utilizar la propiedad “IsPassword” asociada a las variables.
Si observamos bien el Web Panel, las variables de ingreso de datos no están alineadas.
Para alinear controles (por ejemplo: que todas las variables donde el usuario va a ingresar los datos
queden alineadas a la izquierda), se deben usar Tablas.
Vale la pena destacar que si las dos variables se insertan al mismo tiempo (desde el diálogo
correspondiente) GeneXus automáticamente incluye una tabla para alinear los controles.
En el próximo punto veremos cómo alinear los controles del Web Panel insertándolos dentro de una
tabla.
Pero antes de eso, realicemos algunos cambios en el Tema para verificar los conceptos aprendidos
recientemente.
Demo: Trabajando con Temas
Observe que en la base de conocimiento que Ud. ha creado para realizar los ejercicios prácticos,
existe un Tema de nombre “Default”. Este Tema se crea automáticamente al crear una nueva base
de conocimiento.
Observe también que la propiedad “Theme” del modelo, está asociada por defecto al Tema
“Default”, por lo cual, por defecto los objetos de la base de conocimiento están asociados al mismo
Tema.
Ahora, modificaremos el Tema “Default”, de forma de ejemplificar como se trabaja con los Temas.
En la siguiente demostración veremos los pasos seguidos para modificar el Tema “Default” y el
efecto de esos cambios sobre el Web Panel que hemos creado en este capítulo.
Es posible también definir la configuración de los HTML Tags involucrados en el HTML de la Web
Page. En el curso, a medida que se vayan realizando los ejercicios prácticos, se explicarán más
detalles del objeto Tema y su funcionalidad, incluyendo casos de uso de los HTML Tags, y las
ventajas que presenta a la hora de realizar el diseño estético del sitio Web.
Tablas
Cuando se trabaja con objetos web, es necesario utilizar tablas para poder alinear los controles
dentro del formulario para mejorar el diseño de los mismos.
Agregar tabla
Para insertar una tabla se debe utilizar el botón de la barra de controles. Una tabla está
compuesta por filas y celdas, dentro de las que se encuentran los controles.
Las propiedades varían dependiendo de la selección realizada, es decir que las propiedades
disponibles para una celda tienen alguna variación con respecto a las disponibles para la tabla o la
fila. A continuación se documentan las propiedades a nivel de tabla, fila y celda.
Para editar las propiedades de una tabla se debe marcar la tabla (el puntero del mouse cambiará al
posicionarse en los bordes de la misma y en la barra de status se indicará el nombre del control
seleccionado) y presionar el botón derecho del mouse. Seleccionar la opción Properties del menú
pop-up que se despliega.
Otra forma de editarlas es presionando el botón derecho del mouse estando posicionado en
cualquier celda de la tabla, y después ir a la sección de Table. En este caso, se podrán editar además
de las propiedades de la tabla, las de la fila a la que pertenezca la celda y las propias de la celda.
ControlName
Class
La propiedad Class solo se encuentra disponible si el control está en el form de un objeto
que tiene un Tema asociado.
Tooltiptext
Align
Background
Backcolor
BorderWidth: 0 indica que no tendrá borde en ejecución, pero podrá verse en diseño usando el
Cellpadding
Cellspacing
Height
Width
Rules
Como se puede observar en el diálogo de propiedades –sección ROW-, se pueden asignar valores a
propiedades para una fila particular dentro de las tablas. Estos valores tendrán preferencia a los
asignados para la tabla en general.
Las propiedades de las filas, son algunas de las propiedades de las tablas, más una propiedad
adicional: Vertical Align.
Identifier
TooltipText
Align
Vertical Align
Backcolor
BorderColor
Tooltiptext
Align
VerticalAlign
Background
Backcolor
Bordercolor
Height
Width
Colspan
Rowspan
Como decíamos anteriormente, para alinear los controles debemos definir una tabla en el form.
Podríamos también, seleccionar nuevamente las variables para que GeneXus automáticamente
agregue la tabla con las variables y las descripciones correspondientes.
Luego, debemos posicionar el Mouse en la última celda y con el botón derecho seleccionar la opción
Insert Row para agregar una nueva fila donde incluiremos el botón.
Más adelante, veremos más casos prácticos del uso de las tablas.
En este momento ya tenemos implementada nuestra pantalla donde el usuario final va a ingresar su
usuario y contraseña.
Tenemos que verificar en el evento Enter del botón “Login” si existe en nuestra tabla de usuarios
(Users) un usuario con dicho Nick Name. Si existe, verificar que la password ingresada sea correcta y
en caso de no existir darle un mensaje al usuario final informándole que se debe registrar como
nuevo usuario.
En un Work Panel normalmente lo haríamos utilizando el comando msg(), y se abriría una nueva
ventana con el mensaje. En los objetos Web utilizamos el mismo comando msg(), la diferencia está
en dónde se mostrará dicho mensaje, en una caja de texto y/o en el control Error Viewer (como
veremos más adelante) ya que contamos en Web con las facilidades que nos brinda Ajax.
Volvamos entonces a nuestro ejemplo para hacer el control del usuario y password en el evento
Enter del botón “Login” y agregar el comando msg() para desplegarle al cliente el mensaje que
corresponda.
Diseño (en las propiedades del control mismo, seleccionando el control y con botón
derecho haciendo clic en “Properties”).
El Tema En este último caso se configuran las propiedades en una clase del Tema. La clase
se asocia al control, a través de la propiedad “Class” del mismo. La propiedad “Class” se
puede asignar a un control tanto en tiempo de diseño como en ejecución. Para poder asociar
una clase determinada a un control en tiempo de diseño, es necesario que el Tema en el cual
está definido la clase se asocie al objeto que contiene el control. La asociación de un Tema a
un objeto se hace a través de la propiedad “Theme” del objeto.
El orden de precedencia que se tiene en cuenta para que el control adopte las propiedades
configuradas, es el siguiente:
1. Ejecución
2. Diseño
3. Tema
Es decir que si una propiedad de un determinado control está configurada en el Tema, y también en
diseño; la configuración dada en diseño tiene precedencia sobre la del Tema; y la dada en ejecución
sobre la de diseño.
Se recomienda en general configurar las propiedades a nivel de los Temas, ya que de esta forma se
reduce el costo de mantenimiento del sitio.
Cuando se trabaja con objetos Tema de la base de conocimiento, el Editor de Temas, salva en el
directorio Web un archivo con extensión .CSS (Cascading Style Sheet).
Cambiando el Tema asociado al objeto que se desea modificar, basta con llevar el CSS a producción y
no es necesario generar/compilar nuevamente la aplicación. Esto último sí resulta necesario de
hacer en caso de configurar las propiedades en tiempo de diseño.
Nota: Observar que si un control está asociado a una clase de un Tema, el valor default de las
propiedades del control se corresponde a los valores configurados en la clase.
En el diálogo de propiedades, el valor default se puede identificar con un asterisco negro al lado de
la propiedad:
En el siguiente ejemplo, el control tiene una clase asociada (“Attribute”), sin embargo, la propiedad
“ForeColor”, está configurada a nivel de diseño.
En este caso, el asterisco al lado de la clase se visualiza en color gris (valor no default).
Propiedades del Form
Al form de los objetos Web se le pueden asignar propiedades haciendo clic y seleccionando la opción
Properties del menú.
Las propiedades del form que pueden asignarse son las que se muestran en el siguiente diálogo.
Class: La propiedad Class solo se encuentra disponible si el form pertenece a un objeto
que tiene un Tema asociado.
BackColor
TextColor
Background
Background Properties
TooltipText
WordWrap
ActiveLinkColor
VisitedLinkColor
NotVisitedLinkColor
TopMargin
BottomMargin
LeftMargin
RightMargin
BackColor
Background
Caption: El caption del form se transforma en el título de la ventana. Por defecto, tiene
el nombre del objeto Web. Esta propiedad solamente puede modificarse en tiempo de
ejecución.
Es posible configurar en la Clase Form (o derivadas de ella) en el objeto tema, varias de las
propiedades de los forms disponibles en GeneXus y otras que no están en GeneXus.
En el caso de que una propiedad esté asignada en el control (en diseño o en ejecución) ese valor
tiene precedencia respecto al asignado en el tema. Ver Orden de precedencia de las propiedades.
Por detalles de propiedades del Form en los Temas, referirse a Clase Form.
Atributos y Variables
Al seleccionar un control y presionar el botón derecho del mouse aparecen sus propiedades para ser
modificadas. Esta modificación se considera realizada en tiempo de diseño.
Para modificar las propiedades de estos controles en ejecución, es necesario programarlo en algún
evento del objeto.
Las variables y atributos son controles de tipo Edit, que tienen las siguientes propiedades:
Attribute
Class
Control Type: Las propiedades que se aplican sobre atributos y variables, dependen del tipo
de control que se seleccione. (Ver propiedades según el tipo de control).
Dentro del grupo Appearance se encuentran todas las propiedades que aplican al aspecto
del control. Se detallan a continuación:
Auto Resize: Esta propiedad aplica a controles edit que NO tengan la propiedad Read-Only con el
valor ‘True’, ya que en este caso se ignora el ancho especificado.
Fill
BackColor
ForeColor
Font
Format
Tooltiptext
ReturnOnClick
OnClickEvent
Dentro del grupo Behavior se encuentran todas las propiedades que aplican al
comportamiento del control. Se detallan a continuación:
ReadOnly
EnableHistory
EmptyAsNull
IsPassword
InputType: Esta propiedad permite sustituir lo que el usuario digita en un atributo por un valor más
amigable. Si esta propiedad toma el valor ‘Descriptions’, permite que el usuario digite la descripción
de otro atributo y se habilitan las siguientes propiedades: ItemValues, ItemDescription,
InstantiedAttributes, Conditions. Esto se puede realizar a nivel del atributo para que aplique por
defecto en todos los forms en donde este atributo esté presente como control, o también, es posible
definirlo en forma particular, para un control atributo en concreto de un form determinado. En este
último caso se definirá en el control info de ese control en particular.
Suggest: Posibilita al usuario que elija entre un conjunto de valores posibles (una lista de posibles
valores que se despliega debajo del control) y no tenga que recordar exactamente el valor a digitar.
La lista de sugerencias puede ser calculada de un modo incremental (la lista es actualizada con las
entradas del usuario) o haciendo pedidos explícitos (el usuario manualmente hace un pedido para
que se calculen las sugerencias y se le muestren). La actualización de la lista es asincrónica y los
tiempos de cálculo dependen de la calidad de la conexión. Al tomar los valores Incremental u
OnRequest, se habilitan las siguientes propiedades: ItemValues, InstantiedAttributes, Conditions,
FilterOperator, SortDescriptions, CaseSensitive, SuggestMaxItems. Esto se puede realizar tanto a
nivel del atributo como del control.
Conditions: Permite condicionar los valores sugeridos y/o los valores que puede tomar el atributo
edit.
InstantiedAttributes: Permite filtrar el conjunto de valores dependiendo de otros atributos que no
pueden ser inferidos directamente.
Además de las propiedades vistas anteriormente, existen otras que permiten modificar en tiempo de
ejecución los controles de tipo edit. Las propiedades son:
Backcolor
BackStyle
Enabled
FontBold
FontItalic
FontName
FontSize
FontStrikethru
FontUnderline
ForeColor
Format
InternalName
IsPassword
Link
LinkTarget
Visible
Class
Propiedades según el Tipo de Control
COMBO BOX
Las propiedades a nivel de diseño que aplican son:
Attribute
BackColor
ForeColor
Fill
Font
ReadOnly
Backcolor
BackStyle
Enabled
FontBold
FontItalic
FontName
FontSize
FontStrikethru
FontUnderline
ForeColor
InternalName
Visible
NOTA: Alineación de un combo box/dynamic combo box en grids. Siempre se alinea a la izquierda
independientemente del tipo de datos. Esto se hace así porque aún cuando el combo sea sobre un
atributo numérico los valores que se muestran en el combo son de tipo carácter.
Attribute
BackColor
ForeColor
Fill
Font
Los radio button tienen también la propiedad Radio Direction que permite indicar si las opciones del radio
button se desplegarán en forma vertical u horizontal.
BackColor
BackStyle
Caption
Class
Enabled
FontBold
FontItalic
FontName
FontSize
FontStrikethru
FontUnderline
ForeColor
Height
ImeMode
InternalName
IsPassword
Left
Tag
ToolTipText
Top
Visible
Widht
Las propiedades se pueden configurar también en el Tema. La clase predefinida “Attribute” del Editor de
Temas reúne las propiedades para todos los controles en los cuales se puedan representar atributos/variables
en el form, a saber:
Edit
Combo Box
List Box
Radio Button
Obviamente se pueden derivar clases de la clase predefinida “Attribute”, por más información referirse a
Clase Attribute.
Las propiedades que se detallan a continuación aplican únicamente a variables de tipo bitmap.
Class
Autoresize
Borderwidth
AlternateText
Tooltiptext
Hspace
Vspace
ReturnOnClick
OnClickEvent
A las variables de tipo bitmap se le pueden modificar las siguientes propiedades en tiempo de ejecución:
AlternateText
Borderwidth
Class
Enabled
InternalName
Link
LinkTarget
Tooltiptext
Visible
Vspace
HSpace
Las propiedades de las variables bitmap (y controles imagen), se pueden configurar en los Temas.
Referirse a Clase Image.
Los métodos que aplican a los controles combo box, dynamic combo box, listbox y radio button son:
AddItem
Clear
Removeitem
Repaint
Setfocus
Text
Value
Se formatea lo digitado por el usuario en campos de tipo Date y Datetime. Esto permite, por
ejemplo, que el usuario final digite una fecha u hora sin los separadores ('/', ':', etc.) y se mejore la
"visualización".
El formateo ocurre cuando el usuario "sale" del campo y controla únicamente que el formato sea
correcto. No se controla que la fecha y/o hora sea válida: esto lo hacen los programas.
En caso de que el formato no sea correcto, se emite un mensaje de error (una ventana con el
mensaje 'Date or time format is not correct') y se vuelve el foco al campo incorrecto.
Botones
En los objetos Web se pueden usar varios botones y asociarles eventos (predefinidos de GeneXus o
definidos por el usuario). Al presionar el botón derecho del mouse se visualiza el siguiente diálogo
que habilita al usuario a editar las propiedades del mismo o a editar el evento que el botón tiene
asociado.
Propiedades de botones
Las propiedades de los controles de tipo Button que pueden modificarse en diseño son:
ControlName
Class
OnClickEvent
Caption
Font
ForeColor
BackColor
BorderWidth
BorderColor
En ejecución se pueden modificar todas estas propiedades (excepto la control name) del botón y además
las siguientes:
Enabled
Internal Name
Visible
Además de estas propiedades, en la clase Button de un tema se pueden setear otras propiedades que
permiten definir otras características a los botones. Ver Clase Button.
Tamaño de botones
El tamaño del botón queda determinado por el texto ingresado en la propiedad Caption del mismo.
Si se desea que los botones tengan un tamaño fijo, se deben asociar mediante la propiedad Class a
una clase de un tema que tenga un tamaño definido (propiedades Heigth y Width). En este caso, el
tamaño quedará fijo independientemente del caption.
Para asignar un evento a un botón se puede ingresar directamente el nombre del evento (entre comillas
simples) o hacer clic al botón . Al utilizar este selector de eventos se visualiza el siguiente diálogo, con
los eventos disponibles, habilitando al usuario la creación un nuevo evento (mediante el botón New).
INTRODUCCIÓN
Los web panels al igual que los work panels son objetos GeneXus que permiten al usuario en tiempo
de ejecución, realizar interactivamente consultas a la base de datos a través de una pantalla.
Los web panels no permiten la actualización de la base de datos, sino sólo consultarla.
El objetivo primordial de los web panels es la definición de consultas interactivas a la base de datos,
sin embargo se trata de un objeto muy flexible por lo que se presta para diversos usos más.
En este capítulo estudiaremos todos los detalles acerca de los web panels y los compararemos con
los work panels para establecer las similitudes y diferencias.
Cuando un Web Panel es invocado desde otro objeto, y se requiere que reciba uno o más
parámetros para filtrar por igualdad por los mismos, la forma más directa y sencilla de resolverlo es
declarando en la regla parm del objeto, a dicho(s) parámetro(s) por los cuales se necesita filtrar por
igualdad, como atributo(s). (PIE 1)
Es decir, si por ejemplo un web panel exhibe las facturas de un cliente, y se requiere que reciba por
parámetro el código del cliente del cual se deben mostrar sus facuras, la opción más directa y
sencilla para definir el filtro es en la regla parm, recibiendo al código de cliente en el atributo
mismo: parm(CliCod);
De esta forma, GeneXus entenderá automáticamente que el atributo CliCod actuará como filtro por
igualdad en todo el objeto (es decir, que será un filtro global).
Otra alternativa posible, es recibir en la regla parm a una variable y luego definir una condición de
filtro: CliCod=&CliCod; Recordemos que cuando se reciben variables en la regla parm, GeneXus no
hace nada automáticamente con ellas, por lo tanto el analista deberá definir condiciones de filtro
explícitamente utilizando a las variables como desee.
Cuando en cambio, se trata de web panels que no reciben parámetros, y que las condiciones de
filtro deben definirse explícitamente (por ejemplo involucrando a variables cuyos valores son
ingresados por el usuario en tiempo de ejecución en la parte fija del web panel) habrá que decidir si
definir condiciones globales o condiciones a nivel de un grid en particular. (PIE 2)
Las opciones para definir filtros son las mismas en web panels y en work panels
En los web panels se utiliza la programación dirigida por eventos, que es un estilo de programación
en el cuál se define código que permanece ocioso, hasta que suceden eventos provocados por el
usuario o por el sistema, que provocan que el código definido se ejecute.
Los eventos son acciones reconocidas por un objeto que pueden suceder o no. A cada evento se le
puede asociar código, que se ejecutará solamente si el evento se produce.
El código que se le puede asociar a un evento, se escribe con estilo procedural; y cuando el evento
se produce, el código asociado al mismo se ejecutará secuencialmente.
Eventos existentes en Web Panels
Evento Start
Evento Refresh
Evento Load
Evento Enter
Eventos de Usuario
En primera instancia explicaremos cada uno de estos eventos conceptualmente y en qué momento
exacto se ejecutan, y a lo largo del curso veremos varios ejemplos de utilización de los mismos.
Para definir en un web panel que una consulta se efectúe ordenando por cierto(s) atributo(s), y por
ende que los datos extraídos de la consulta se muestren ordenados con dicho criterio, se debe hacer
clic con el botón derecho del mouse sobre el grid, y seleccionar el ítem Order en el siguiente menú
pop up:
A continuación, se presentará el siguiente diálogo para que se ingrese por qué atributo(s) se desea
ordenar:
Definir esto es equivalente a definir la cláusula order en el comando for each , por ejemplo: que
para ordenar en forma descendente por un atributo se debe encerrar al atributo entre paréntesis (),
o que se crean índices temporales cuando no existe un índice físico por los atributos por los cuales se
indica ordenar.
Solamente si el form del web panel no tiene ningún grid, y se necesita definir un orden específico para la
consulta, se contará con la posibilidad de definir en la sección de reglas del web panel, la regla de sintaxis:
order(att1, att2, attN); siendo att1, att2, attN: la lista de atributos que define el orden de la consulta.
En el objeto work panel, las reglas más utilizadas son las siguientes: Order, Noaccept, Search,
Hidden, Workfile_lines y default.
Estas tres reglas se utilizan de la misma forma en los work panels que en los web panels.
Cuando se quiere usar la regla Hidden para atributos de un grid, se recomienda en lugar de eso, utilizar la
propiedad de Visible. El valor de los atributos / variables de la regla hidden se "guarda" para cada línea de
cada grid que exista en la pantalla. Los atributos con Visible en False, no se ven en el grid final pero también
se "guardan" aunque solamente para cada línea del grid en el que fueron definidos. Se sugiere que se
promueva el uso de los atributos con Visible en False para el desarrollo de aplicaciones en lugar de la regla
hidden. La causa de esto es que los hiddens se mandan en todos los grids mientras que los otros sólo para el
grid en que fueron definidos. Esto redunda en menos código HTML a enviar al Browser y, en consecuencia,
mejor performance.
Algo similar ocurre con la regla Order, ya que en caso de tener múltiples grids definidos en el objeto
se recomienda usar la propiedad a nivel del grid y no la regla ya que se estará indicando
concretamente a cual de los grids deberá aplicarse el orden.
Workfile_lines
Esta regla no aplica a los web panels ya que no existe una tabla temporal para almacenar el resultado de una
consulta a la base de datos. La forma de hacer esto en web panels es usando la propiedad Rows del grid.
Default
Esta regla asigna un valor por defecto a una variable (definida en el objeto). El valor puede ser un literal
entre comillas, un número o una de las funciones Today(), Date() o SysDate(), debiendo coincidir el tipo de
datos del valor con el tipo de datos de la variable.
A continuación se detallan los comandos soportados por los Web Panels y las transacciones con
interfaz Web.
Call
El comando Call no presenta grandes diferencias con respecto al resto de los objetos GeneXus.
Es importante tener en cuenta que los objetos web ejecutan en el servidor y por consiguiente no
pueden realizar llamadas a programas que tengan salida en pantalla, ya que la ejecución de dicha
llamada cancelaría por time-out. En resumen, desde un objeto web, se puede llamar a otro objeto
web, a un procedimiento o reporte que no tengan salida en pantalla.
Link
El comando link es equivalente al comando call para llamar a páginas estáticas o redireccionar a una
URL. Este comando puede ser utilizado dentro de cualquier evento de un objeto web con excepción
del evento Load. El resultado de la utilización de este comando es el redireccionamiento en forma
automática a la URL especificada dentro del mismo.
Sintaxis:
Donde:
usr-pgm
url
parm
Ejemplo:
Event ENTER
Link(‘http://www.ARTech.com.uy’)
Endevent
Load
El comando Refresh vuelve a cargar la página, teniendo el mismo efecto que presionar la tecla de
función F5 del browser. La página se cargará manteniendo los últimos valores sometidos para las
variables ingresadas por el usuario.
Return
Incluir el comando return en un objeto web, es equivalente a hacer un CALL al objeto que lo invocó.
En consecuencia no equivale a presionar el botón ‘Back’ del browser, ya que si se ingresaron valores
en variables del objeto web llamador, los mismos no son mantenidos al ejecutar el comando Return.
Este comando Return puede ser ejecutado en cualquier evento o subrutina del objeto, salvo el evento Load y
los métodos Load de las grillas. Tampoco puede ser ejecutado en subrutinas llamadas directa o
indirectamente por el evento Load o métodos Load de las grillas. En caso que se ejecute en las mencionadas
situaciones los resultados son impredecibles.
Si se utiliza el método Set en un tipo de datos WebSession y luego se ejecuta el comando Return el valor de
la(s) cookie(s) se establece correctamente.
Se puede decir que los objetos Web Panel y Work Panel de GeneXus son similares ya que ambos
permiten definir consultas interactivas a la base de datos. Son objetos muy flexibles que se prestan
para múltiples usos, cuya programación está dirigida por eventos. De todos modos, hay algunas
diferencias causadas principalmente por el esquema de trabajo en Internet.
Tabla Base
La determinación de la tabla base de los Web Panels es análoga a la determinación de los Work
Panels.
Eventos
Los eventos de los Web Panels son los mismos que en los Work Panels, es decir evento Start,
Refresh, Load, Enter y los definidos por el usuario. La diferencia con los Work Panels es el orden de
disparo de estos eventos. Esto está relacionado con el esquema de trabajo en Internet.
Variables
Como se menciona en el documento Esquema de trabajo en Internet, las variables adquieren los
valores ingresados por el usuario después de presionar algún botón en el objeto web.
Por ejemplo, cualquier link a otro objeto web especificado en el evento Start con una variable que se
ingresa en un Web Panel no va a tener ningún valor cuando se haga clic sobre el link.
Si en un evento se usa una variable que se carga en otro evento, entonces esa variable debe estar
presente en el form. Si no está en el form, la variable no tendrá valor cuando se disparan los otros
eventos (esto es por el “orden” en que ocurren los eventos).
Además, deberá estar en el form después del control en el que se carga la variable. Por ejemplo, si la
variable se carga en el Evento Load de una grilla entonces la variable tiene que estar en pantalla
después de la grilla.
En un Web Panel existen fórmulas que pueden ser gatilladas antes del evento Start y otras que
deben gatillarse luego del mismo evento.
Las fórmulas que se gatillan antes del evento Start son aquéllas que sólo dependen de los
parámetros que llegan al programa (mediante la regla parm())
Las fórmulas que se gatillan después del evento Start son aquéllas que dependen de atributos o
variables instanciados (vía asignación, Call, etc.) en el evento Start.
Propiedades
En los Work Panels las propiedades más utilizadas son las correspondientes al grupo Loading (Load
Records, Load at Startup, Automatic Refresh y When to Refresh) para manipular la visualización de
grandes cantidades de registros.
En los Web Panels con tabla base la carga de los registros se realiza de una sola vez (lo que se
corresponde con el valor Load all records de la propiedad Load Records) y la grilla se carga por
primera vez inmediatamente a continuación de la apertura del form en tiempo de ejecución (lo que
se corresponde con el valor Yes de la propiedad Load at Startup).
En las grillas de los objetos Web para resolver la visualización de grandes cantidades de registros se
dispone de la paginación automática.
El Web Panel es “con tabla base” cuando a lo sumo tiene un grid y GeneXus puede determinar un for each
implícito asociado a él.
Para determinar si un Web Panel tiene tabla base y en caso afirmativo cuál será, al momento de especificarlo
GeneXus analiza los atributos incluidos en:
Cuando un Web Panel contiene más de un grid en su form, GeneXus no determina una única tabla
base asociada, sino una tabla base asociada a cada grid.
Los incluidos en el grid (se tienen en cuenta tanto los atributos visibles como los no
visibles)
Los referenciados en Order y Conditions locales al grid
Los atributos de la parte fija del Web Panel no participan en la determinación de la tabla base de
ninguno de los grids, pero deberán pertenecer a la tabla extendida de alguno de ellos (para que sea
posible inferir sus valores). De no respetarse esto, al especificar al Web Panel, se mostrará en el
listado de navegación resultante, un warning advirtiendo de esta situación.
Los atributos utilizados en los eventos del Web Panel tampoco participan en la determinación de la
tabla base de ninguno de los grids. Los atributos que se incluyan en los eventos fuera de comandos
for each, deberán pertenecer a la tabla extendida de alguno de los grids (al igual que los de la parte
fija).
Demo: Web Panel Principal del Sitio
Comenzaremos a desarrollar el Web Panel principal del sitio donde el usuario va a poder buscar las
atracciones turísticas y los servicios provistos de una ciudad como también los vuelos que arriban a
la misma. El nombre del objeto será MainSearch y como será el punto principal de entrada de
nuestro sitio lo definiremos como objeto Main asignando a la propiedad “Main” en “True”.
Las Transacciones que ya están definidas en este sistema son las siguientes (se describen solo los
principales atributos de las mismas)
CityId
(TourismServiceCatTypeId*
TourismServiceCatTypePrice)
ArrivalCityId TourismServiceCatTypeDsc)
(FlightCategory
FlightPrice)
Users
UserId*
UserNickName
UserPwd
UserLastName
UserFirstName
UserName
UserEmail
UserAddress
UserPhone
CountryId
CountryName
CityId
CityName
Allí programaremos la paginación a pedido en los grids, cargando 5 registros a la vez y pudiendo
filtrar por país y ciudad. En cada grid, pondremos links a otros Web Panels con información más
detallada.
Para hacer esto crearemos dos variables en la parte fija del Web Panel, donde el usuario indicará los
filtros correspondientes para el país y la ciudad (&CountryId y &CityId).
Estas variables las definiremos basadas en los atributos para que “hereden” los tipos de datos de los
mismos.
Buscando que la interfaz sea amigable para los usuarios, se sugiere que el ingreso de datos sea
simple y rápido.
Para esto, se recomienda que los usuarios no deban ingresar (¡ni recordar!) códigos sino que puedan
ingresar los nombres y que el diálogo les sugiera valores posibles a medida que digitan.
Para esto, definiremos las variables como dynamic combo box con filtros.
Definiremos que &CountryId sea un combo dinámico. Los valores posibles serán el atributo
CountryId y las descripciones serán el nombre del país (CountryName).
Además, utilizaremos un valor vacío que indique que no está seleccionado ningún país. Para esto,
asignaremos a la propiedad “EmptyItem” el valor “Yes” y el texto será “Select a Country…” (se
configura en la propiedad EmptyItemText).
Lo mismo haremos con la ciudad. Para eso definiremos &CityId también como combo dinámico con
un valor vacío de texto “Select a City…”.
Recordar que al seleccionar más de un atributo, GeneXus crea una Tabla para alinear los
controles. Sin embargo, el orden elegido no será el deseado por lo que deberán moverse los
controles.
Para que el combo muestre las ciudades del país elegido previamente, es necesario definirle una
condición por el país.
La condición será:
CountryId = &CountryId;
Podemos ejecutar el Web Panel que hemos desarrollado para ir probando la funcionalidad.
Cuando se desea que todos los combos dinámicos de la base de conocimiento muestren el
mismo valor en ejecución para el valor vacío, se deja el valor GX_EmptyItemText propuesto en la
propiedad EmptyItem. Este texto aparecerá como código en el Objeto Lenguaje para que pueda
ser traducido. El texto propuesto es “(None)” cuando el idioma lenguaje es inglés.
Lo mismo ocurrirá si se asigna un valor específico a esta propiedad a nivel del control o del atributo.
En este caso, ese texto será una nueva entrada en los códigos del objeto Lenguaje.
Recuerde que es necesario especificar el objeto antes de que aparezcan los códigos en el objeto
Language.
¿En qué momento se ejecuta? Cuando comienza la ejecución del programa asociado a un web
panel, es decir, ni bien se abre un web panel en tiempo de ejecución.
¿Cuántas veces se ejecuta? Una vez cuando comienza la ejecución del web panel y tantas veces
más como ejecuciones de eventos de usuario se realicen que no incluyan una invocación a otro
objeto web.
En el evento Start no se conocen valores de atributos, salvo los recibidos por parámetro. Esto se
debe a que aún no se ha efectuado la consulta.
El Evento Start de un work panel se ejecuta una vez sóla cuando comienza la ejecución del
mismo.
Cuando el usuario presiona el botón Refresh en un web panel se ejecuta el evento Refresh.
A su vez, cuando el usuario pasa de la parte fija del web panel al grid, también se ejecuta el evento
Refresh.
Y cuando se ejecuta el comando Refresh incluido por el analista GeneXus en algún evento, también
se ejecuta el evento Refresh.
El evento Refresh es un evento del sistema que a continuación de ejecutarse, causa que se ejecute
la consulta a la base de datos. Es decir, al ejecutarse el evento Refresh, se ejecuta el código
asociado al mismo, y a continuación se ejecuta la consulta a la base de datos. Seguidamente, se
ejecutará el evento Load.
El Evento Start de un work panel se ejecuta una vez sóla cuando comienza la ejecución del
mismo.
Evento Load (de Web Panels)
Cada vez que se ejecute el evento Refresh en un web panel, seguidamente a la ejecución del mismo,
se ejecutará el evento Load.
La cantidad de veces que se ejecutará el evento Load, dependerá de si el web panel tiene tabla base
o no tiene tabla base.
De modo que por cada registro leído en la consulta efectuada a la base de datos, se ejecutará el
evento Load (ejecutándose el código incluido en el mismo, y cargándose a continuación una línea en
el grid con los datos del registro).
Que el web panel no tenga tabla base, significa que no tiene un for each implícito asociado; por lo
tanto, cuando se ejecute el evento Refresh, no comenzará a ejecutarse ninguna consulta; se
ejecutará el código asociado al evento Refresh, y a continuación se ejecutará el código asociado al
evento Load, una sola vez.
Cuando se inserta un nuevo botón en el form de un Web Panel, por defecto aparece con el Caption
“Confirm” y aparece asociado al evento del sistema Enter.
El evento Enter puede asociarse a cualquier botón, atributo, imagen, text block, en la propiedad de
los controles: OnClickEvent.
De modo que si se necesita ejecutar acciones cuando el usuario final haga clic en el control asociado,
en este evento deberán codificarse.
Además de los eventos ofrecidos por GeneXus, el analista puede definir eventos creados por él, los
cuales reciben el nombre de eventos de usuario.
Cada evento de usuario debe asociarse a un control insertado en el form del web panel de los que
soportan el OnClickEvent (botones, text blocks, imágenes, atributos).
En tiempo de ejecución, el evento de usuario ocurrirá luego de que el usuario haga clic sobre el
control asociado al mismo. Se consigue de dos maneras distintas:
…
EndEvent
Event nombreControl.click
Endevent
Con esta última alternativa no tendremos que definir un evento de usuario, sino que estaremos
programando el evento clic del control.
Esquema de trabajo en Internet
Es importante entender que en Internet, cuando el usuario accede a una página del servidor Web
para visualizarla, el Browser baja la página al cliente. Por lo tanto, no existe forma de detectar lo que
realiza el usuario: el Servidor Web volverá a tener el control cuando se dispare el evento Enter o
algún evento de usuario. En ese momento se envía (o se somete, se hace un post) el resultado al
servidor para continuar con su procesamiento. Es decir, una vez que el objeto web finaliza la
ejecución en el servidor, no queda en memoria. Como consecuencia, la forma en que programamos
este tipo de aplicaciones presenta algunas diferencias con respecto a lo acostumbrado en ambientes
no web.
Es por esta razón importante destacar el orden en que se disparan los eventos y el momento en que
las variables adquieren el valor ingresado por el usuario.
El orden de ejecución de los eventos en web panels es diferente si se trata de la primera llamada al
mismo (GET) o si se disparó algún evento de usuario o enter (POST).
2. Evento Refresh
3. Evento Load
Luego de esto, cuando se ejecuta el evento Enter o un evento de usuario que no llame a ningún otro
web panel (ya sea porque el usuario presionó un botón o dió clic en algún control del form con el
evento Clic programado), se ejecutará nuevamente éste y el orden de disparo de los eventos será
diferente.
4. Evento Refresh
5. Evento Load
Relacionado con esto es importante destacar el momento en que las variables adquieren los valores
ingresados por el usuario: solamente lo harán después de ejecutar un evento (presionar un botón),
que es cuando el servidor Web tiene el control del procesamiento.
Por ejemplo, cualquier link a otro web panel especificado en el Evento Start con una variable que se
ingresa en el web panel no va a tener ningún valor cuando se haga clic sobre el link.
Si en un Evento se usa una variable que se carga en otro evento, entonces esa variable debe estar
presente en el form. Si no está en el form, la variable no tendrá valor cuando se disparan los otros
eventos (esto es por el “orden” en que ocurren los eventos).
Además, deberá estar en el form después del control en el que se carga la variable. Por ejemplo, si la
variable se carga en el LOAD de un grid entonces la variable tiene que estar en pantalla después del
grid.
Si el evento que se ejecuta llama a otro web panel, comenzará a ejecutarse ese objeto,
disparándose los eventos del mismo según lo descrito antes en la primer Ejecución de los web
panels.
En HTML se puede especificar dos métodos distintos para someter un formulario. El método
se especifica dentro del elemento HTML “FORM”, usando el atributo “METHOD”, por ejemplo:
Las especificaciones HTML definen técnicamente la diferencia entre GET y POST de la siguiente
forma:
En el GET, los datos del form son codificados por el browser en la URL misma.
Entonces, cuando es METHOD="GET" los datos del form se codifican en una URL (o mas
genéricamente en una URI), lo cual significa que esa forma de someter el form es equivalente a
seguir un link a la URL codificada.
En general, el GET es para recuperar datos mientras que el POST sería para grabar, actualizar datos,
ordenar un producto, etc..
En GeneXus todos los eventos se resuelven con un POST y se ejecutan en el servidor Web.
Demo: Esquema de Trabajo en Internet
Aunque decimos que los web panels son similares a los work panels, hay una diferencia fundamental entre
ellos relacionada con el hecho que el objeto web una vez que finaliza la ejecución, no queda en memoria.
Como consecuencia, la forma en que programamos este tipo de aplicaciones presenta algunas diferencias con
respecto a lo acostumbrado en ambientes no web.
Es por esta razón que es importante tener claro el orden de ejecución de los eventos. Ejemplifiquemos esto,
programando nuestra aplicación.
Supongamos que en el evento donde validamos el usuario y la contraseña (en el web panel Login),
guardamos en una variable el código de usuario para poder utilizarlo en otro evento. Esto nos permitiría, por
ejemplo, llamar a un objeto que permita visualizar los datos del usuario.
Event ‘Login’
for each
if UserPwd = &UserPwd
&UserId = UserId
else
login.Visible = 1
endif
when none
login.Visible = 1
endfor
Endevent
Para realizar la llamada al web panel Perfil del Cliente (UserProfile), existen varias alternativas: se puede
definir un link en algún evento, o se puede agregar un botón y en el evento asociado invocar al objeto.
Si agregásemos un botón o una imagen con un evento clic asociado, entonces el código seria el siguiente:
Event profile.clic/profile
Call(HUserProfile,&UserId)
Endevent
Otra alternativa (la que vamos a implementar en este caso), es usar un control textblock y hacer el llamado
al webpanel en el evento clic del textblock.
1. En la primer ejecución se disparan los eventos: Start, Refresh y Load y podemos ingresar el usuario y
password.
2. Cuando presionamos el botón para validar el login, se asigna a la variable &UserId el código de
usuario correspondiente.
3. Cuando presionamos la imagen con el evento clic asociado, se dispara el evento Start, se leen las
variables que están en pantalla, se ejecuta el evento clic y ahí cuando trata de redireccionarnos al
Web Panel CustProfile, la variable &CustId no tiene valor ninguno, ya que la misma se perdió luego de
haber finalizado la ejecución del Web Panel en el punto 2.
Probemos el web panel con el usuario “myuser”, y password “mykey”. Este usuario ya ha sido definido en los
datos que se distribuyen con el curso.
Es por esta razón, que si queremos disponer del valor de la misma, deberíamos agregar la variable &UserId
en el form y la ocultaríamos usando la propiedad Visible (por ejemplo en el evento Start).
Entonces en este caso, cuando el web panel ejecute por segunda vez, se dispararán los eventos:
1. Start
2. Se leen las variables del form (en este momento se obtiene el valor de CustId)
3. Se ejecuta el evento clic, y por consiguiente se llama al web panel con el código de cliente correcto!
INTRODUCCIÓN
En los objetos web, se dispone de más de un tipo de grid: el grid estándar y el grid Freestyle. Estos
grids, potencian el diseño de aplicaciones Web, permitiendo al desarrollador mayor libertad a la
hora del diseño.
Además en el caso de los Web Panels, es posible utilizar múltiples grids y también anidarlos para
permitir navegaciones más complejas.
A lo largo de este capítulo iremos implementando todo esto a medida que vamos viendo los
conceptos teóricos necesarios para su desarrollo.
Control Grid
Este control permite desplegar, -y dependiendo del objeto GeneXus que se trate, también ingresar,
modificar y/o eliminar- información asociada a muchos registros.
Puede utilizarse en los objetos con interfaz, es decir transacciones, web panels o work panels y
permite incluir tanto atributos como variables (incluyendo las de tipo bitmap).
Cuando el control Grid se utiliza en una transacción, por medio del mismo será posible insertar,
modificar y/o eliminar registros, en la tabla asociada que corresponda (en ejemplo, en la tabla
TOURISMSERVICELEVEL1).
Cuando en cambio, el control Grid se utiliza en un web panel o work panel, el mismo permitirá
visualizar únicamente los datos almacenados en tablas.
El botón que se encuentra en la barra de controles, permite insertar el control Grid. Al editar las
propiedades del control Grid, se abre un diálogo con las siguientes opciones: Columnas y
Propiedades.
Columns
Properties
AutoResize
Width
Heigth
LinesColor
LinesFont
TitleForeColor
TitleFont
BackColorStyle
BorderColor
Rows
AllowCollapsing
Collapsed
AllowSelection
SelectionColor
AllowHovering
HoveringColor
Si BackColorStyle = Header
LinesBackColor
TitleBackColor
Si BackColorStyle = Report
LinesBackColor
LinesBackColorEven
TitleBackColor
Si BackColorStyle = Uniform
BackColor
El ancho de cada columna de un grid se especifica como un porcentaje del ancho total del grid (que
por defecto no se especifica, el browser lo calcula en función al contenido de todas las celdas).
El ancho del grid NO se deduce como la suma de los anchos de las columnas, ya que si estos se
especifican en valores relativos (porcentajes), puede no corresponderse a lo deseado.
Aplican a todas las columnas del grid, para modificar los valores correspondientes a una
determinada columna, se deben modificar las propiedades de la misma (ver más adelante).
TABLE
Los grids también tienen algunas propiedades configurables para las tablas. Estas propiedades son:
ToolTiptext
Align
Background
BorderWidth
Cellpadding
Cellspacing
Rules
A continuación se detallan las propiedades que se pueden modificar a los grids en tiempo de
ejecución:
Visible: si la propiedad Visible tiene el valor 0, el grid completo desaparece del formulario. No
aplica a los grids de las transacciones.
Backstyle
BackColor
BackColorEven
BackColorOdd
PageCount
RecordCount
Rows
Align
AllowCollapsing
AllowHovering
AllowSelection
BackColorStyle
Background
BorderColor
BorderWidth
CellPadding
CellSpacing
Class
Collapsed
Height
HoveringColor
InternalName
Rules
SelectionColor
TitleBackColor
Tooltiptext
Width
También es posible indicar propiedades particulares para las diferentes columnas que forman el
grid. Para esto, se debe seleccionar la opción Columns del menú que aparece al hacer clic en el grid.
En este diálogo, seleccionando Properties sobre una columna se despliega un diálogo, como el
siguiente:
ControlName
ControlType
InputType
Suggest
ReadOnly
EnableHistory
EmptyAsNull
IsPassword
Autoresize
Font
ForeColor
Title
TitleFont
TitleForeColor
Format
Visible
Tooltiptext
ReturnOnClick
PROPIEDADES DE COLUMNAS EN TIEMPO DE EJECUCIÓN
En tiempo de ejecución se pueden modificar las siguientes propiedades de las columnas de un
grid:
Backcolor
Backstyle
Enabled
EnableHistory
FontBold
FontItalic
FontName
FontSize
FontStrikeThru
FontUnderline
ForeColor
Format
InternalName
IsPassword
Link
LinkTarget
Title
TitleBackcolor
TitleBackstyle
TitleFontBold
TitleFontItalic
TitleFontName
TitleFontSize
TitleFontStrikeThru
TitleFontUnderline
TitleForeColor
TitleFormat
Tooltiptext
Visible
Class
En la clase Grid o derivada de ella, en los Temas, es posible configurar propiedades adicionales para dicho
control. Ver Clase Grid.
Vamos ahora a definir el grid de los vuelos que arriban al país/ciudad seleccionado. Se quiere que
solamente cuando no se selecciona un valor para el país y/o ciudad, en el grid aparezca una columna
con esa información.
En la descripción del vuelo incluiremos un link a otro Web Panel (denominado “Flight” que
desarrollaremos más adelante, por eso definimos el nombre entre comillas para que lo considere
como objeto externo) para mostrar los detalles del vuelo.
Para esto, programaremos en el evento Load del control la propiedad link para el atributo FlightDsc.
Por defecto, GeneXus propone nombres para los controles (que sugiere según el tipo de control y la
cantidad de ese tipo que existan en el form). En muchos casos para simplificar la comprensión de la
lógica del control puede ser útil asignarles nombres más intuitivos.
Le asignaremos al control grid el nombre “Flights” y los atributos que lo componen serán la
descripción, la aerolínea y el código del país/ciudad de donde parte el vuelo, por lo tanto será un
grid con tabla base.
El evento será:
Event Flights.Load
Event Fligths.Refresh
if &CityId.IsEmpty()
ArrivalCityId.Visible = 1
else
ArrivalCityId.Visible = 0
endif
if &CountryId.IsEmpty()
ArrivalCountryId.Visible = 1
else
ArrivalCountryId.Visible = 0
endif
EndEvent // Refresh
GeneXus navega la tabla COUNTRIES ordenada por nombre de país, para realizar la carga del combo
dinámico &CountryId. Mientas que para la carga de &CityId, recorre la tabla COUNTRIES1 ordenado
por el nombre de la ciudad y filtrando por el país seleccionado en la variable &CountryId.
Para resolver el evento Load asociado al grid Flights, GeneXus navega la tabla FLIGHTS ordenada por
número de vuelo y filtrando por el país seleccionado en la variable &CountryId (en el caso de que se
haya seleccionado uno) y por la ciudad seleccionada en la variable &CityId (en el caso de que se haya
seleccionado una).
Al ejecutarlo habrá notado que si indica un valor para el país o la ciudad el dato no se muestra en la
línea del vuelo, pero el título se mantiene.
Esta es una de las principales diferencias entre los grids estándar y de tipo Free Style.
Notar que las condiciones de filtro por país y ciudad se realizan con la cláusula WHEN para
indicar que se toman en cuenta cuando las variables tengan un valor. En el caso de tener un valor
nulo, no se considera la condición por lo que se recorrerá toda la tabla.
El grid Free Style permite al usuario definir el formato de los datos a desplegar de una forma menos
estructurada que el grid tradicional.
Puede utilizarse en los objetos con interfaz web, es decir transacciones y web panels. El grid Free
Style es básicamente una tabla a la que se le pueden insertar los atributos / variables, text blocks,
imágenes, botones, web components, embedded pages, grids Free Style y/o grids que se van a
mostrar posteriormente en la pantalla.
Este tipo de grid no posee títulos para las columnas y además permite tener más de un tipo de
control, atributo / variable en una misma celda, proporcionando de esta forma mayor libertad de
diseño.
Para insertar el grid Free Style se debe utilizar el botón de la barra de controles disponibles. Se
despliega el diálogo de selección de atributos y variables que conformarán la grilla.
Para visualizar las propiedades de un grid Free Style, hay que seleccionar la tabla del grid, presionar
el botón derecho del mouse y seleccionar la opción ‘Properties’.
BackColorStyle
Rows
Columns
AllowCollapsing
Collapsed
Si BackColorStyle = Report
LinesBackColor
LinesBackColorEven
Si BackColorStyle = Uniform
BackColor
Visible: Si la propiedad Visible tiene el valor 0, el grid Free Style desaparece del formulario. En
el caso de tener grids anidados, la propiedad Visible aplicada al grid padre, aplica también a los
grids hijos.
Align
AllowCollapsing
BackColor
BackColorEven
BackColorOdd
BackColorStyle
Background
BorderColor
BorderWidth
CellPadding
CellSpacing
Class
Collapsed
Columns
Height
InternalName
PageCount
RecordCount
Rows
Rules
Width
En la clase FreeStyleGrid o derivada de ella, en los Temas, es posible configurar propiedades adicionales para
dicho control. Ver Clase FreeStyleGrid.
Vamos ahora a definir el Web Panel “Flights” que invocamos desde el grid de los vuelos del objeto
MainSearch para mostrar los detalles del vuelo.
Este será un Web Panel de salida (así se clasifican los Web Panels -y también los Work Panels- cuya
única función es exhibir datos).
Para que un Web Panel únicamente muestre datos, su form debe contener solamente atributos, ya
que los atributos al incluirse en Web Panels son indefectiblemente de salida. Otra posibilidad es
incluir en el form variables (sin ningún evento que las procese con el comando For Each line) y
cargarles valores explícitamente.
Mostraremos los datos básicos del vuelo, la aerolínea, el origen y el destino del mismo y también los
datos de los posibles precios.
Pondremos también las banderas de los países, para eso, usaremos variables de tipo bitmap donde
cargaremos las imágenes correspondientes.
Comencemos entonces creando un nuevo objeto de tipo Web Panel con nombre Flights.
Como recibiremos como parámetro el código del vuelo, definimos la regla parm(FlightId);
Por defecto todo atributo y variable que está dentro de un grid se despliega en ejecución como
texto, es decir que son únicamente de lectura y por consiguiente no pueden ser modificados.
Es posible aceptar datos en las variables de un grid dependiendo de la programación de los eventos
existentes en el objeto. Si:
1. dentro de un evento del Web Panel se está utilizando el comando For each line o For each
line in <grid>, ó
entonces todas las variables que están dentro del grid pasan a ser de ingreso. Es posible indicar en
este caso cuáles son las variables que no van a poder ser modificadas utilizando la regla noaccept() o
modificando la propiedad Read Only de la variable dentro del grid.
Es posible asociar un evento a cualquier variable o atributo que pertenezca al grid. Se consigue de
dos maneras distintas:
1. Editando las propiedades del control, y definiendo un evento de usuario en la propiedad
OnClicEvent
Event nombreControl.click
Endevent
Con esta última alternativa no tendremos que definir un evento de usuario, sino que estaremos
programando el evento clic.
Para ello, se accede a las propiedades del grid haciendo clic en el botón derecho sobre el control grid
y se configura la propiedad AllowSelection con el valor ‘True’. Al hacerlo se habilitan tres
propiedades más, que permiten especificar SelectionColor: el color que tendrá la línea cuando el
usuario la seleccione (haciendo clic con el mouse sobre la misma); AllowHovering: la posibilidad de
que cambie el color de las líneas cuando el usuario se desplaza con el mouse sobre ellas, y
HoveringColor: el color que tendrá una línea cuando el mouse pasa sobre ella.
En el grid de los vuelos, existe una columna con una imagen que nos permite marcar el vuelo como
interesante para analizarlo más adelante en detalle y planificar así el viaje.
Para implementarlo, deberemos agregar una variable de tipo bitmap, la cual se cargará en el evento
Load del control Flights.
Agregaremos entonces en el Event Flights.Load :
&interesting = Loadbitmap("int_unsel.jpg")
Existen varias formas posibles para procesar el registro como se describió anteriormente.En este
ejemplo, programaremos el evento Click asociado a la variable:
Event &interesting.Click
call(“Interesting”, FlightId)
&interesting = Loadbitmap("int_sel.jpg")
EndEvent // &interesting.Click
En ambiente web, los datos resultado de una consulta a la base de datos que se devuelven en un
grid se trasforman en texto html y ocuparán tantas líneas como resultados.
Tanto por temas de usabilidad, de performance o de tamaño de la página HTML generada, puede ser
conveniente desplegar los resultados en un grid de tamaño fijo y permitir con botones de
movimiento la navegación entre las páginas de los mismos. Nos referimos a esto como paginación
del grid.
Para esto, se dispone de métodos asociados al control Grid, los que aplican cuando la propiedad
‘Rows’ del grid tiene un valor diferente de cero.
Aplica a ambos tipos de grids estándar y free style y también cuando los grids están anidados.
Existen algunas diferencias relacionadas con la paginación cuando un grid tiene tabla base o no.
Cuando el grid no tiene tabla base, no está disponible el método Last Page ni GotoPage.
Métodos
FIRSTPAGE
El método FirstPage lleva al usuario al primer conjunto de registros devueltos.
0: Operación exitosa
Ejemplo
Event Enter
MyGrid.FirstPage()
Endevent
En este ejemplo cuando el usuario presiona el botón asociado al evento enter, en el grid se
mostrará el primer conjunto de registros.
NEXTPAGE
El método NextPage lleva al usuario al siguiente conjunto de registros.
Ejemplo
Event Following.Click
&err = MyGrid.NextPage()
if &err = 2
endif
Endevent
PREVIOUSPAGE
El método PreviousPage lleva al usuario al conjunto anterior de registros.
0: Operación exitosa
1: No está habilitado el paginado en el grid
2: Ya se encuentra en la primera página
Ejemplo
Event Back.click
&err = MyGrid.PreviousPage()
if &err = 2
endif
Endevent
En este ejemplo cuando el usuario presiona el botón Back, en el grid se mostrará el conjunto
de registros anterior y en el caso que ya esté cargada la primer página se muestra el mensaje
‘You already are in the first page’ en el textblock Message.
LASTPAGE
El método LastPage lleva al usuario al último conjunto de registros. Puede ser utilizado únicamente
si el grid tiene tabla base.
0: Operación exitosa
1: No está habilitado el paginado en el grid
3: El grid no tiene tabla base
Ejemplo
Event Last.click
MyGrid.LastPage()
Endevent
En este ejemplo cuando el usuario presiona el botón Last, en el grid se mostrará el último
conjunto de registros.
GOTOPAGE
El método GotoPage(PageNumber) permite acceder en forma directa a un determinado conjunto de
registros. Puede ser utilizado únicamente si el grid tiene tabla base.
0: Operación exitosa
1: No está habilitado el paginado en el grid
Ejemplo
En este ejemplo, dado el grid (GSearchResults) con el resultado de una búsqueda, y otro grid
(GPages) con el número de páginas de la primera para permitir un acceso más rápido de
paginado.
Event Refresh
&PageCounts = GSearchResults.PageCount
EndEvent
Event GPages.Load
if &PageCounts > 1
&Count = 1
&PageNumber = &Count
SFPages.Load()
&Count += 1
enddo
endif
EndEvent
Event &PageNumber.Click
GSearchResults.GotoPage(&PageNumber)
EndEvent
Resumen
A continuación se incluye una tabla con un resumen de los métodos disponibles cuando un grid tiene
tabla base y cuando no.
FirstPage
NextPage
PreviousPage
LastPage
GoToPage
Propiedades
Cada grid dispone de las siguientes propiedades que son utilizadas en la paginación:
RecordCount
PageCount
Consideraciones
Si el web panel que se está paginando tiene filtros, se debería agregar el método FirstPage
dentro del evento que aplica el filtro, a los efectos de evitar que el resultado desplegado
corresponda a la página en la que se encontraba anteriormente.
El método LastPage determina cuál sería la última página, para lo que utiliza la propiedad
Rows y la propiedad RecordCount del grid. El hecho de utilizar la propiedad RecordCount
implica que el DBMS (no el código generado) barre dos veces la tabla base del grid (la
primera vez para contar y la siguiente para "cargar").
El método LastPage ha sido pensado para que se ejecute un único comando Load por cada
registro de la tabla base. Por ello, si existen IFs en el evento Grid.Load que pueden
condicionar la ejecución del comando mencionado o se ejecuta más de una vez el método
Load por cada registro, los resultados pueden ser inesperados.
Implementación
El paginado se realiza por "número de registro". Esto quiere decir que, la página 1 tendrá los
registros del 1 al valor de la propiedad Rows, la página 2 los que van del Rows +1 al Rows * 2 y así
sucesivamente. Para mostrar la página 2, internamente, se "pasa por" los registros de la página 1 sin
mostrarlos. En general, para mostrar la página N, se "pasa por" los registros de las páginas anteriores
(N-1) sin mostrarlos.
1. Tener un buen filtrado de datos (de forma que no existan muchas páginas)
2. Evitar, cuando el costo sea alto, el uso de GotoPage( N) con valores altos de N, así como el
uso de LastPage.
Ejemplo
Los métodos de paginado de grids pueden ser utilizados en los eventos escritos por el usuario. Por
ejemplo:
Event Start
&Count = MyGrid.RecordCount
Pagina2.Visible = 1
EndIf
Pagina3.Visible = 1
EndIf
Endevent
Event Siguiente.Click
MyGrid.NextPage()
Endevent
Event Anterior.Click
MyGrid.PreviousPage()
Endevent
Event Enter
MyGrid.FirstPage()
Endevent
Para eso debemos modificar la propiedad Rows del grid y asignarle 5 como valor. Además, para
permitir la navegación entre todos los registros (las típicas acciones de ir a la primer página, a la
anterior, a la siguiente y a la última), vamos a incluir imágenes en el formulario programando su
comportamiento en el evento clic de cada una.
Definiremos entonces las variables de tipo Bitmap &first, &previous, &next y &last a las cuales les
asociaremos la imagen correspondiente en el evento start y luego en el evento click de cada una de
ellas programaremos el método de paginación del grid correspondiente.
El código que se ejecutará cuando el usuario haga clic sobre cada una de las imágenes será el
siguiente:
Event &first.Click
Flights.FirstPage()
EndEvent // &first.Click
Event &previous.Click
Flights.PreviousPage()
EndEvent // &previous.Click
Event &next.Click
Flights.NextPage()
EndEvent // &next.Click
Event &last.Click
Flights.LastPage()
EndEvent // &last.Click
Además cuando “modifiquemos” los valores de las variables &CountryId y &CityId de la parte fija,
vamos a presionar el botón de Buscar (“Search”) queriendo que se carguen los primeros 5 vuelos
que cumplen con los nuevos valores de las variables. Para esto, vamos a tener que programar en el
evento asociado al botón de Buscar lo siguiente:
Event Enter
Flights.FirstPage()
EndEvent // Enter
Si el evento de Buscar no tiene al evento Enter asociado, esta lógica deberá estar en el evento
de usuario definido.
Cuando un web panel contiene más de un grid en su form, GeneXus no determina una única tabla
base asociada al web panel, sino una tabla base asociada a cada grid.
Es decir, GeneXus determina para cada grid una navegación independiente. Puede verse una
analogía entre un web panel con varios grids y un reporte con for eachs paralelos.
A continuación mostramos un ejemplo:
Dado que el web panel “View Users & Service Providers” tiene más de un grid en su form, GeneXus
no determinará una tabla base asociada al web panel, sino que determinará una tabla base para
cada grid.
Los atributos que participan en la determinación de la tabla base de cada grid son:
los incluidos en el grid (se tienen en cuenta tanto los atributos visibles como los ocultos)
Los atributos de la parte fija del web panel no participan en la determinación de la tabla base de
ninguno de los grids, pero deberán pertenecer a la tabla extendida de alguno de ellos (para que sea
posible inferir sus valores). De no respetarse esto, al especificar al web panel, se mostrará en el
listado de navegación resultante, el warning: “Attribute not instantiated”.
Los atributos utilizados en los eventos del web panel tampoco participan en la determinación de la
tabla base de ninguno de los grids. Los atributos que se incluyan en los eventos fuera de comandos
for each, deberán pertenecer a la tabla extendida de alguno de los grids.
En el ejemplo, no hay definidos ni Order ni Conditions para ninguno de los grids, por lo que la tabla
base del grid que se encuentra arriba en el form será: USERS y la tabla base del grid que se
encuentra abajo en el form será: RATES.
Es importante resaltar que GeneXus determina la tabla base de cada grid, pero no busca ni establece
relaciones entre las mismas.
Al igual que en el web panel recientemente visto, si se define el siguiente web panel:
GeneXus determinará la tabla base del primer grid (que será USERS) y la tabla base del segundo grid
(que será COUNTRIES), pero no analizará si hay atributos en común entre ellas, y por ende no
definirá filtros automáticos. Es decir que los grids tendrán asociadas navegaciones independientes o
paralelas.
Si bien GeneXus no establece relaciones entre las tablas bases de los grids, el analista podrá definirlo
explícitamente. Primero estudiaremos los eventos en web panels con más de un grid, y a
continuación veremos cómo definir cargas relacionadas.
En web panels con más de un grid, existe un evento Refresh global y un evento Refresh particular
para cada grid.
Los eventos Refresh y Load a nivel de grids, deben referenciar al grid usando la siguiente
nomenclatura:
Event <Subfile Control Name>.<Refresh | Load>
....
EndEvent
Por ejemplo, si en el último web panel visto, los nombres de los grid son GridUsers y GridCountries
respectivamente, para codificar los eventos Refresh y Load a nivel de los grids, la sintaxis deberá ser:
Event GridUsers.Refresh
....
EndEvent
Event GridUsers.Load
....
EndEvent
Event GridCountries.Refresh
....
EndEvent
Event GridCountries.Load
....
EndEvent
Además de estos eventos a nivel de los grids, estará el evento Refresh global:
Event Refresh
....
EndEvent
Cada vez que se ejecute cualquiera de las acciones que provocan que se ejecute el evento Refresh,
se ejecutará:
GridUsers.Refresh
GridUsers.Load
GridCountries.Refresh
GridCountries.Load
De esta manera, cada uno de los grids se cargará con los datos correspondientes.
El comando LOAD mantiene la misma sintaxis en web panels con más de un grid. Se debe incluir al
mismo para hacer cargas de grids sin tabla base, dentro del evento Load de un grid.
De modo que los grids “no tendrán tabla base” y en consecuencia el evento Load de cada grid, se
ejecutará una sóla vez.
Event GirdCountries.Load
For each
&CountryId=CountryId
&CountryName=CountryName
Load
Endfor
Endevent
Event GridCities.Load
For each
where CountryId=&CurrentCountryId
&CityId=CityId
&CityName = CityName
Load
endfor
Endevent
Event Enter
¤tCountryId = &CountryId
Endevent
Consideraciones
Es posible especificar condiciones de filtro tanto a nivel global como a nivel de cada grid.
Para cada grid, se tendrán en cuenta las condiciones globales y las condiciones locales (es
decir: condiciones globales “and” condiciones locales).
De necesitarse utilizar al comando For each line en un web panel con más de un grid, se
deberá incluir una referencia al grid con la siguiente sintaxis:
Endfor
GridCountries.CountryId
Lo que nos quedaría por hacer en este Web Panel es desplegar la bandera y el resumen del "Destino
del Mes" y un grid con las ciudades del mismo.
Recordemos cómo es que dijimos que queríamos que apareciera el formulario en ejecución …
Lo primero que debemos hacer para poder mostrar el país del mes es agregar una celda a la derecha
de la celda donde filtramos por país/ciudad. La forma más sencilla de hacerlo es clic con el botón
derecho, y seleccionar la opción “Split Cell”. Una vez realizado este cambio es necesario modificar el
valor de la propiedad “Colspan” de la celda superior a 3, ya que ahora la misma debe abarcar 3
celdas en lugar de 2.
Para simplificar el desarrollo suponemos que el país del mes es el de código “URU”, entonces
podemos cargar la bandera y el resumen del mismo en el evento Start.
Por otro lado, vamos a tener que crear un grid con las ciudades del país del mes . Para eso el
nombre de la ciudad será la única columna del grid y en las condiciones locales al mismo definiremos
el filtro por el país del mes.
Podemos definir un grid estándar que tenga como título de la columnas Cities.
Para que no se vean en ejecución los bordes donde se carga el resumen del país del Mes, a la
variable correspondiente se la debe definir como ReadOnly.
Como no se asigna un nombre al grid, el control name correspondiente será Grid1. Se sugiere
que de todos modos se asigne el nombre Cities al control para facilitar luego la lectura del código y
también de la navegación del objeto.
Grids anidados
Puede haber grids anidados de varios niveles y puede haber también paralelos.
Puede decirse que se está definiendo un árbol en donde cada nodo es un grid.
Los grids comunes solo pueden ser hojas del árbol de anidación.
Por ejemplo, se quiere tener un web panel que muestre los poveedores de servicios, pero
indentados por categoría:
Hoteles
Hotel Colonia
Hotel Oceanía
Transport
Alfa Travel
OtherWorld Travel
...
Para ello se define un grid Free Style con la categoría y dentro de este se inserta otro grid con los
poveedores de servicios (podría ser un grid estándar o Free Style).
Los grids anidados cumplen las mismas reglas de relacionamiento que si fueran For Eachs anidados.
Por lo tanto, GeneXus determina la tabla base de cada grid (no son por completo independientes: en
la determinación de la tabla base del anidado influirá la del principal).
Luego, a partir de esas determinaciones, define las navegaciones que realizará para cada grid. La
lógica de los grids dependerá de las relaciones que encuentre entre las tablas determinadas.
Si no tiene tabla base, se deben cargar los datos con el comando Load.
Disparo de Eventos
Cada vez que se ejecuta el comando Load en un grid con anidaciones, se llama al evento Refresh y load de
cada hijo.
Para mostrar las atracciones turísticas del país/ciudad seleccionado, debemos implementar grids
anidados.
El grid padre tendrá la categoría de las atracciones y en el grid anidado las atracciones en sí.
En caso de que no se seleccione un país, se mostrarán las atracciones del país del mes. Además
como no se referencia a la ciudad estarán todas las atracciones de las ciudades del mismo.
Agregamos entonces un grid Free Style (de nombre Attractions), donde colocamos el atributo
TouristAttractionCatDescription, CountryId y una variable bitmap para cargar la imagen correspondiente
(almacenada en el atributo TouristAttractionCatImage) y dentro de este grid colocamos otro (también de tipo
Free Style y de nombre Attraction) para desplegar la información de la atracción turística.
Suponiendo que el país del mes es Uruguay, en el grid Attractions, agregaremos las siguientes conditions:
Como vimos anteriormente el grid puede ser estándar o Free Style, en este caso elegimos un grid Free Style
simplemente por el modo en que esta página va a ser diseñada.
Las columnas pueden ser atributos o variables (incluyendo las de tipo bitmap). El comportamiento
de los atributos y variables en un grid en una transacción es diferente al descrito en los Web Panels.
En ejecución, los atributos que se encuentran en el formulario de una transacción son de ingreso,
por lo tanto lo mismo aplica a aquellos que se encuentran dentro de un grid. Si se quiere modificar el
comportamiento por defecto, es decir no se desea el ingreso de un atributo, entonces se puede
utilizar la regla noaccept(Att) o la propiedad Read Only de la columna.
Nuevamente en este caso, se despliegan en el grid todos los registros ingresados en la transacción,
pero en el caso de transacciones no se puede programar paginación a pedido, por lo que de ser
necesario, se aconseja el uso de un Web Panel para el ingreso de información.
En el caso de las transacciones, el grid despliega por defecto 5 líneas de ingreso, este valor puede ser
modificado por el usuario utilizando las propiedades del mismo (Ver Propiedades del grid). Esto
significa, que siempre se despliegan x filas adicionales a los registros ya ingresados en la tabla.
Como se menciona anteriormente, los atributos en una transacción son de ingreso, por lo tanto no
es necesario realizar ninguna modificación.
Para poder ingresar valores en variables, es necesario utilizar la regla accept(&Var) para modificar el
comportamiento por defecto.
INTRODUCCIÓN
En este capítulo veremos los conceptos de Web Component y Embedded Page (página embebida).
El primero nos permite la reutilización de lógica entre los objetos y el segundo permite incluir dentro
de sitios diseñados con GeneXus páginas de terceros.
Web Components
Los Web Components permiten a los diseñadores de aplicaciones GeneXus Web un alto grado de
reutilización de los mismos.
Son objetos web que tienen una propiedad en la cual se indica que son componentes. Es decir,
pueden ser ejecutados en forma independiente (como cualquier otro objeto web) o pueden formar
parte de otro objeto web (Web Panel o Web Transaction).
Cualquier parte de un objeto web que se repita en varios objetos de una aplicación web, puede ser
definida como Web Component.
Los ejemplos más comunes son: menús, login, área que permite la personalización, etc.
La idea entonces es, en lugar de tener implementado, por ejemplo, la carga del menú en cada uno
de los objetos web que requieren el mismo, programarla en un Web Component y reutilizarlo en
cada Web Panel que requiere un menú.
Para definir un objeto web como Web Component se debe configurar la propiedad “Type” (antes
Web Component) con el valor “Component”. De esta forma, se habilita la propiedad “URL access”.
La cual puede tomar los siguientes valores:
Se debe notar que un objeto web definido como Web Component no pierde ninguna de sus
características, por lo tanto, puede ser ejecutado en forma autónoma.
Los Web Components se generan dentro del mismo HTML del Web Panel que los contiene. Esto
significa que el servidor resuelve la inclusión del Web Component en tiempo de ejecución y devuelve
al navegador el código HTML con el Web Component ya incluido.
Para insertar un control Web Component en un Web Panel o Web Transaction se debe elegir la
opción Insert / Web Component, o la opción de la barra de controles, con lo cual se creará un
control de tipo ‘Web Component’ en el objeto.
Para determinar el objeto que se va a desplegar en lugar del control Web Component, se utilizan las
propiedades del mismo. El objeto web a desplegar se puede fijar en diseño o en tiempo de
ejecución, como se describe a continuación.
PROPIEDADES MODIFICABLES EN DISEÑO
El control Web Component tiene las siguientes propiedades de diseño:
Object: Permite asociar un objeto web al Web Component. Sólo se aceptan objetos con la
propiedad “Type” en “Component”.
Parameters: Permite especificar la lista de parámetros con los que se invocará el Web
Component.
Sintaxis
Donde:
Wxxx
Es el Web Panel o Transacción al que se le ha configurado la propiedad “Type” en “Component”.
Sintaxis:
Control.Visible = Value
Valores:
Como lo demuestra la sintaxis, es posible dinamizar los Web Components, es decir que el contenido
de un Web Component sea variable. Por ejemplo:
&variable = ‘HMenu’
Comp1.Object = Create(&variable)
En el momento de hacer el Create (al ejecutar) GeneXus busca qué nombre de objeto (de los que
tengan definida la propiedad “Type” en “Component”) es igual al valor de la variable, si lo encuentra,
evalúa que coincidan los parámetros (cantidad y tipo), si no encuentra el objeto el espacio del Web
Component queda en blanco al ejecutar el Web Panel que lo contiene.
Esto implica que si se agrega un componente al modelo y el mismo será llamado de forma dinámica,
basta con generar y compilar el componente mismo.
Observaciones
En diseño, el tamaño del Web Component permanece fijo, pero en ejecución, el tamaño quedará
sujeto al espacio ocupado por el mismo. La forma de fijar el tamaño del Web Component en
ejecución es entonces incluyéndolo en una tabla y fijando el tamaño de la celda.
La asignación de un Web Component puede realizarse dentro de cualquier evento del Web Panel
‘padre’.
Si se asigna un Web Component en el evento Start del padre, los parámetros se pasarán solamente
la primera vez que se crea. En sucesivos POST, los parámetros se recordarán del render anterior.
Si se asigna un Web Component en cualquier otro evento (Refresh, Load, de usuario, etc.), los
parámetros se pasarán siempre que se ejecute dicho evento.
Si se asigna el objeto web en la propiedad Object del control Web Component en diseño, el pasaje
de parámetros se realiza en forma análoga a lo descrito en el punto anterior.
Los controles y las variables de los Web Components no son accesibles por los objetos que los
contienen (objeto web ‘padre’). Si por ejemplo se desea que un campo del Web Component tenga
un color determinado por el padre, se le tendrá que pasar por parámetro el color y asignarlo en el
evento Start del Web Component.
En ejecución, las propiedades del form del Web Component son heredadas del objeto web que lo
contiene. Por ejemplo si el form de un Web Component tiene color verde, pero el form del objeto
web que lo contiene tiene color blanco, entonces este último predominará sobre el primero. No es
así con las propiedades de los demás controles.
Ejemplo:
En la siguiente figura, se puede observar un Web Panel que contiene 2 Web Components (A y B) y un grid.
Cada Web Component tiene a su vez un grid.
En este caso el orden de los eventos cuando se ejecuta por primera vez es el siguiente:
Nota: La lectura de variables de cada objeto se realiza siempre inmediatamente después del evento Start de
dicho objeto.
En el ejemplo, si se dispara un evento del Web Component A, el orden de los eventos sería el siguiente:
En el ejemplo, al dispararse un evento del Web Panel, el orden de los eventos sería el siguiente:
Nota: si el objeto web tiene más de un grid, primero se ejecuta el Refresh independiente de los grids y luego
el refresh de cada uno de los grids en el orden en que aparecen en pantalla.
Todos los eventos del Web Component (Start, Refresh y Load si tiene grids) se ejecutan cada vez que
aparece el Web Component.
A continuación se describen algunos puntos a considerar para el diseño de páginas Web con
GeneXus y Web Components para lograr una optimización del código HTML generado:
Cuando se utiliza la función Create (especificando un objeto o una variable) los generadores tienen que
incrementar el código HTML generado para saber cuál fue el nombre del Objeto Web Component que se
utilizó.
El incremento en el código HTML por utilizar Create es relativamente menor. De todas formas, en páginas con
muchos Web Components y/o con Web Components dentro de grids, puede sumar varios KBytes más a la
página.
Resulta evidente que el DO CASE puede incluir Creates de Web Components que nunca van a ser llamados
(porque no son necesarios en la lógica del programa) y entonces nos encontraríamos en la misma situación
del punto anterior.
Genera menos código HTML un atributo/variable que no está en el form que uno que sí está pero
tiene la propiedad Visible en cero. Ninguno de los dos se "ve" en la página generada.
Lo que vamos a hacer ahora es definir el Web Panel Login que tenemos desarrollado para indicar
que el mismo es un Web Component. Para esto, configuraremos la propiedad “Type” en
“Component”.
Embedded Pages
Definición
El objetivo de las páginas embebidas o ‘Embedded Pages’ es poder incluir información externa; es
decir desplegar el contenido de cualquier URL en objetos web generados por GeneXus.
Una ‘Embedded Page’ es un control que se puede insertar en un Web Panel o Web Transaction. A
este control se le puede asociar cualquier página u objeto web GeneXus, cuyo contenido luego será
incluido en ejecución dentro del objeto.
El uso de Embedded Pages brinda a los usuarios GeneXus la siguiente posibilidad de incluir
información externa: permite que se incluyan páginas estáticas o dinámicas de la propia aplicación o
desarrolladas por terceros.
Dichas páginas pueden estar en el mismo servidor que la aplicación o en otro servidor. Esta
característica brinda gran dinamismo a las aplicaciones web desarrolladas con GeneXus.
Generación
Las Embedded Pages se generan como un ‘inline frame’ en el HTML final. Al ejecutar el objeto que
contiene una Embedded Page, el browser se encarga de realizar el requerimiento de la página
asociada y de incluirla dentro del inline frame.
Para insertar una Embedded Page en un objeto web se debe seleccionar la opción Insert /
Embedded Page, con lo cual se creará un control de tipo Embedded Page.
Como se mencionó anteriormente la Embedded Page es una página totalmente independiente del
objeto web que la contiene, por consiguiente, si se utiliza un objeto GeneXus en una Embedded
Page, los eventos de éste y del contenedor se dispararán en forma independiente y no es posible
establecer a priori cuándo se ejecutan los de uno con relación a los del otro.
Requerimientos
Para poder visualizar objetos web que contienen Embedded Pages, se requieren browsers que
soporten el tag correspondiente al ‘inline frame’ (<IFRAME>). En consecuencia, el browser (en el
cliente) debe ser como mínimo Internet Explorer 4.0, Netscape 6.0 o versiones superiores.
Propiedades
BorderStyle
Scrollbars
Source
TooltipText
Height
Width
Align
BorderStyle
TooltipText
Source
Visible
Height
Width
HeightUnit
WidthUnit
Si en las propiedades del control no se especifica la propiedad Source, entonces en el evento Start o Refresh
se debe asignar algún valor a la misma.
Por ejemplo:
Por ejemplo:
&url = “http://www.genexus.com”
MyPage.Source = &url
Para esto, en el objeto MainSearch agregaremos debajo de la tabla que contiene a los restantes
objetos un control Embedded Page. Para lo cual, deberemos ir al menú Insert / Embedded Page.
www.uruguaynatural.com.
INTRODUCCIÓN
En este capítulo continuaremos viendo formas de reutilizar lógica en el desarrollo de las aplicaciones
Web.
Una Master Page es un Web Panel con la propiedad “Type” en “Master Page”. En una misma base de
conocimiento se pueden definir tantas Master Pages como se desee.
Una vez que exista al menos una Master Page en la base de conocimiento, puede ser referenciada
desde cualquier Web Panel o Transacción Web, para ser utilizada por este objeto de modo de ser
cargado con ese marco o contexto.
De esta forma, el objeto referenciado hereda todo el layout y comportamiento de su Master Page.
Para poder cargar cualquier objeto web con el marco especificado por la Master Page, se creó un
nuevo control llamado “Content Placeholder”. Este control define en qué lugar, dentro de la Master
Page, estará ubicado el contenido de las Transacciones Web y los Web Panels que la utilizarán como
su página maestra.
Tal como lo ilustra la figura anterior, se define un Web Panel para oficiar de página maestra, es decir,
de la página que contendrá el layout y comportamiento genérico del sitio.
Esa página tendrá un Web Component para cargar el Header que deseemos darle a todas las páginas
del sitio, otro para el menú, y luego tendremos el “hueco” donde querremos que cada página
particular del sitio sea cargada.
A cada una de esas páginas individuales que conforman en conjunto el contenido del sitio, habrá que
configurarles en su propiedad “MasterPage” el nombre de la página maestra que creamos antes,
para que cuando sean ejecutadas, lo sean con el “marco” dado por la Master Page.
Una Master Page es definida, especificada y generada en forma independiente. Si se desea modificar
el layout o comportamiento general del sitio, solo hay que realizar la modificación en la Master
Page, sin necesidad de modificar/regenerar los objetos web que la utilicen.
• Menos código (se ahorra mucho código Javascript que generan los Web Components)
• Desarrollo incremental (solo cambiando el Master Web Panel cambia toda la aplicación)
¿Cómo hacer que un objeto web tenga una Master Page asociada?
Contamos con la propiedad “Master Page” para objetos web (Transacciones Web o Web Panels). Sus
valores posibles son:
(none)
Y solo puede definirse para: Transacciones Web y Web Panels con la propiedad “Type” en “Web
Page” (no Component).
Si se definen varios Web Panels como Master Pages, éstos aparecerán para ser seleccionados como
“Master Page” de un objeto web, en la propiedad “Master Page” que por defecto asume el valor
“(none)”.
Solo puede asociarse una Master Page a Transacciones Web o Web Panels que no sean Web
Components.
Observaciones
EVENTOS
Cuando se ejecuta un Web Panel que tiene asociada una Master Page, la secuencia de ejecución de
los eventos de cada uno será la siguiente:
3. Evento REFRESH y LOAD de la Master Page (aquí la Master Page es dibujada hasta que se
encuentra el Content Placeholder)
5. …
Restricciones
Una Master Page es un Web Panel común y corriente (incluso puede tener Web Components) pero
necesita cumplir las siguientes condiciones:
• No puede tener regla parm (en caso contrario mostrará en tiempo de especificación
“spc0092 Master Pages do not support the parm() rule”)
• No puede ser Main (si se escoge para la propiedad “Type” el valor “Master Page” para un
Web Panel, la propiedad Main desaparece)
• No puede invocarse una Master Page desde otro objeto como si fuera un simple Web Panel
(en tiempo de especificación mostrará: “spc0008 Events(6): Call to program
MasterWebPanel that cannot be generated”)
• Si un Web Panel era una Master Page y deja de serlo, los objetos que tuviesen asociada esa
Master Page mostrarán un error de especificación (“spc0093 The Master Page property
references an object that is not a Master Page).
Definamos en nuestra aplicación práctica una Master Page para incluir en ella el diseño del sitio.
Creemos entonces un nuevo objeto Web Panel MyMPage.
La idea sería tener un cabezal en la parte superior, el componente de login a la izquierda y un pie de
página para la aplicación.
Por lo tanto definiremos una tabla de 3 x 1 para alinear las secciones. La celda del medio la
dividiremos utilizando la opción Split Cell. Para que luego en ejecución se visualice correctamente
definiremos en la property “Width” tanto de las celdas (superior e inferior) como de la Tabla en
“100%”. Mientras que en la celda que tiene el Componente Login definiremos “20%” y en la celda
Zona de datos “80%”.
El cabezal y el footer serán dos nuevos objetos definidos como componentes que serán incrustados
en esta tabla.
Componente Cabezal
Ahora, es necesario definir los Web Panels que se invocarán desde este objeto para tener el diseño
definido. Para esto siga las instrucciones que se describen en el próximo documento.
Ahora es necesario que defina los componentes que se invocarán desde la Master Page.
Para el cabezal, crearemos un Web Panel “Header”. En el mismo incluiremos una Tabla de 1x1, en la
propiedad “Backcolor” configuraremos el color “Blue” para la celda de la primera fila. Además,
configuramos la propiedad “Width” en “100%”, para que la misma ocupe el ancho completo de la
pantalla. Luego, insertaremos el texto “Travel Agency”.Finalmente, configuraremos la propiedad
“Type” de este Web Panel en “Component”, de forma tal que luego lo podramos invocar desde la
Master Page.
Para el pie de página, crearemos un nuevo Web Panel denominado “Footer”.En el mismo
agregaremos una Tabla de 2x1. En la celda superior configuraremos la propiedad “BackColor” en el
siguiente color: “Peach” y en la celda inferior “Bone”. Agregaremos las variables &Today y &Time
respectivamente en esta celda, además en la propiedad “Align” de la misma se debe optar por
“Center”. En la propiedad “Width” de la tabla la configuramos en “100%”.
Por último, se deberá setear la propiedad “Type” de este Web Panel en “Component”, de forma tal
que luego lo podramos invocar desde la Master Page.
Luego de tener estos objetos definidos, vuelva a la Master Page para referenciarlos desde los
controles correspondientes.
Asignemos también al objeto MainSearch que estamos desarrollando esta Master Page. Para esto,
en la propiedad “Master Page” configure la Master Page definida anteriormente (MyMPage).
Especifique y genere los objetos modificados y ejecute el objeto para verlo en ejecución.
Para poder cargar cualquier objecto web con el marco especificado por la Master Page, se creó un
nuevo control llamado “Content Placeholder”. Este control define en qué lugar, dentro de la Master
Page, estará ubicado el contenido de las Transacciones Web y los Web Panels que la utilizarán como
su página maestra.
Para insertar un Content Placeholder se debe seleccionar la opción Insert / Content Placeholder,
con lo cual se creará un control de tipo Content Placeholder.
Propiedades
En caso de intentar insertar un segundo control de este tipo, al grabar dará un error: “Error: Only
one Content Placeholder control is allowed”.
INTRODUCCIÓN
Destacaremos aquí algunas particularidades de las Transacciones Web que están diseñadas en la
aplicación para profundizar algunos conceptos.
Para destacar el funcionamiento de las mismas, se describirán sus diferencias con respecto al
comportamiento de las transacciones en ambiente gráfico, destacando las propiedades y métodos
específicos utilizados en ambiente Web, como ser las propiedades Rows y AddLines. Así como
también el manejo de Blobs en Web Forms.
Cada Transacción contiene un form (pantalla) web mediante el cual se realizarán las altas, bajas y
modificaciones en ambiente Web.
Para diseñar el form web de una Transacción, se debe abrir la Transacción y seleccionar la opción Object/
Web Form del menú GeneXus. Otra forma, es seleccionando el tab Web Form:
Este form es similar al form GUI-Windows, en el sentido que contiene a todos los atributos definidos
en la estructura, con sus respectivas descripciones (para cada descripción se creará un text block).
Sin embargo, se pueden percibir algunas diferencias:
1) Aparece un control llamado Error Viewer que se utiliza para presentar mensajes. Este
control podrá ubicarse en cualquier parte del form y se le podrán asignar propiedades (tipo
de letra, color, etc.).
2) Aparece un botón llamado Get que se utiliza para obtener un registro luego de
ingresar un valor en el/los atributo/s clave.
3) Algunos botones difieren con respecto a los botones del form GUI-Windows. En particular
los botones Close y Help tienen la misma funcionalidad en ambos forms; sin embargo el
botón Delete All del form web, no opera de la misma forma que el Delete del form GUI-
Windows; y existen otras diferencias en lo que a botones se refiere, y su funcionamiento.
Las diferencias tienen que ver con la forma de trabajo de las aplicaciones Web (HTML), donde cada
vez que el usuario selecciona un botón, hay una comunicación con el servidor Web, una conexión a
la base de datos para efectuar una consulta u operación, desconexión de la misma, y presentación
del resultado con formato HTML en el browser del usuario.
Los botones definidos automáticamente por GeneXus pueden cambiarse por imágenes a las que se
les asocian en la propiedad OnClickEvent los eventos estándar de GeneXus (por ejemplo, ‘Next’,
‘Last’, ‘Get’, etc.).
El control Error Viewer es utilizado para desplegar mensajes al usuario, utilizando la función msg().
Para insertarlo, ir por el menú de GeneXus: Insert / Error Viewer.
Si el control Error Viewer no se coloca en una posición determinada del form, y se usa la función
msg(), el mensaje aparece en la esquina superior izquierda de la pantalla, de lo contrario, aparece
donde se colocó el control.
Esto significa que los objetos Web tienen un control Error Viewer implícito que es donde se
despliega el mensaje al usar la función msg().
Display Mode
ForeColor
Font
Fill
Propiedades del Error Viewer en ejecución
Además de las propiedades detalladas anteriormente, se pueden modificar las siguientes propiedades en
tiempo de ejecución:
BackColor
Display Mode
ForeColor
Class
Además de las propiedades mencionadas, en la clase Error Viewer de un Tema (o alguna clase derivada de
ella), se pueden configurar otras propiedades para el control. Ver Clase ErrorViewer.
Tener en cuenta que además de la Clase ErrorViewer, están las clases: ErrorMessages y
WarningMessages (que pertenecen a la clase Messages) de un Tema y que aplican a los mensajes
(de las reglas “msg()” y/o “error()”) que se despliegan al utilizar Client Server Validation).
Ahora que ya vimos como funcionan las Transacciones Web, podemos definir la Transacción para
registrar un nuevo usuario que es invocada en el link que definiremos en el Web Panel MainSearch.
Para hacerlo, tenemos que editar la Transacción de Usuarios (Users), seleccionando previamente el
modelo de Diseño en la base de conocimiento.
Comenzaremos asociando la Master Page definida previamente para que tome el diseño que ya
hemos definido. Para esto, debemos asignar a la propiedad “MasterPage” el valor “MyMPage”.
La numeración de usuarios se realiza en forma automática, por lo tanto se debe asignar “Yes” a la
propiedad “Autonumber” de la Transacción para que la clave primaria de la tabla se autonumere.
Como ya existe un registro ingresado, comenzaremos a numerarla a partir del número 2. Para eso,
asignar el valor “2” a la propiedad “Autonumber Start”.
Se debe evitar que el Nickname incluya menos de 5 caracteres. El algoritmo podría ser más
complejo, por lo que en ese caso se debería invocar a un procedimiento que devuelva si hubo o no
error.
El ingreso de todos los campos (menos el número de teléfono) es “obligatorio”, por lo cual debemos
agregar reglas que hagan este control:
Accept(&PswConf);
Finalmente, se debe controlar que la contraseña concuerde con la confirmación ingresada, para eso
es necesario agregar:
En el evento Start, se deberá agregar el código siguiente para que los controles de ingreso de
passwords queden enmascarados:
Event Start
&PswConf.IsPassword = 1
UserPwd.IsPassword = 1
EndEvent
Ahora que ya definimos la Transacción Web, podemos modificar el link para registrar un nuevo
usuario, en la página principal, de forma de que le pase los parámetros adecuados a la Transacción
Users.
Recuerde que la página principal del sitio MainSearch tiene asociada la Master Page MyMPage la
cual contiene un Web Component ”Login”, al cual le crearemos un link para registrar un nuevo
usuario.
Durante la ejecución pudimos visualizar claramente como es la ejecución de las reglas con Ajax.
Pudiendo ver cómo se disparan las reglas, la fórmula (en el caso del campo Full Name) y en cuando y
donde se despliegan los mensajes correspondientes a las reglas Error y Msg.
Resulta importante tener en cuenta que algunas reglas se disparan tanto en el cliente como en el
servidor, por lo que se disparan más de una vez, como se pudo observar en la ejecución anterior.
Además, al momento de grabar la password se podría haber utilizado las funciones de encriptación
que provee GeneXus.
GeneXus provee las siguientes funciones para encriptar datos: GetEncryptionKey, Encrypt64 y
Decrypt64.
Ahora que ya vimos como funcionan las Transacciones Web de dos niveles editaremos la
Transacción CountryAttraction para registrar las diferentes atracciones de un país. Para ello el
usuario deberá seleccionar un país y una ciudad (de los respectivos dynamic combo boxes, puesto
que estos atributos fueron definidos así en la Transacción anterior) y para facilitar al usuario el
ingreso de la información en el segundo nivel, aplicaremos las propiedades InputType y Suggest, al
momento de ingresar la categoría de la atracción.
El diálogo de las Transacciones en ambiente Web utiliza la tecnología Ajax para brindar una
alternativa al diálogo a pantalla completa (full screen) y proveer más interacción con el usuario.
En la medida que el usuario final vaya pasando por los campos de la pantalla y/o ingresando
información en ellos, se irán validando los datos, infiriendo los atributos de la tabla extendida, y
disparándose las reglas y fórmulas definidas. Todas estas operaciones se ejecutarán en forma
interactiva para que el usuario final pueda ir viendo resultados. De todas formas, las características
del diálogo a pantalla completa se mantendrán, en el sentido que cuando el usuario final confirme
los datos, se grabarán los de la pantalla completa, disparándose antes todas las validaciones, reglas,
y fórmulas.
En las aplicaciones .Net y Java con interfaz Web siempre se trabaja con diálogo de validación a nivel
del cliente (Web Client Side Validation). El propósito de esta funcionalidad es incrementar el nivel de
interacción de las aplicaciones Web utilizando la arquitectura Ajax, haciéndolas más atractivas sin
costo de desarrollo alguno.
GeneXus genera código para muchas de las reglas y fórmulas que el desarrollador escribe en las
transacciones, que es ejecutado en el browser del usuario final. En este sentido el usuario obtiene
un feedback temprano, ya que no es necesario someter un request de la página entera al servidor.
Este código es generado en el lenguaje Javascript, por lo que el browser debe tener habilitada la
opción de ejecutar Javascript.
Algunas reglas, por ejemplo aquellas que requieren acceso a la base de datos, deben acceder al
servidor para retornar sus resultados en tiempo real, lo que ahora es posible sin que deba viajar la
página HTML entera del servidor Web al cliente para ser desplegada por el browser. Cuando se carga
la página solicitada en el browser, el código Javascript también será enviado para:
Disparo de reglas que no dependen de ningún evento de disparo. Esto quiere decir, reglas
que dependen del árbol natural de evaluación.
Todo lo que hace el usuario es ingresar un valor en el campo que es clave foránea, y al abandonarlo
para pasar al siguiente campo, verá que aparecen en pantalla los valores inferidos. El usuario no se
percatará que entre medio viajó información al servidor y volvió, rearmándose la página entera.
Así como ocurría en Win cuando se tenía configurada la propiedad Client Side Validation para que
reglas, fórmulas y controles de integridad referencial se ejecutaran en el cliente, éstas no dejan de
ejecutarse en el servidor. Por el contrario, son ejecutadas por partida doble: primero en el cliente, y
luego, cuando el usuario confirma, vuelven a dispararse en el servidor antes de actualizar la base de
datos.
La validación de reglas y el cálculo de fórmulas son disparados cuando se pierde el foco sobre el
control. La regla de error, al igual que en Win, no permite seguir avanzando entre los campos del
form, hasta que la condición que la produce deja de cumplirse. También al igual que en Win, al
abandonar un control, se dispara todo lo que involucre a ese control, y a todos los que le sigan
consecutivamente y que sean noaccept (o read only).
Las validaciones de los tipos de datos (por ejemplo “invalid date format”) se hacen en el browser y
para presentar el mensaje de error se utiliza el mismo control que veremos se utiliza para las
validaciones de usuario.
En ambiente Web las Transacciones implementan un diálogo muy similar al que permiten los generadores
.Net y Java para aplicaciones con interfaz Windows cuando la propiedad Client Side Validattion tiene el valor
Yes.
Inferencia de modo: En Web el modo no será inferido automáticamente a partir del valor
que el usuario ingrese en los atributos que conformen la clave primaria, al contrario de lo
que sucede en Win. Es por ello que en diseño aparece automáticamente el botón “Get”,
para permitir recuperar un registro existente y poder trabajar con él. El desarrollador puede
eliminarlo si la transacción recibe clave y modo. En Win solo será incluido el botón “Get” si
se tiene configurada la propiedad CSV en “No”.
Botón de confirmación en ejecución: En Web el botón (con texto por defecto “Apply
Changes”) no cambia su texto de acuerdo al modo en el que se esté trabajando. En cambio
en Win el botón (con texto en diseño “Confirm”) cambia su texto en ejecución de acuerdo al
modo en que se encuentre la transacción (si se está insertando, dirá “Add”, si se está
actualizando dirá “Update” y si se invocó a la transacción recibiendo modo delete, el botón
mostrará “Delete”).
Una quinta diferencia que es importante tener en cuenta tiene que ver con la UTL (Unidad
de Trabajo Lógica). No debe perderse de vista que una UTL Web NO contiene las
operaciones realizadas dentro de distintos objetos en una cadena de invocaciones. Por cada
transacción Web existirá commit en caso de que el desarrollador no lo deshabilite, pero las
operaciones de ese objeto deben commitearse ANTES de llamar a otro objeto, pues de no
hacerlo, ya habrá terminado la vida de esa UTL al invocar al otro objeto y el Commit de la
transacción no operará.
¿En dónde serán desplegados los mensajes?
El lugar dónde se desplegarán los mensajes depende del momento de disparo. Cuando un mensaje
(“msg”) o error es disparado en el servidor (como por ejemplo registro duplicado), será desplegado
como una lista en el control Error Viewer. Además, en cajas de texto sobre la pantalla,
específicamente sobre los campos que el usuario haya ingresado (al momento de perder el foco) y
en consecuencia se tengan que presentar mensajes.
El Error Viewer continuará desplegando todos los mensajes y errores que no dependen de controles
del form que el usuario se ha posicionado. Por ejemplo, las reglas stand-alone. Asimismo, cuando el
usuario envía la página al servidor, todas las reglas y fórmulas se volverán a disparar. Todos los
mensajes que fueron disparados en el cliente y aún son válidos se redesplegarán también en un Text
Box o en el Error Viewer. Las reglas asociadas a eventos de disparo (AfterValidate, AfterInsert, etc.)
serán evaluadas por primera vez, lo que generarán mensajes y errores que se desplegarán en el
Error Viewer.
Es decir, funcionarán de manera combinada el control Error Viewer junto con los mensajes
interactivos en cajas de texto.
Todas las reglas “error” están asociadas a la Clase ErrorMessages y las reglas “msg” están asociadas
la Clase WarningMessages. Ambas clases pertenecen a la Clase Messages, donde se les puede
configurar sus propiedades como con las demás clases. La diferencia en este caso es que no hay
controles GeneXus asociados a dichas clases. La asociación a las clases ErrorMessages y
WarningMessages es automática (para los errores y reglas “msg” respectivamente).
Tener en cuenta que además de las mencionadas clases, está la Clase ErrorViewer que aplica a la
lista de mensajes del control Error Viewer.
En ambiente Web las Transacciones implementan un diálogo muy similar al que permiten los generadores
.Net y Java para aplicaciones con interfaz Windows cuando la propiedad Client Side Validation tiene el valor
Yes.
Los programas que se generan correspondientes a las Transacciones –tanto para ambiente Windows
como para ambiente Web- permiten dar altas, bajas y modificaciones en forma interactiva a la base
de datos a través de los mismos.
Además de esto, las Transacciones tienen un comportamiento diferente según reciban o no el modo
instanciado.
Las Transacciones Web pueden invocarse sin recibir el modo instanciado. Se detalla el
comportamiento de las mismas dependiendo de la acción: inserción, modificación o eliminación de
registros.
Modo Insert
Al ingresar a una Transacción Web de este tipo, se comienza en modo Insert, y se despliega una
pantalla con la siguiente forma:
Si se quiere ingresar un registro nuevo, se digitan los datos en la pantalla y se presiona el botón
‘Apply Changes’. Esto provoca, en primera instancia, que se validen los datos ingresados en forma
similar a cuando se presiona el botón ‘Check’. En caso de que ya exista el registro va a dar un
mensaje de error que se despliega en el Error Viewer. El mensaje es ‘Record already exists’.
Además, si no se trabaja con confirmación (propiedad Confirmation del objeto), se insertarán los
datos. Si se trabaja con confirmación, se desplegará el mensaje ‘Please confirm the data’. Al
presionar nuevamente el botón ‘Apply Changes’, se insertarán los datos.
Luego de actualizada la base de datos, se despliega el mensaje ‘Data has been successfuly added’.
Modo Update
Para entrar en modo Update, se deberá poner un valor en la clave y presionar el botón ‘Get’ ( ).
Esto hace que se carguen los datos del registro.
Al cargar los datos también se traen las descripciones. Se pueden modificar los datos y presionar el
botón ‘Apply Changes’, y se actualizarán los datos con un procedimiento análogo al del modo Insert.
Modo Delete
Para eliminar un registro primero se debe ingresar en modo ‘Update’ (ingresando la clave y
presionando el botón ‘Get’), y luego presionar el botón ‘Delete All’, lo que provoca que se
deshabilite dicho botón. En el caso de trabajar con confirmación, se desplegará el mensaje ‘Confirm
deletion’.
Al presionar el botón ‘Apply Changes’, se eliminarán los datos y se desplegará el mensaje ‘Data has
been successfuly deleted’.
En el caso de que no se trabaje con confirmación, al presionar el botón ‘Delete All’ se eliminarán
directamente los datos y se desplegará el mensaje ‘Data has been successfuly deleted’, sin necesidad
de presionar ‘Apply Changes’.
Al eliminarse un registro se cargan los datos correspondientes al registro anterior, quedando en
modo ‘Actualizar’. Si se borran todos los registros, la Transacción queda en modo ‘Insert’.
Observaciones
Tener en cuenta que si la variable &mode no es recibida como parámetro puede tomar cualquier
valor. Y en el evento Start al menos, el valor es indeterminado.
Este es el comportamiento esperado ya que el valor que tiene que tener no está establecido aún.
Las Transacciones Web que se invocan instanciando el modo Insert, Update, Delete o Display,
deshabilitan los botones de movimiento entre registros y los botones ‘Get’, ‘Select’ y ‘Delete All’.
Modo Delete
Cuando se invoca una Transacción Web instanciando el modo Delete siempre se despliega el
mensaje ‘Confirm deletion’, sin importar si se está trabajando con confirmación o no. Al
presionar el botón ‘Apply Changes’, se elimina el registro.
Cuando se trabaja con Transacciones Web de más de un nivel, se tienen que tener en cuenta los
siguientes puntos:
Las Transacciones Web pueden tener más de un nivel anidado. Asimismo, pueden tener varios
niveles en paralelo. Se implementa de la siguiente forma:
Método AddLines
Se implementó el método AddLines para el tipo de control grid. El mismo aplica en Transacciones
Web. Y permite al usuario ingresar líneas en el grid una por una.
El uso es bastante simple, para el caso del ingreso de datos que necesita más líneas de las que hay
por defecto se puede agregar un botón con este método. Este método no realiza ni validaciones ni
chequeos, sólo agrega las líneas en blanco al final y mantiene los valores que ya estaban ingresados
en la Transacción.
Sintaxis
MyGrid.AddLines(N)
Ejemplo
El usuario podrá presionar el botón AddLines en Modo Insert para agregar línea a línea en el grid de
la Transacción.
Event Start
if &Mode = 'INS'
MyGrid.Rows = 1
else // &Mode = UPD / DLT / DSP
MyGrid.Rows = 0
endif
EndEvent
Event 'AddLines'
MyGrid.AddLines(1)
EndEvent // 'Addlines'
Eliminación de líneas
En diseño se utiliza una variable &GxRemove definida y agregada automáticamente a los grids de la
pantalla por defecto. Esta variable es un check box que se ubica en la primera columna del grid.
Cuando se desea eliminar alguna línea del grid, se debe marcar la misma con el check box, y
presionar el botón de ‘Apply Changes’, no el botón de ‘Delete All’. Este último eliminará toda la
transacción, no las líneas marcadas.
Nota: Es importante considerar nuevamente que cuando se está en una Transacción Web se está
modificando todo el “documento” y no se está en un nivel en particular de la misma. Por eso para
eliminar líneas se debe utilizar el botón ‘Apply Changes’ porque en realidad se está actualizando el
“documento”. Lo mismo para agregar líneas, se debe utilizar el botón ‘Apply Changes’ porque se
está actualizando el “documento”.
Las reglas, en el objeto Transacción, cumplen un rol muy importante ya que permiten programar su
comportamiento (por ejemplo: asignar valores por defecto, definir controles sobre los datos, etc.).
Se escriben de forma declarativa, es decir que el orden en el que se escriben no significa que sea el
orden de ejecución.
Son solo válidas dentro de la Transacción en la que están definidas, es decir, son locales.
Todas las reglas de Transacciones pueden involucrar a atributos de la(s) tabla(s) base(s)
asociada(s) a la Transacción; y la mayor parte de ellas pueden también involucrar atributos de la(s)
tabla(s) extendida(s) de la(s) tabla(s) base(s) asociada(s) a la Transacción. Para poder referenciar a un
atributo en una regla, el mismo deberá estar incluido en la estructura de la Transacción. Ya sea que
pertenezca a alguna de las tablas bases asociadas a la Transacción, o a sus tablas extendidas.
Default
Error
Msg
Asignación
Serial
Subtract
Add
Allownulls
Update
Accept
Noaccept
Recomendamos acceder al Help de GeneXus para consultar sobre otras reglas válidas para
Transacciones, o para profundizar sobre estas, de ser necesario.
Default
Permite asignar un valor por defecto a un atributo o variable; el valor por defecto inicializará al
atributo o variable si se está realizando una inserción por medio de la Transacción (modo Insert),
pero el usuario final podrá cambiarlo si ese valor no es el que desea.
Sintaxis
Donde:
exp: es una expresión que puede involucrar constantes, funciones, variables u otros atributos. El tipo
de datos de la expresión debe coincidir con el tipo de datos del atributo o variable.
Funcionalidad: Esta regla asigna el valor de la expresión exp como valor por defecto del atributo att
o variable var, cuando la Transacción se ejecuta en modo Insert.
Esta regla no es válida para atributos que forman parte de la clave primaria de alguno de los niveles
de la Transacción, porque es disparada luego de que la clave es ingresada (ya que solo en ese
momento el modo es conocido y esta regla se dispara solo en modo Insert).
Error
Permite desplegar un mensaje de error si la condición se satisface. Sirve para definir los controles
que deben cumplir los datos.
Sintaxis
Error( ‘msg’ | &var | character expresion, msgId ) if cond [on evento/momento de disparo];
Donde:
var: es el nombre de una variable de tipo character, que contiene un string con un mensaje de error
a desplegar.
character expression: es una expresión cuyo tipo resultante es character y que será desplegada.
msgId: es un string (sin espacios en blanco ni comillas) que será utilizado solo si la Transacción es
definida también como business component1.
cond: es una expresión booleana (que puede contener los operadores lógicos and, or, not).
evento/momento de disparo: es uno de los eventos predefinidos de GeneXus disponibles para reglas
de Transacciones, que permiten definir el momento específico de ejecución de una regla.
Funcionalidad: Esta regla despliega el mensaje del parámetro msg, var o character expresion, si la
condición cond que se evalúa resulta verdadera. El mensaje de error se despliega en el control Error
Viewer y/o un cuadro de texto, deteniendo cualquier actualización a la base de datos. Cuando la
Transacción se ejecuta como Business Component, de dispararse el error, generará una entrada en
el SDT messages, con identificador msgId.
Msg
Sintaxis
Msg( ‘msg’ | &var | character expresion, msgId) if cond [on evento/momento de disparo];
Donde:
msg, var, character expresion, msgId, cond, evento/momento de disparo: son los mismos que para la
regla error.
Funcionalidad: Esta regla se utiliza para presentar mensajes de advertencia al usuario. Despliega el
mensaje del primer parámetro, si la condición se satisface, análogamente a la regla Error; pero a
diferencia de esta última, permite continuar con la ejecución si la condición sigue satisfaciéndose.
Del mismo modo, si la Transacción es Business Component, de dispararse la regla genera una
entrada en el SDT messages.
Los mensajes de advertencia se despliegan en el Error Viewer o cuadro de texto en ambiente Web.
Noaccept
Permite indicar que los atributos no aceptarán valores por parte del usuario (serán solo de salida). Si
bien se dispone de las propiedades ‘Visible’ o ‘Enabled’ para que los atributos no acepten valores, se
recomienda el uso de la regla Noaccept.
Sintaxis
Donde:
cond: es una expresión booleana (puede contener los operadores lógicos and, or, not).
Funcionalidad: En una Transacción, todos los atributos que pertenecen a las tablas base asociadas a
la Transacción, por defecto son aceptados. Si queremos que algunos atributos con estas
características no sean aceptados, entonces contamos con la regla Noaccept.
Subtract
Sintaxis
Donde:
att1, att2: son atributos pertenecientes a alguna de las tablas base asociadas a la Transacción, o a
sus tablas extendidas (y deben estar declarados en la estructura)
cond: es una expresión booleana (que puede contener los operadores lógicos and, or, not).
En modo:
- Insert: se le sustrae al valor del atributo att2, el valor del atributo att1
- Update: se le sustrae al valor del atributo att2, la diferencia entre el valor nuevo y el viejo de att1
Esta regla tiene la inteligencia para, dependiendo del modo, restar o sumar.
Add
Sintaxis
Donde:
att1, att2: son atributos pertenecientes a alguna de las tablas base asociadas a la Transacción, o a
sus tablas extendidas (y deben estar declarados en la estructura).
En modo:
- Insert: se le suma al valor del atributo att2, el valor del atributo att1
- Update: se le suma al valor del atributo att2, la diferencia entre el valor nuevo y el
viejo de att1
Serial
Sintaxis
Donde:
att1: es un atributo perteneciente a alguna de las tablas base asociadas a la Transacción (es decir,
no inferido), que desea autonumerarse (debiendo estar declarado en la estructura).
att2: Tiene que pertenecer a una tabla directamente superordinada a la del atributo att1.
Funcionalidad: El propósito de esta regla es asignar un número correlativo a att1 cada vez que se
inserta un registro en la tabla a la que pertenece att1. Se toma el valor de att2 (att2 contiene el
último número utilizado en la autonumeración), se le suma el valor del parámetro step, y el valor
resultante se asigna tanto al atributo att1 del nuevo registro, como al atributo att2 para conservar
el último número asignado.
Es decir, cuando se está insertando un registro por medio de una Transacción en la cual se ha
definido la regla: Serial(att1, att2, step);, se accede al att2 (habrá un solo valor de este atributo
relacionado, pues pertenece a una tabla directamente superordinada1), se le suma el valor step, y se
asigna el valor obtenido tanto a att1 del registro que va a ser insertado, como a att2 perteneciente a
una tabla directamente superordinada con respecto a la tabla que contiene a att1.
Accept
Permite indicar que las variables aceptarán valores por parte del usuario en un nivel dado de la
Transacción.
Sintaxis
Accept(&var [, att]);
Donde:
Update
Sintaxis
Donde:
atti: es un atributo perteneciente a la tabla extendida de alguna de las tablas bases asociadas a la
Transacción.
Funcionalidad: En una Transacción, todos los atributos que pertenecen a las tablas base asociadas a
la Transacción, por defecto son aceptados y los que perteneciendo a la tabla extendida, no
pertenecen a la base, son inferidos, y por tanto no aceptados.
Pero si queremos que algunos de estos atributos inferidos sean aceptados, para que el usuario
pueda modificar desde el form su valor, entonces contamos con la regla Update.
En la mayoría de los casos el orden de ejecución de las reglas definido por GeneXus a partir de
nuestras especificaciones es el deseado. Pero en algunos casos podemos querer cambiar el
momento de disparo de una regla.
GeneXus ofrece eventos o momentos de disparo en las Transacciones, que ocurren antes o después
de determinada acción, como la grabación del cabezal, o de una línea. Las reglas de las
Transacciones pueden condicionarse de manera tal de dispararse en el preciso instante en que
ocurre alguno de esos eventos de disparo.
Eventos de disparo:
BeforeValidate
AfterValidate
BeforeComplete
AfterComplete
…
Commit
La acción de “validación de los datos del cabezal” ocurre cuando se han validado todos y cada uno
de los campos ingresados en el cabezal. Observar que en este punto ya se han disparado todas las
reglas que correspondían a atributos del cabezal y que no tenían evento de disparo asociado.
Inmediatamente después se grabará el registro correspondiente al cabezal.
Análogo es el caso de las líneas: “la validación de los datos de una línea” ocurre cuando ya se han
validado todos y cada uno de los datos de la línea, y también se han disparado todas las reglas
correspondientes según el árbol de evaluación. Inmediatamente después de esta acción de
validación, se grabará físicamente el registro correspondiente a la línea.
Cada Transacción, al terminar de trabajar con un cabezal y sus líneas, realiza un commit (es
automático); será colocado en el código generado por GeneXus, a menos que el analista especifique
lo contrario.
Los eventos de disparo de reglas permiten definir que se ejecuten antes o después de alguna de las
acciones que acabamos de enumerar. Veremos cuándo ocurre cada evento de disparo.
Evento de disparo: BeforeValidate
Este evento de disparo ocurre un instante de tiempo antes de que la información de la instancia con
la que se está trabajando (cabezal o línea x) sea validada (o confirmada). Es decir, ocurrirá un
instante de tiempo antes de la acción de “validación del cabezal” o “validación de la línea”, según
corresponda. Observar que aquí también se habrán disparado todas las reglas según el árbol de
evaluación que no estén condicionadas a evento de disparo alguno.
El evento de disparo AfterValidate permite especificar que una regla se ejecute inmediatamente
antes de que se grabe físicamente cada instancia del nivel al cual está asociada la regla, en la tabla
física correspondiente, y después de que se hayan validado los datos de esa instancia.
Existen tres eventos de disparo que ocurren en el mismo momento que el AfterValidate, pero que ya
contienen intrínseco el modo. Ellos son: BeforeInsert, BeforeUpdate y BeforeValidate.
Observar que aquí es redundante condicionar la regla a “If Insert”. Por tanto, valen las siguientes
equivalencias:
Si hacemos un esquema de las acciones que rodean al evento de disparo, quedarán claros los dos
sinónimos elegidos para este evento (AfterValidate y BeforeInsert para modo insert)
VALIDACIÓN DE LOS DATOS
Así como existe un evento de disparo que permite definir que determinadas reglas se ejecuten
inmediatamente antes de que se produzca la grabación física de cada instancia de un nivel
(AfterValidate, BeforeInsert, BeforeUpdate, BeforeDelete), también existen eventos de disparo para
definir que ciertas reglas se ejecuten inmediantamente después de que se inserten, modifiquen o
eliminen físicamente instancias de un nivel. Estos eventos son AfterInsert, AfterUpdate y
AfterDelete.
El evento de disparo AfterInsert permite definir que una regla se ejecute inmediatamente después
de que se inserte físicamente cada instancia del nivel al cual está asociada la regla; el AfterUdate
luego de que se actualice físicamente la instancia, y el AfterDelete luego de que se elimine.
El evento de disparo AfterLevel permite definir que una regla se ejecute inmediatamente después de
terminar de iterar determinado nivel.
Esquema de disparo
ABANDONAR NIVEL 2
AfterLevel - BeforeComplete
COMMIT
AfterComplete
Observaciones
Una regla condicionada al evento de disparo AfterLevel Level atributo del 1er. nivel solo se disparará
en una Transacción Win (para una Transacción Web no tiene sentido) y lo hará una sola vez, cuando
se cierra la Transacción.
omo mencionaremos luego, en una Transacción Web estos eventos se ejecutarán una vez por cada
instancia de Transacción con la que se trabaje.
Otro tema importante son las reglas que no tienen evento de disparo asociado, se ejecutarán una
vez o dos o tres, dependiendo de lo que se haya configurado en la propiedad del modelo
Confirmation.
Por ejemplo, si se trabaja en Web y con la propiedad Confirmation=No, valor por defecto, las reglas
que no tengan evento de disparo asociado se dispararán: primero en forma interactiva en la medida
que el usuario final vaya trabajando en el form, y luego nuevamente cuando el usuario final efectúe
la confirmación.
Si se tiene una invocación a un procedimiento que actualiza la base de datos, habrá que optar por
alguna de las siguientes alternativas para evitar que se dispare más de una vez:
Por último, si se configurara la propiedad Confirmation= Yes, las reglas sin evento de disparo
asociado tendrían un triple disparo.
Esto no sucederá con reglas de GeneXus (como subtract, add) que actualizan la base de datos
porque GeneXus tiene la inteligencia para realizar el update solo al confirmar (lo mostrado en forma
interactiva se calcula en memoria).
Los eventos son acciones que pueden suceder o no. Se escribe código asociado a cada evento
posible, y el mismo se disparará sólo si el evento se produce.
Evento Start
Eventos de Usuario
Evento Exit
En primera instancia explicaremos cada uno de estos eventos conceptualmente y en qué momento
exacto se ejecutan, y a lo largo del curso veremos varios ejemplos de utilización de los mismos.
¿En qué momento se ejecuta? Se ejecutará cada vez que se someta el form de la Transacción, es
decir cuando se presione cualquier botón del form (“Get”, “Apply Changes”, botones de navegación,
botón Select o cualquier botón con un evento de usuario asociado).
En el evento Start fundamentalmente se trabaja con variables. En cuanto a utilizar atributos en este
evento, ya sea para evaluarlos y/o usarlos de algún modo menos para actualizarlos, se debe tener en
cuenta que los únicos atributos que se tienen disponibles son los que se reciben por parámetro en la
regla parm. Ningún otro atributo tendrá valor en este evento, pues todavía no se ha editado ninguna
instancia de la Transacción.
Evento Alter Trn (de Transacciones Web)
El evento After Trn de las Transacciones ocurre inmediatamente después de la ejecución de las
reglas con evento de disparo AfterComplete. Por consiguiente, el código que se incluya en este
evento, se ejecutará luego de culminada cada iteración completa por medio de la Transacción (es
decir, luego de haberse grabado cada cabezal con sus correspondientes líneas como registros físicos
en las tablas que corresponda y de haberse efectuado COMMIT).
Existen las siguientes alternativas para programar comportamientos que se deseen ejecutar luego de
cada iteración completa por medio de una Transacción:
Definir reglas individuales con evento de disparo AfterComplete y dejar el evento After Trn
sin código
Definir todas las sentencias en el evento After Trn con estilo procedural, y no definir reglas
con evento de disparo AfterComplete
Definir ambas cosas: alguna(s) regla(s) con evento de disparo AfterComplete y código en el
evento After Trn
Como venimos explicando, primero se ejecutan las reglas definidas con evento de disparo
AfterComplete, e inmediatamente después de las mismas se ejecuta el código definido en el evento
After Trn.
Un concepto que es muy importante tener claro, es que tanto en reglas con evento de disparo
AfterComplete como en el evento After Trn, se conocen los valores de los atributos del primer nivel
de la Transacción. Es decir, si bien ya se grabaron físicamente los registros correspondientes al
cabezal y las líneas de cierta iteración completa, e incluso se efectuó COMMIT, aún se tienen
disponibles los valores de los atributos del primer nivel, pudiendo estos utilizarse para pasarlos por
parámetro en una invocación, o evaluar su valor, o usarlos de algún modo menos para
actualizarlos .
Un detalle a tener en cuenta es que en el evento After Trn -como en todo evento- es posible incluir
comandos, a diferencia de en la sección de reglas de una Transacción, que no se puede.
Hay dos motivos por los cuales no es posible actualizar a atributos ni en reglas con evento de
disparo AfterComplete ni en el evento After Trn. El primer motivo es que ya se han hecho las
grabaciones pertinentes e incluso se ha efectuado COMMIT, de modo que ya es tarde para asignar
valores a atributos. Y además, en lo que respecta al evento After Trn, en los eventos no se permite
realizar asignaciones a atributos.
Eventos de usuario (de Transacciones Web)
Además de los eventos ofrecidos por GeneXus, el analista puede definir eventos creados por él, los
cuales reciben el nombre de eventos de usuario.
Cada evento de usuario debe asociarse a un control insertado en el form Web de la Transacción de
los que soportan el OnClickEvent (botones, text blocks, imágenes, atributos) y/o a una tecla de
función.
En tiempo de ejecución, el evento de usuario ocurrirá luego de que el usuario haga clic sobre el
control o la tecla de función asociado/a al mismo. Se consigue de dos maneras distintas:
…
EndEvent
Event nombreControl.click
Endevent
Con esta última alternativa no tendremos que definir un evento de usuario, sino que estaremos
programando el evento clic del control.
Nota: se pueden ejecutar eventos asociados a botones con Alt+<letra>. Se logra colocando un ‘&’ en
el Caption del botón, antes de la letra con la que se desea acceder al evento.
El evento Exit es un evento del sistema (por lo tanto ocurre automáticamente) y es lo último en
ejecutarse.
¿En qué momento se ejecuta? Ocurre una única vez, al final de cada iteración (es lo último que se
ejecuta).
Al igual que en el evento Start, en el evento Exit fundamentalmente se trabaja con variables.
En cuanto a utilizar atributos en este evento, ya sea para evaluarlos y/o usarlos de algún modo salvo
actualizarlos, se debe tener en cuenta que los únicos atributos que se tienen disponibles son los que
se reciben por parámetro en la regla parm. Ningún otro atributo tendrá valor en este evento.
Como se dispara cada vez que se dibuja la pantalla, no hace las veces de un verdadero Exit, por lo
que no suele utilizarse en este ambiente.
1. Evento START
2. Reglas que no tienen condiciones de disparo
Al presionar el botón ‘Get’, el botón ‘Confirm’ o cualquier botón con un evento de usuario asociado, el disparo
de eventos y reglas es el siguiente:
1. Evento START
2. Lectura de los atributos/variables del form
3. Reglas
4. Evento START
7. COMMIT
9. Evento EXIT
Como consecuencia, una Transacción Web inicia una UTL (Unidad de Trabajo Lógica) al comenzar a ejecutar
y la cierra (ya sea por COMMIT o ROLLBACK) antes de terminar. No puede formar parte de otra UTL. Si un
programa llama a una Transacción Web, ésta iniciará una nueva UTL.
No puede definirse una UTL compuesta por varias Transacciones Web. Una Transacción Web solo
puede Commitear los registros insertados por ella misma, o por procedimientos (teniendo la
propiedad “Commit on exit” en “No”) en una cadena de invocaciones, pero no puede Commitear los
registros insertados por otra Transacción.
El objeto que “gobierna” la UTL será la Transacción y puede incluir en ella las acciones realizadas en
procedimientos invocados desde ella.
Por todo esto, no aplica la propiedad “Commit on Exit” en las Transacciones Web, es decir si se pone
“Commit on exit” en “No” nadie comiteará estos datos.
Si se necesita que las operaciones de dos o más transacciones (con o sin procedimientos incluidos)
conformen una misma UTL, se pueden emular las transacciones con Web Panels y Business
Components y utilizar el comando Commit.
Dejamos aquí presentado simplemente el tema, para volver a él luego de estudiados los Business
Components, donde nos será posible comprender esta solución.
Consideraciones Generales
Control de concurrencia
Las Transacciones Web utilizan el diálogo pseudo-conversacional. Esto implica que, mientras el usuario está
realizando modificaciones a los datos o simplemente viéndolos, no existe ningún tipo de locks en la base de
datos.
El control de cambios (es decir la validación entre la lectura inicial y la confirmación) se realiza a nivel de
cada tabla involucrada en la Transacción Web. Los valores leídos al momento de “enviar” los datos son
comparados con sus correspondientes, en cada tabla, en el momento de “recibir” las modificaciones (cuando
el usuario presiona Confirm). Si los valores no coinciden, se informa al usuario que hubo cambios y que debe
intentar nuevamente.
Es importante notar que el control de cambios se realiza sobre todos los atributos involucrados salvo aquellos
de tipo Long VarChar por su tamaño.
Prompts
Para cada Transacción Web se genera un Web Panel que será el Prompt por defecto (autoPrompt), y los
Prompts correspondientes a las claves foráneas que se tengan. Para modificar el Prompt llamado por defecto,
se puede utilizar la regla Prompt.
En el caso que no se quiera la generación por defecto de los Prompts, se tiene la propiedad a nivel
del modelo: Generate Prompt Programs.
Valores:
Yes: Crea el Prompt asociado a la Transacción que está siendo especificada así como las referencias en la
lógica interna de la Transacción.
No: Elimina las referencias a los Prompts asociados a la Transacción. La primera vez que la Transacción se
especifique con esta opción, el Prompt no se crea. De otra manera, los Prompts no son eliminados, solamente
se eliminan las referencias a ellos.
También es posible definir Web Panels como Prompts tal como se verá a continuación.
Existen casos en los que un usuario requiere crear un Web Panel que luego quiere utilizar como
Prompt para obtener valores de atributos/variables.
Para invocar el Web Panel, simplemente se utiliza la regla Prompt en una Transacción Web o dentro
de un Web Panel.
Al dispararse la regla Prompt (haciendo clic sobre un control) se abre una ventana con el Web Panel
y, al seleccionar un valor (nuevamente haciendo clic) se cierra la ventana y el valor se asigna a el/los
atributos/variables que corresponda.
El Web Panel que será utilizado como Prompt debe cumplir ciertas condiciones:
Debe tener uno o más parámetros de tipo output. Puede tener de in, de inout también
pero lo importante es que tenga de output que son los que devolverá.
Alguno de los atributos, variables, text blocks o imágenes del form debe tener la propiedad
de diseño ReturnOnClic en True. Puede tener habilitada esta propiedad en más de un
atributo/variable. En caso de ser una variable, tiene que tener la propiedad Read Only en
Trae para que la propiedad esté habilitada.
Los valores a retornar (de los parámetros definidos como de output) no se determinan al
realizar clic, sino al desplegarse la pantalla por lo que tienen que tener el valor válido a
retornar en cada Load (si se muestra un grid, por ejemplo).
Si uno de los atributos, variables, text blocks o imágenes del form que tienen la propiedad de diseño
ReturnOnClic en True también tiene programado el evento Clic, el código que esté en dicho evento
se ignora. Simplemente al hacer clic se asignan los valores a las variables de tipo OUT y se retorna.
Uso avanzado
Esta funcionalidad puede no contemplar todos los casos. Por ello, también se implementó la función
ReturnOnClic() (sin parámetros) que puede ser asignada a la propiedad Link de cualquier control
(que tenga esta propiedad).
Ejemplos
Prompt de Cities
En los Eventos:
Event Grid1.load
&CityId = CityId
Endevent
En el form:
Un grid que tiene CityNom y CityId, donde CityNom (por ejemplo) tiene la propiedad ReturnOnClic
en true.
No solo un Web Panel puede ser un Web Component, sino también cualquier Transacción con
interfaz Web.
La posibilidad de definir una Transacción como Web Component permite tener en un Web Panel
varios componentes, algunos conteniendo Transacciones (para altas, bajas y modificaciones de
datos) y otros conteniendo Web Panels que despliegan información relacionada, menues, etc..
La definición y el uso de una Transacción como Web Component es como lo vimos en el capítulo
Web Components.
Observaciones
Es posible tener varios Web Components con Transacciones en un mismo Web Panel, pero se deben
tener en cuenta los siguientes puntos:
El estado de grabación no se mantiene por cada componente. Esto significa que si el usuario ingresa
a un componente y realiza una operación (por ejemplo modifica un atributo de la Transacción y
oprime el botón “Aplicar Cambios” por primera vez) y no reconfirma la misma, al realizar una
operación en otro componente (por ejemplo un GET), se pierden los cambios realizados en el
primero (es decir se refresca la página con el valor y estado que tenía antes de modificar el atributo).
INTRODUCCIÓN
Las aplicaciones Web necesitan un look & feel bastante más sofisticado que las aplicaciones Win y
los desarrolladores no tenemos las habilidades y el tiempo para lograr un diseño con esas
características.
Por esa razón, por lo general se opta por contratar servicios de diseño. Por lo cual, es necesario
luego integrar ese diseño con la aplicación GeneXus. Esta integración se logra a través de los
“Themes”.
Para el diseño gráfico contamos con el “Editor de Themes”, una herramienta de libre distribución
que se puede ejecutar en forma independiente de GeneXus.
Mientras que en versiones anteriores las propiedades de los controles en los “html forms” (Web
Panels y forms html de las Transacciones) debían ser configuradas en los controles, hoy mediante los
“Themes” se pueden definir “Clases” para los diferentes tipos de controles y asignarles propiedades
a esas clases.
Luego, los controles se asocian a esas clases, y éstos heredarán las propiedades allí configuradas. Por
lo tanto ya no es necesario establecer los valores de las propiedades para cada control en el form.
Las propiedades de los controles se configuran en un único lugar: en las clases del Theme.
Cualquier cambio de diseño que se requiera hacer, se realizará en el Theme (sin necesidad de
generar/compilar absolutamente nada), de esta forma se logra la uniformidad estética del sitio con
un bajo costo de mantenimiento (no es necesario cambiar cada uno de los objetos), y como
consecuencia se obtiene una mayor productividad en el desarrollo de aplicaciones Web.
Recuerde que en el capítulo 2 se dió una introducción del objeto Theme e incluso se realizaron
algunos ejercicios para comprender su funcionamiento.
Veremos a lo largo de este capítulo en forma más completa, las diferentes funcionalidades que
brinda este objeto.
Generalidades de un Theme
El editor de temas es una herramienta de libre distribución que se puede ejecutar en forma
independiente de GeneXus. Esto es para que la herramienta pueda ser usada por el diseñador
gráfico, y el desarrollo de la aplicación se independice e incluso se paralelice con su diseño.
Se despliega como una estructura jerárquica de Clases, la siguiente es una imagen del editor de
temas:
Una clase podrá ser asignada a un control en tiempo de diseño, y en tiempo de ejecución a través de
la “Propiedad Class”.
CLASES PREDEFINIDAS
Attribute
Button
Error Viewer
FreeStyleGrid
Grid
HyperLink
Image
Table
Textblock
Form
CLASE “MESSAGES”
La clase “Messages” se utiliza para configurar los seteos de los mensajes desplegados en la pantalla a
consecuencia de Web Client Side Validation. La misma tiene dos clases:
Para utilizarlas, se configuran de igual forma que las restantes clases. La diferencia está en que no se
tiene ningún control GeneXus asociado. La asociación de estas clases es automática.
Nota 1: Existen también clases específicas de botones, correspondientes a aquellos que son
generados en forma automática por GeneXus en Web Transactions y Web Prompts.
Cuando se crean dichos objetos los botones se asocian a las clases correspondientes. Estas clases
son descendientes directas de la clase “SpecialButtons” que es hija de la clase “Button”:
BtnCancel
BtnCheck
BtnDelete
BtnEnter
BtnFirst
BtnGet
BtnHelp
BtnLast
BtnNext
BtnPrevious
BtnRefresh
BtnSelect
Nota 2: Las propiedades del form, que se definen en GeneXus se aplican al BODY del HTML. Esto es porque algunas de esas propiedades
no son soportadas por el tag FORM (por ejemplo, el background color).
Por la misma razón, la clase Form queda en runtime asociada al tag BODY.
ReadonlyX (descendiente de X)
Blobs:
BlobContentX (descendiente de X)
ReadonlyBlobContentX (descendiente e BlobContentX)
BlobInputX
BlobContentX y BlobInputX son clases asignadas en tiempo de ejecución a los controles blob. Un control blob
consiste en el contenido y en lo que se carga en el control.
Si la clase X ha sido asociada al blob en diseño, la clase BlobContentX es asignada al contenido, y la clase
BlobInputX es asignada al control cargado.
ReadonlyY
Blobs:
BlobContentY
ReadonlyBlobContentY
BlobInputY
CLASES DERIVADAS
Se pueden crear clases derivadas a partir de las clases predefinidas; el proceso de definir una clase
significa para el desarrollador asignarle un nombre (hacer botón derecho en la clase padre y clic en
“New Class”) y configurar las propiedades que le corresponden a esa clase.
Las clases hijas o derivadas quedan implícitamente vinculadas en una relación de herencia con las clases de
las cuales derivan. Como consecuencia de esto, las modificaciones en las clases “padre” se verán reflejadas
en las “hijas”, con algunas excepciones. Las modificaciones consisten en cambiar los valores de alguna de las
propiedades de la clase.
La parte inferior del editor muestra el nombre de la propiedad, junto con una descripción de la
misma. Además dirá “Inherited: True” o “Inherited: False” según corresponda.
Si para una propiedad de una clase dice “Inherited: True”, significa que su valor es un reflejo del
valor de la misma propiedad del padre. Es decir, cualquier cambio en la clase padre se traduce en un
cambio en la misma propiedad en el hijo.
En cambio, "Inherited: False" implica que un cambio en la propiedad en la clase padre no se reflejará
en la clase hija. La herencia en el valor de las propiedades se pierde cuando éstas son alteradas en
las clases hijas.
Si la clase por defecto no se indica explícitamente, será la clase predefinida por GeneXus.
La clase por defecto es identificada en el editor de temas por un triángulo azul en la esquina derecha
del icono de la clase.
Propiedades de un Theme
Si se configura la propiedad Base Image Path del modelo, y al salvar el Theme, si parte del path dado
en alguna propiedad de una clase (como ser la propiedad Background) coincide con el indicado en la
Base Image Path, la imagen se salva relativa.
Esto es porque cuando se trabaja desde dentro de GeneXus el valor de la propiedad coincide con el
Base Image Path de la base de conocimiento.
Si no se setea la propiedad cuando se trabaja con el Template, es decir, se usan caminos absolutos y
no relativos, todas las imágenes quedarán apuntando a c:\cliente\imagenes que no existe en la
máquina del usuario GeneXus y por lo tanto no se va a visualizar correctamente el Theme cuando se
incorpore a la base de conocimiento (además del hecho de que el usuario seguramente tuviera que
cambiar ese path porque no será válido en producción).
Si el diseñador configura la propiedad (en el ejemplo, con el valor c:\cliente\imagenes), las imágenes
quedarán salvadas en forma relativa, luego el usuario GeneXus debe copiar las imágenes a e:\images
para poder visualizar correctamente el Theme al incorporarlo a la base de conocimiento, sin
necesidad de algún otro procedimiento (como sería ir a cambiar uno por uno las imágenes utilizadas
en el Theme para que apunten a la imágen correcta).
Notas:
En este panel es posible configurar las propiedades de la clase seleccionada, o del HTML Tag
seleccionado. Junto con estas propiedades, se incluyen todas las propiedades disponibles en
GeneXus, bajo la categoría: “GeneXus Attribute Control Propierties”,como se visualiza en la figura:
Nota: Además, el alcance de las propiedades disponibles dentro del Editor de Temas puede ser
ampliado. El usuario podrá definir nuevas propiedades si lo necesita (en el caso de que no existan en
el Editor).
Background Properties
Box
Classification
Extensions
GeneXus Attributes Control Properties
Mouse and Keyboard
Text
Esa es la clasificación estándar de las propiedades de los CSS (Cascading Style Sheets), con la excepción del
grupo “GeneXus Attributes Control Properties”, cuyo propósito es centralizar las propiedades que pueden ser
editadas en GeneXus, para el control correspondiente a la clase.
Clase Form
El control Form, se modifica según la clase Form. Las propiedades bajo el grupo “GeneXus Form
Properties” son las que pueden ser editadas en las properties del control Form en diseño, más
algunas propiedades que complementan la funcionalidad de aquellas y se encuentran en el estándar
de CSS, que son las siguientes:
Background
BorderColor
BorderStyle
BorderWidth
Font
TextColor
Height
Width
WordWrap
Caption
Dentro de las propiedades del grupo “GeneXus Button Control Properties”, se tienen las siguientes
propiedades:
BackColor
Background
BorderColor
BorderStyle
BorderWidth
Font
ForeColor
Height
Width
Clase Attribute
Dentro de las propiedades del grupo “GeneXus Attribute Control Properties”, se tienen las siguientes
propiedades, que si bien pertenecen a ese grupo, no se encuentran dentro de GeneXus para los
atributos/variables:
BackColor
Background
BorderColor
BorderStyle
BorderWidth
Font
ForeColor
Height
ImeMode
Width
Clase Image
La clase Image se puede asignar tanto a controles imagen, como a variables de tipo bitmap.
Las propiedades del grupo “GeneXus Image Control Properties”, para imágenes son las siguientes:
BackColor
BorderColor
BorderStyle
BorderWidth
Font
ForeColor
Height
Width
En particular, el valor de la propiedad Margin del Editor de Themes, se suma al valor de las
propiedades Hspace y Vspace de GeneXus (caso de imágenes).
Margin
Border
Padding
Content
Las propiedades hspace y vspace son similares a border, por eso se "suman" cuando se define un
margin.
Clase Table
Las propiedades del grupo “GeneXus Table Control Properties”, para tablas son las siguientes:
BackColor
Background
BorderColor
BorderStyle
BorderWidth
Height
Width
LinesColor
LinesFont
Clase Grid
La propiedad que se encuentra en el grupo “GeneXus Grid Control Properties”, y no está en diseño
en GeneXus, es:
BorderStyle
Clase FreeStyleGrid
Clase TextBlock
Las propiedades del grupo “GeneXus TextBlock Control Properties”, que no se encuentran
disponibles en diseño en GeneXus para textblocks son las siguientes:
BackColor
Background
BorderColor
BorderStyle
BorderWidth
Height
Width
Clase ErrorViewer
Las propiedades del grupo “GeneXus Errorviewer Control Properties”, que no se encuentran
disponibles en diseño en GeneXus para el control ErrorViewer son las siguientes:
Background
BorderColor
BorderStyle
BorderWidth
Height
Width
La propiedad BorderStyle, en el Tema, tiene una gama de valores más amplia que en el caso de la
misma propiedad en GeneXus.
Los valores que la propiedad acepta en el Tema son los que admite la tecnología CSS y son los
siguientes:
None
Dotted
Dashed
Solid
Double
Groove
Ridge
Inset
Outset
La vista previa del editor se puede personalizar, agregándole “Custom Views”, que son archivos
.HTML. Para eso, agregar una nueva vista a través del menú contextual del nodo Custom Views, o
presionando la tecla INS sobre el mismo.
Se puede modificar el source y ver los cambios reflejados en el HTML, pero no se salvan dichos
cambios en el documento que esté activo.
La siguiente figura muestra un ejemplo en el cual se agregó una vista previa llamada “Transacción”.
Si se tienen diferentes clases form definidas (es decir, distintas clases hijas de la clase predefinida form), el
preview para el resto de los controles se ve con un aspecto de fondo correspondiente a la configuración de
aquella clase form que sea la default.
HTML Tags
Los HTML Tags complementan la funcionalidad de los Temas, en cuanto a que permiten definir las
características de un Tag HTML, en un determinado contexto. Es decir, siempre que se quiera
establecer la configuración de un determinado Tag dentro de un contexto, se puede hacer mediante
el Editor de Temas. Por ejemplo, definir las propiedades de los links dentro de una tabla.
La configuración de los Tags HTML, dada en el editor, se ve reflejada en la página Web si esos Tags
están en el HTML de la página, en el mismo contexto con el cual fueron definidos en el editor.
El contexto está determinado por la jerarquía con la cuál se definen los Tags.
Para el ejemplo que mencionábamos anteriormente, de definir las propiedades de los links dentro
de una tabla, se haría como se muestra en la figura:
Se define un Tag A hijo de un Tag TD.
Es decir, siempre que un tag A se encuentre anidado a un tag TD en el HTML generado, se tomará el
forecolor definido en el ejemplo.
Otro caso de ejemplo sería definir un tag body y la propiedad “ForeColor” del mismo, con lo cual el
texto libre de la página tomará ese color.
Demo: Temas
Cuando se hace una aplicación Web es necesario que el sitio se vea “uniforme”.
Esto implícitamente requiere de un alto costo de mantenimiento, ya que si por ejemplo hay que
cambiar el color de un grid de azul a celeste, probablemente habría que hacerlo en todas las páginas
del sitio para mantener la uniformidad del mismo. Antes, había que ir por cada uno de los controles
de cada objeto. Hoy el cambio se realiza en un solo lado: el Tema.
En tiempo de ejecución, ese archivo .CSS (que contiene la definición de las clases) es referenciado en el
Header de las páginas generadas, y se transfiere al pc del cliente para almacenarse en su caché.
Por lo cual, siempre que realicemos un cambio en el Tema asociado a un objeto, basta con llevar el archivo
.CSS a producción, para que el usuario final perciba los cambios estéticos realizados (no es necesario generar
ni compilar!!).
Observe que los objetos de la base de conocimiento del curso están asociados al Tema “Default” (a través de
la propiedad “Theme” del objeto), y los controles de cada uno de los objetos están asociados a la clase
default correspondiente (propiedad “Class” de los controles).
Realizaremos algunos cambios a las clases de Tema “Default” y veremos cómo se reflejan los cambios en
ejecución.
Note que en nuestro caso, el directorio de producción coincide con el directorio Web del modelo, por lo cuál
no es necesario copiar el .CSS a ningún lado.
Para crear un nuevo Theme desde dentro de GeneXus, se debe ir a la opción Object / New
Object / Theme
Un folder “HTMLNodes”
En ese Tema vamos a definir una clase “BtnLogin” para la cual definiremos algunas propiedades. En
particular, vamos a asignarle una imagen a la propiedad “Background” de la clase.
Observe que la propiedad “Base Image Path” del Tema coincide con la misma propiedad del modelo
de diseño. Entonces, dado que vamos a usar una imagen que se encuentra bajo el “Base Image
Path”, el path de la propiedad Background del Tema quedará relativo.
Al Tema “Agency” lo vamos a asociar al Web Panel Login. Debemos cambiar la clase del botón
“Login” para que sea “BtnLogin”.
Haga clic aquí para ver la demostración
Observe que en este caso sí es necesario generar/compilar antes de ejecutar, ya que cambiamos una
property del objeto y una property del control.
En el caso de que una propiedad de una clase esté marcada como “Inherited:False”, es posible
revertir la situación.
Haciendo clic con el botón derecho sobre la propiedad correspondiente, aparece un menú “Inherit
Value”. Seleccionando dicha opción, la propiedad pasará a heredar el valor de la misma propiedad
del padre.
Por ejemplo si se define una clase “Bullet” derivada de Texblock, con el fin de definir las propiedades
de los textos en listas con viñetas. Supongamos que ahora se quiere tener otra clase para los textos
anidados a aquellos que están asociados a la clase “Bullet”, y se desea que tengan las mismas
características que la clase “Bullet” a excepción de la indentación. Llamemos a esa clase “SubBullet”
y creémosla como hija de “Bullet”. Esta clase solo difiere con su padre en la propiedad “TextIndent”.
Por lo cual, esa es la única propiedad que no hereda, y la única propiedad que habiéndose
modificado en el padre no se refleja en la clase “SubBullet”.
Como ejemplo del concepto de herencia en los Temas, edite el Tema “default” de la base de
conocimiento, y modifique la propiedad “BackColor” de la clase Button.
Observe que para todas las clases hijas de “Special Buttons”, que es a su vez hija de “Button”, la
propiedad “Backcolor” está indicada como inherited:True, por lo cual, las clases hijas heredan esa
propiedad del padre.
Vea en la Transaction Web Users como todos los botones cambian el “Backcolor”, siendo que cada
uno de ellos está asociado a una clase diferente derivada de “Button”.
Haga clic aquí para ver cómo se pierde la herencia de las propiedades, al ser modificadas en la clase
hija.
Dentro de la base de conocimiento es posible salvar los Themes como archivos con extensión .CSS (objeto
Theme de la base de conocimiento). Asimismo, dentro y fuera de GeneXus, el editor permite trabajar con
archivos con extensión XML.
Esta última funcionalidad (trabajar con archivos XML) permite la integración entre el editor como aplicación
independiente y como tool de GeneXus.
Nomenclatura: Llamaremos “Template” a los archivos XML que tienen el formato de Themes, pero
no son objetos GeneXus Theme. Cuando el editor es ejecutado en forma independiente de
GeneXus, siempre se trabaja con Templates.
Entonces, un usuario podrá diseñar un sitio utilizando el editor de temas independientemente de GeneXus; el
producto de su trabajo serán archivos .XML que otro usuario (posiblemente quien desarrolle la aplicación)
podrá integrar a la base de conocimiento, y salvar como objetos GeneXus Theme (archivos .CSS).
Por otro lado, también se podrá desde la base de conocimiento salvar un Theme con extensión .XML de
manera de poder editarlo y modificarlo por fuera de GeneXus.
Con esto se logra independizar el trabajo de diseño de las páginas, del desarrollo de la aplicación.
Dado un diseño en formato XML (un Template creado con el editor por fuera de GeneXus), se puede
incorporarlo a la base de conocimiento rápidamente siguiendo los siguientes pasos:
Abrir el Template usando el editor desde dentro de GeneXus (opción File / Open Template)
Salvar el Template como un Theme (opción File / Save As)
OPCIÓN SAVE AS
Cuando el Editor es ejecutado desde dentro de GeneXus, mediante la opción del menú : File / Save
As se puede:
De lo contrario (si el checkbox está deshabilitado), se habilita la opción File Name, para ingresar el nombre
que se le dará al archivo XML generado.
Si el Editor se ejecuta por fuera de GeneXus la única opción del File / Save As es guardar un Template
como otro Template.
OPTIONS / CUSTOMIZE / TEMPLATES
En el Menú Options / Customize del editor de temas se presenta el siguiente diálogo:
Mediante este diálogo se incorporan archivos XML al Editor, y se determina uno de ellos como “Default
Template”. El default Template se usa para:
Inicializar el Theme que se crea automáticamente cada vez que se crea una nueva base de
conocimiento.
Para inicializar un Theme si se crea desde el menú de GeneXus (Object / New Theme).
Los templates “Custom” se graban en el registry de la máquina, y por lo general solo va a ser necesario
incorporar aquellos que se sepa que se van a usar habitualmente como base para crear Themes.
Notas:
Se puede optar por crear un XML o un objeto Theme GeneXus. Si el check “GeneXus” está
seleccionado, se creará un objeto Theme, de lo contrario, se crea un Template.
GeneXus distribuye nueve templates (archivos con extensión .XML) que podrán ser usados
opcionalmente como default. Estos quedan en el folder “THEMES” de la instalación de
GeneXus.
Los Templates que son incluidos con la versión son los siguientes:
Beach.xml
Classic.xml
Executive.xml
Extreme.xml
Fancy.xml
Fantastic.xml
Light.xml
PinkPanther.xml
Safari.xml
Los cuatro primeros son “serios” y siguen las recomendaciones de "buen uso" del diseño en Internet,
el resto son divertidos y radicales.
OPTIONS / CUSTOMIZE / EDITORS
Mediante el menú del editor Options/Customize/Editors es posible seleccionar el tipo de diálogo
para los colores.
Default
Designer
Si se usa el diálogo "Designer", y se definen “Custom Colors” (botón “Add to Custom Colors”), estos
valores son almacenados con el Theme.
De esta forma si se define un conjunto de colores básicos para el Theme, estarán disponibles cada
vez que se quiera editar. Por ejemplo: si se crea un Theme Gold (toda una combinación de amarillos
y naranjas), en los custom colors quedan los colores definidos como custom.
El editor como aplicación independiente
Usando el editor desde fuera de GeneXus, se pueden salvar los Themes en archivos con extensión
XML.
Se puede llamar al editor desde fuera de GeneXus, haciendo doble clic en el GXThemeEditor.exe o desde
línea de comandos pasándole como parámetro opcionalmente un archivo con extensión .XML.
De forma de distinguir cuando se edita un Template de cuando se edita un Theme, la interfaz del editor
cambia en el siguiente aspecto:
El color de fondo del Treeview es gris y no blanco como en el caso de cuando se edita un Theme
GeneXus.
Cuando se crea una nueva base de conocimiento en GeneXus, se crea un objeto Theme por defecto.
Para la inicialización de este objeto se utiliza el Theme definido como Default en el editor (“Default
Template” como se vio anteriormente).
Interacción diseñador – desarrollador de la aplicación Web
Debido a las exigencias de un buen diseño estético del sitio, por lo general es necesario contratar el
servicio de un diseñador gráfico. De ahí es que surge la necesidad de una buena interacción entre el
diseñador y quien programa la aplicación, e incluso el hecho de paralelizar ambas tareas.
Veremos en un ejemplo práctico, como a través del Editor de Temas, se logra independizar el diseño
de las páginas, del desarrollo de la funcionalidad de la aplicación.
El diseñador gráfico (sin tener GeneXus instalado en su máquina), se instalará el Editor de Temas a
través de un setup de nombre GXThemeEditor.exe .
Una vez abierto el editor de temas como aplicación independiente a GeneXus, “diseñaremos” un
Template y lo salvaremos en algún directorio (es un archivo con extensión XML).
Haga clic aquí para ver como creamos el Template por fuera de GeneXus.
Una vez salvado el Template en algún directorio, vamos a ejecutar esta vez el Editor de Temas desde
adentro de la aplicación GeneXus (mediante la opción “Tools / Theme Editor”).
Para editar el Template anteriormente creado, ir al menú del Editor de Temas “File / Open
Template” y seleccionar el Template del directorio donde lo hemos guardado (con extensión XML).
Para salvarlo como un Theme de la base de conocimiento, ir al menú “File / Save As”, y estando
seleccionada la opción GeneXus del diálogo, salvarlo con el nombre “Agency”.
Una vez que es un Theme de la base de conocimiento, lo podemos asociar a la propiedad “Theme”
del modelo.
Haga clic aquí para ver como integramos el Template anteriormente creado, al modelo del curso.
INTRODUCCIÓN
Los reportes definen procesos no interactivos de extracción –consulta– de datos. Son listados que
pueden emitirse por impresora, visualizarse por pantalla, o grabarse en un archivo.
Decimos que son procesos no interactivos, porque primero se extraen los datos y luego se muestran,
no habiendo interacción con el usuario durante el proceso de extracción. El proceso es solo de
extracción: no pueden actualizarse los datos leídos.
En el presente capítulo estudiaremos las particularidades de este tipo de objetos en ambientes Web.
Una solución para la generación de reportes en Web es trabajar con reportes PDF.
Con este tipo de reporte, se cuenta con mayor potencialidad para el desarrollo de aplicaciones Web.
El reporte generado como PDF puede visualizarse directamente desde el browser, así como también
grabarlo en el disco del servidor para luego procesarlo.
El reporte se podrá llamar desde el objeto Web tanto con el comando o función LINK como con el
comando CALL. También es posible abrir el Acrobat Reader e ingresar directamente la URL.
Configuración de propiedades
El cliente que vaya a ejecutar el reporte ya sea que lo va a visualizar en el browser o que lo va a
ejecutar luego de salvarlo a un archivo, tiene que tener instalado el Acrobat Reader.
Observaciones
En este tipo de reportes se debe tener en cuenta que no se pueden utilizar la regla o función msg,
así como la regla ask.
Al definir que un objeto es main (en este caso un Reporte, pero podría ser una Transacción, Web
Panel, etc.), GeneXus genera un programa ejecutable con la lógica del objeto mismo y la de todos los
objetos invocados directa o indirectamente por él.
El programa ejecutable generado se podrá compilar y ejecutar de forma independiente, es decir, al
seleccionar Build / Run se verá como programa independiente del Developer Menu y podrá
compilarse y ejecutarse.
La definición de un objeto como main se realiza editando las propiedades del objeto, y configurando
la propiedad “Main program” del mismo con valor “True”.
Lo siguiente que haremos es crear un reporte en formato PDF que pueda ser visualizado desde el
browser, y referenciado con un link desde el Web Panel Flights, de manera de poder imprimir todos
los datos con respecto al vuelo.
(Puede diseñar el layout del reporte como Usted lo crea más conveniente)
Lo que haremos es navegar por la tabla FLIGHTS para el número de vuelo recibido por parámetro y
luego navegaremos por la tabla PRICES de dicho vuelo.
Es necesario configurar las siguientes propiedades al objeto reporte recién creado:
Main
Y la siguiente rule:
output_file('Flight.pdf','PDF');
Para eso, agregar un textblock en el form del Web Panel, de nombre “PrintFlight”, y en el evento
Start agregar:
PrintFlight.Link = link(RFlight )
INTRODUCCIÓN
Una pregunta muy importante a la hora de desarrollar una aplicación para Internet, es la siguiente:
¿Es segura nuestra aplicación en Internet?
Como la seguridad es un concepto muy amplio, la respuesta a esta pregunta no es sencilla. Sin
embargo, dependiendo del tipo de aplicación que se está desarrollando, este punto puede ser
crucial.
Se puede decir que al publicar una aplicación en Internet, se tienen 3 niveles distintos de seguridad:
A lo largo de este capítulo se va a desarrollar cada uno de los puntos mencionados anteriormente.
Cuando se habla de la seguridad a nivel del servidor Web, se están enfrentando básicamente los
siguientes riesgos:
Intercepción de información
Desde siempre, existe una única tecnología que provee los principios para resolver estos problemas:
CRIPTOGRAFIA.
Existen servidores Web, que pueden trabajar como servidores seguros. Un servidor seguro es un
servidor Web, al cual se le habilitó la posibilidad de encriptar los datos que se envían al browser, así
como desencriptar la información recibida del mismo.
El standard más conocido de autenticación y encriptación de datos para el Web es el SSL. Este
standard fue propuesto por Netscape Communications Corporation y es el que soportan la mayoría
de los browsers (Internet Explorer, Netscape).
La seguridad ofrecida por el servidor Web, depende en parte también del largo del certificado
soportado. Cuanto más largo sea el mismo más segura es la comunicación de los datos. Hay que
destacar que los servidores seguros protegen “únicamente” la información confidencial de ser
interceptada por terceros, pero sin seguridad a nivel del sistema el servidor Web sigue siendo
vulnerable a ataques.
La property “Protocol Specification” aplica a la generación automática de links entre Web Panels, y
el objetivo es identificar el protocolo por defecto a usar cuando se construyen los links (HTTP,
HTTPS).
La mayor parte de los riesgos que se presentan al tener un servidor Web público son asumidos por el
administrador del sitio. Desde el momento que se instala un servidor Web en un sitio, se abre para la
comunidad Internet una “ventana” a la red de área local. La mayor parte de los usuarios únicamente
visitan el sitio, otros, sin embargo intentarán entrar por la “ventana” abierta. Los resultados pueden
ser variados, desde el simple descubrimiento que la página principal del sitio Web fue cambiada,
hasta el robo de la base de datos que contiene la información de sus clientes.
Es entonces importante que el administrador del sistema defina políticas de seguridad, así como
tome las medidas necesarias para evitar el acceso de usuarios no deseados. Estas medidas pueden
ser a nivel del sistema operativo (restringir las operaciones que se pueden realizar, limitar los
permisos sobre documentos y directorios, deshabilitar servicios no utilizados, etc.), como a nivel del
servidor (aislamiento de la red, instalación de firewall).
Existe abundante documentación sobre el tema, que es recomendable leer, para saber que pasos
debería seguir al publicar documentos, o aplicaciones en su sitio Web.
Bibliografía
Verisign:
http://www.verisign.com/products/site/faq/40-bit.html#6
El correo:
http://www.correo.com.uy/CorreoCert/sitio_seguro.htm
Microsoft:
http://www.microsoft.com/resources/documentation/WindowsServ/2003/enterprise/proddocs/en-
us/Default.asp?url=/resources/documentation/WindowsServ/2003/enterprise/proddocs/en-
us/iis_security.asp
http://www.microsoft.com/technet/security/topics/hardsys/default.mspx#XSLTfullModule1221211
20120
http://www.securityfocus.com/infocus/1694
La seguridad a nivel de la base de datos es también un punto sensible a la hora de publicar una
aplicación en Internet. Es de fundamental importancia evitar que usuarios no autorizados puedan
acceder a los datos corporativos, así como que un usuario autorizado realice operaciones que le
deberían estar negadas.
A nivel de la aplicación, la seguridad depende del tipo de aplicación que se esté desarrollando. La
implementación de controles de seguridad, es importante en aplicaciones en las cuales los usuarios
acceden a información confidencial, como por ejemplo sus datos personales. La razón por la cual son
necesarios dichos controles, es que los parámetros que se pasan entre objetos Web (y entre páginas
dinámicas en general) viajan visibles al usuario, como por ejemplo:
http://www.artech.com.uy/cgibin/hmyapp.exe?1,’NOMBRE’.
Por lo tanto, por más que se disponga de una página de login, donde se valida el usuario y su
contraseña para ingresar al sistema, el usuario eventualmente podría saltearse la misma, ingresando
en el navegador la URL de la siguiente página con un código de usuario válido.
Para evitar que se burle el control de acceso y permitir que se acceda a información confidencial, es
que se debe agregar algún tipo de control adicional de seguridad.
Manejo de sesiones
El uso de sesiones se compone de una Transacción “Security” que almacena el usuario logueado, un número
randómico de sesión y la fecha y hora del comienzo de la misma. Mediante este número de sesión se controla
que un usuario no pueda acceder a los datos de otro usuario.
Cada vez que el usuario ingresa a una página del sistema, se chequea el número de usuario y el
número de sesión. Si estos no se corresponden con los datos almacenados en la tabla SECURITY, se
muestra una pantalla indicando el error y se vuelve al usuario a la página donde se pide login y
password nuevamente. Este número de sesión es válido por un tiempo determinado que se
configura en el procedimiento. Si el usuario está logueado por más de dicha cantidad de tiempo, se
muestra la misma pantalla de error.
La primera vez que un usuario ingresa al sitio debe registrarse al mismo, creando un nuevo usuario
(navegando a través del link “Click here to complete a brief registration form”, el cual lo lleva a la
Transacción “Users”). De esa forma se da de alta el usuario, y se crea un registro en la tabla
SECURITY con el identificador del usuario, el número randómico de sesión, la fecha y hora de la
registración.
Luego se llama a la página donde se muestra la información a la cual únicamente los usuarios
registrados pueden acceder, en este caso, ingresar al Web Panel “MainSearch” para hacer consultas
sobre los vuelos.
En el evento Start del Web Panel “MainSearch”, se llama al procedimiento “Checksesion”. Este
procedimiento verifica que el número de sesión del usuario recibido se corresponda con el que se
encuentra almacenado, así como su validez. Si alguna de las condiciones anteriores no se cumple, se
llama a una página de error, donde se explica al usuario la causa del mismo. Hay que darse cuenta
que en ese caso nunca llegaría a visualizarse la página “MainSearch”.
El otro caso que queda por analizar, es cuando el usuario ya está registrado. En este caso en el
evento que valida el usuario se realiza una llamada al procedimiento “GenSesNum” que actualiza en
la tabla SECURITY el número de sesión asignado al usuario, así como la fecha y hora de generación
del mismo. Igualmente que en el caso anterior, en el Web Panel “MainSearch” se invoca al
procedimiento “CheckSession” para validar la sesión.
Funciones de cookies
El objetivo es proveer funciones que permitan leer y grabar cookies desde objetos Web generados
por GeneXus.
Las cookies son archivos pequeños que se graban desde un Web site en las máquinas de los clientes.
Los programas CGI o cualquier aplicación que corre en un servidor, puede leer o grabar las cookies
en el cliente.
El uso más común de las cookies es la identificación de usuarios. Cuando un usuario se registra en un
Web site (Portal o E-Store), el sitio graba una cookie en la máquina del cliente con la identificación
del cliente. De este modo la próxima vez que el cliente visite este sitio, intenta leer la cookie y si la
misma existe usa el valor de la cookie para identificar el usuario y recuperar sus preferencias desde
una base de datos.
También existen otros usos de las cookies, como rotación de contenido (especialmente avisos),
mantener estado de una aplicación, etc. Incluso se pueden usar como método de almacenar el
“carrito de compras” de modo que la información del mismo quede en la máquina cliente y se
mantiene entre conexiones.
Como se menciona anteriormente, generalmente se usa una cookie para identificar el usuario (en
algunos casos, una para la sesión, en otros para el usuario), aunque se podrían poner todos los
valores de las preferencias en cookies. Lo ideal es tener una clave que viaje y con esta clave leer la
información del usuario. De este modo la información del usuario no viaja hacia el cliente, ni está en
la URL. (Ej. tarjetas de crédito, nombre, dirección) simplemente permanece en el servidor.
Hay que tener en cuenta que existe un límite en cuanto a la cantidad de cookies que el cliente puede
aceptar. El máximo son 300 cookies en total por cliente (para todos los servidores juntos por cada
browser/cliente) y 20 cookies por servidor o dominio lo cual quiere decir que si una aplicación graba
más de 20 cookies las últimas van a borrar los valores de las primeras. Además existe un límite de
tamaño de 4K por cookie, si una cookie supera ese límite es truncada.
El usuario puede preferir no grabar la cookie permanentemente (por Ej. si está accediendo desde
una máquina pública como podría ser un cybercafe) o incluso puede deshabilitar el uso de cookies,
por lo cual esta no debe ser la única manera de identificar al usuario, sino que se debe poder usar un
método alternativo en caso de que el browser no soporte o no tenga habilitado el manejo de
cookies.
Otra particularidad es que el lugar donde se almacenan las cookies (al menos en Windows) depende
del browser, por lo que si un usuario tiene más de un browser, cada uno tendrá un conjunto
independiente de cookies.
1. El usuario se conecta a un servidor que por alguna razón quiere grabar una cookie.
2. En la respuesta (HTML Headers), se indica el nombre y valor de la cookie a grabar, así como
otros valores (el más relevante es la fecha de expiración).
4. Cada vez que el usuario se conecte a una URL de este dominio el browser enviará al servidor
las cookies que se hayan grabado desde el dominio y no hayan expirado.
Se dispone de las siguientes funciones, las que pueden ser utilizadas en cualquier objeto GeneXus, el
resultado tiene sentido únicamente si dicho objeto fue llamado en forma directa o indirecta por un
objeto Web o está ejecutando en un ambiente Web.
GETCOOKIE
Permite leer una cookie, devolviendo un string con el valor. Si no encuentra la cookie (o no la puede leer por
estar deshabilitada) devuelve el string vacío.
Sintaxis
&var_char = GetCookie(NombreCookie)
NombreCookie: carácter
&var_char: carácter
SETCOOKIE
Permite grabar una cookie. Devuelve 0 (cero) si el resultado es correcto, otro valor si hubo algún
error.
Sintaxis
Los parámetros entre paréntesis rectos son opcionales. Si alguno de los parámetros va nulo se
asume el default.
Domain-name: Carácter. Dominio donde es válida la cookie. Por defecto es el dominio desde donde
se creó.
Nota: Si se activa el trace para el generador C/SQL, y se pone TraceLevel=4 o mayor se verá en el
trace todas las cookies que llegan al programa. Se imprimen una por cada línea precedidos por la
palabra cookie.
Observaciones
Las funciones mencionadas anteriormente siempre devuelven 0. La única forma de detectar si una
cookie fue almacenada es leerla. En consecuencia no se puede obtener la configuración del browser.
Ejemplos
Aquí se está grabando una cookie -válida para todo el dominio- de nombre ID_USER con el valor
correspondiente al atributo UsrId y que expirará el 1° de Enero de 2002.
Aquí se está grabando una cookie -válida para los Web Panels de la misma aplicación -de nombre
SESSION_ID_GX- con el valor correspondiente a la variable &Strsession. La cookie expirará al cerrar
la sesión del browser.
&Op= SetCookie(“USR_PAIS”, “UY”, “/”, ADDYR(&Today, 1), “otrodom.artech.com.uy”, 1)
Aquí se está grabando una cookie -válida para todo el dominio ‘otrodom’- de nombre USER_PAIS con
el valor UY y que expirará exactamente dentro de un año.
WebSession es un tipo de datos de GeneXus que permite almacenar datos en una sesión de usuario
del servidor Web. De esta manera se pueden tener variables globales, accesibles mientras la sesión
esté activa. Los mismos aplican a los siguientes objetos: Transacciones, Web Panels, Procedimientos;
para el lenguaje Java.
Descripción
Los servidores Web permiten manejar el concepto de sesión. Una sesión se identifica por una clave
única, que se mantiene mientras el usuario continúe en el sitio Web. El objeto WebSession permite
almacenar información que será visible desde cualquier objeto Web dentro de la sesión activa como
si fueran variables globales al sitio.
Para utilizar el objeto WebSession, se debe definir una variable de este mismo tipo y aplicarles los
métodos y propiedades adecuados.
Propiedades
Id
Ejemplo:
&Iden = &Session.Id
Métodos
Set(key, value)
Permite hacer una entrada en la sesión activa. Key y value deben ser del tipo String.
Ejemplo:
&Session.set(“user”, &User)
Get(key)
Retorna un String correspondiente a la entrada key de la sesiones. En caso de que la clave no exista retorna
el String nulo.
Ejemplo:
&User = &session.get(“user”)
Remove(key)
Ejemplo:
&Session.remove(“user”)
Destroy()
Detruye el contenido de la sesión. Es recomendable utilizarlo cuando el usuario hace un “logout”, si es que
existe este concepto en la misma.
Ejemplo:
&Session.destroy()
Consideraciones Generales
La validez de la Websession es similar a la validez de las cookies que solo valen por la sesión. Esto
quiere decir que si se abre una instancia nueva del browser, se pierde la sesión, pero si se abre en
una ventana nueva se mantiene.
Los datos y el ID de una sesión son diferentes para cada generador. Esto implica que no puedo hacer
un link de un Web Panel .NET a un Web Panel Java y mantener los valores de la sesión
Encriptación de Parámetros
Los objetos Web generados con GeneXus, permiten visualizar los parámetros que se pasan entre los
objetos en la barra de dirección del browser. Esto hace que, si se pasa información reservada como
parámetro entre objetos Web (Número de cliente, por ejemplo), las aplicaciones no sean muy
confiables en cuanto a la seguridad, porque un usuario podría simplemente cambiar el valor de
dicho parámetro en la URL y disponer de información sobre la que no debería tener acceso. No
sucede lo mismo si se utilizan cookies, en este caso no hay problemas de seguridad.
Es por eso que se hace necesario pasar los parámetros sin que el usuario de la aplicación los conozca
o sea encriptar los parámetros.
En GeneXus se implementa la encriptación de los parámetros de los objetos Web que van en la URL
en forma automática y transparente para el usuario. Esto aplica a los siguientes objetos Web: Web
Panels, Transacciones Web.
Descripción
Que los usuarios finales no sepan el o los datos que van en los parámetros
Que los usuarios finales no puedan modificar el o los datos que van en los parámetros
Se agrega la propiedad “Encrypt URL Parameters” a nivel de modelo, en el grupo “Web Information”
y también a nivel de objeto.
No: Indica que No se van a encriptar los parámetros que van en la URL de los objetos Web, siendo
éste el valor por defecto.
Session Key: Indica que se van a encriptar los parámetros que van en la URL, utilizando una clave
diferente para cada sesión. La encriptación se realiza a través del uso de cookies locales.Este valor
ofrece un nivel de seguridad mayor, pero no permite compartir URLs. Esto significa que no es posible
para un usuario X enviar una URL que tenga parámetros a otro usuario Y, ya que en este caso la URL
no va a funcionar porque se necesita la cookie correspondiente para la desencriptación.
Site Key: Se encriptan los parámetros que van en la URL de los objetos Web, pero la clave de
encriptación va a ser la misma para todo el sitio. En este caso no se utilizan cookies. Esto da un nivel
de seguridad menor pero facilita el traspaso de links.
La propiedad a nivel de objeto, además de los valores mencionados tiene el valor “Use model’s
property value”. Este valor indica que se va a tomar el valor de la propiedad del modelo para realizar
la encriptación de ese objeto. Este es el valor por defecto.
Consideraciones Generales
En cambio, si se abre una sesión del browser, y luego se ejecuta nuevamente el exe del browser para
abrir una nueva ventana, las dos ventanas no pertencen a la misma instancia.
Con esto, si se ejecutan objetos Web, y se configuró la propiedad del modelo (o la propiedad a nivel
de objeto) con el valor “Session Key”, la cookie que se defina para guardar este valor va a funcionar
en las sesiones del browser que compartan la misma instancia.
Cuando se utiliza la propiedad a nivel de objeto para encriptar parámetros, y se realizan varios
llamados entre objetos Web, se debe tener en cuenta que los valores utilizados por todos lo objetos
involucrados debe ser el mismo. Por ejemplo: Si se tiene un Web Panel que llama a otro pasándole
parámetros, y se quieren visualizar estos parámetros encriptados, en ambos Web Panels se debe
configurar el mismo valor para la propiedad “Encrypt URL Parameters”. Lo mismo sucede si el árbol
de llamadas involucra a más objetos Web, todos (los llamados y los llamadores) deben tener
configurada la propiedad “Encrypt URL Parameters” y todos deben tener el mismo valor en dicha
propiedad.
Ejemplos
Si se tiene un Web Panel que recibe parámetros y no se utiliza la encriptación de parámetros, la URL
correspondiente al Web Panel será del estilo:
http://localhost/HINGRESO_WebObj/hdospar.asp?2,3
http://localhost/HINGRESO_WebObj/hdospar.asp?lQ/tK1lefxCZMVoXrnmrTQ==
A continuación se realiza una comparación entre las soluciones disponibles para agregar seguridad
a una aplicación Web.
Cookies
Ventajas
No es necesario el pasaje de parámetros entre Web Panels, ya que los valores se graban en la
cookie.
Desventajas
Tienen limitaciones en cuanto al tamaño máximo, cantidad de cookies que se pueden grabar.
Se tiene dependencia de la configuración del browser.
Manejo de sesiones
Ventajas
Desventajas
Mayor complejidad de programación
Pérdida de información: si el usuario pasa a una página estática, y luego vuelve a ingresar la
URL en el browser, debe volver a loguearse.
Ventajas
Desventajas
Depende de la configuración del browser. No permite compartir datos si los objetos son
generados en diferentes lenguajes. Por el momento no es soportado por C/SQL.
Encriptación de la URL
Ventajas
Desventajas
Además de los temas vistos anteriormente, existen algunas características particulares para cada
generador que permiten brindar mayor seguridad a las aplicaciones.
Generador .NET
Para el Generador .NET existen las siguientes propiedades a nivel del modelo:
Generate strong named assemblies
SessionState
La primera, determina que los objetos main y/o dlls (assemblies) generados tengan un nombre único
o no. Esto permite acceder a un conjunto de ventajas importantes que provee el Framework .NET,
como ser la configuración de seguridad para el assembly.
http://www.gxtechnical.com/gxdlsp/pub/iehelp.htm?genexus/csharp/docum/manuals/9.0/manualn
et90.htm
Generador Java
Con el Generador Java existe la posibilidad de conectar un servidor Web al motor de servlets, de
forma de que los requerimientos vayan directamente al servidor Web (al puerto 80). Luego éste los
redirecciona al motor de servlets (puerto 8080 por defecto), quien es que los resuelve, y manda la
respuesta al servidor Web. El motor de servlets ejecuta los servlets, y es quien establece la conexión
a la base de datos. El servidor Web solo sirve de "intermediario" como una capa más de seguridad,
pero allí no se ejecuta nada. Este servidor puede estar en el DMZ entre dos firewalls, uno que lo une
a Internet, y otro a la red local.
Por más detalles técnicos de este tema, se recomienda acceder al siguiente link:
http://www2.gxtechnical.com/portal/hgxpp001.aspx?15,4,61,O,S,0,,17187;S;0;A;0;0;;;;;;;;;;;;;;;;;A;%2
0%20/%20%20/%20%20;;0;9;;17187;;99;;0;1;%200;N;N;S;B;B
Como hemos visto hasta el momento, si bien el Web Panel MainSearch permite realizar consultas
para que pueda ver los detalles de un vuelo se exige que el usuario ya se haya identificado y que sea
por supuesto un usuario válido.
En caso de ser un usuario registrado y haberse identificado, se mostrarán los detalles del vuelo y
precios del mismo, pero en caso contrario se le dará al usuario un mensaje diciéndole que "Debe
identificarse antes de realizar alguna compra".
Todo esto es lo que tenemos que implementar en el Web Panel MainSearch. Es decir, que a partir
del link asociado al atributo FlightDsc se requiere que la aplicación sea segura.
Utilizaremos cookies “temporales” para evitar que todo usuario que se registre al sitio desde el
mismo computador utilice la misma información de conexión.
Disponemos de un Business Object (security.xpz) que brinda los objetos necesarios para definir la
“seguridad” en las aplicaciones Internet utilizando cookies.
Una tabla denominada Security donde se almacena para cada nuevo usuario el número
generado en forma aleatoria para su sesión, así como la fecha y hora de la última sesión
activa.
SecId*
SecRnd (Número de sesión randómico)
SecDate (Fecha de Inicio de Sesión)
SecHour (Hora de Inicio de Sesión)
Una cookie denominada SECURITY que concatena (separados por una coma) el número
identificador del usuario (atributo UserId), así como un número generado en forma
aleatoria de la sesión de este usuario (atributo SecRnd).
A los efectos de una buena comprensión del xpz, se describen los objetos que lo integran y
utilizaremos.
SECURITY
Es la Transacción que define la tabla de SECURITY.
INSERTSEC
Este Procedimiento da de alta en la tabla SECURITY la primera vez que el usuario inicia una sesión en
el Web.
CHECKSESSION
Este procedimiento valida el número de sesión recibido con el usuario que está logueado, y devuelve
el código de validación resultante. A la sesión se le da una validez de 1 día.
Se distinguen tres casos: cuando el usuario tiene iniciada una sesión vigente (valor S), cuando el
usuario tiene una sesión vencida (valor V) y cuando el usuario tiene una sesión, pero no coincide el
número randómico de sesión (valor I).
GENSESNUM
Este procedimiento actualiza el número randómico de sesión del usuario, junto con la fecha y hora
en que se logueó por última vez.
RETSTR
Este procedimiento devuelve los dos valores almacenados en la cookie: el número de usuario y el
número de sesión.
ERROR
Este Web Panel se invoca siempre que sea necesario cancelar la ejecución de la aplicación (por
ejemplo: cuando la sesión ya no está vigente se invoca automáticamente a este Web Panel,
desplegándole al usuario el mensaje correspondiente).
La cookie se debe grabar cuando el usuario se registra en el sitio por primera vez (en la Transacción TUsers) y cada vez que se identifique.
1) Cuando el usuario se identifica,luego de chequear que el usuario y password ingresados son válidos, tenemos que grabar una cookie (con
la función SetCookie), y luego en el evento Start del Web Panel Flights de “acceso limitado a usuarios registrados” tenemos que leer la
cookie (con la función GetCookie). Como definimos anteriormente un web component para encapsular el procedimiento de login,
simplemente debemos editar el evento “Enter” del Web Panel definido como web component y realizar la siguiente modificación:
Event Enter
For each
&UserId = UserId
If UserPwd = &UserPwd
&SecRnd = Udp(PGenSesNum,UserId)
&CookieVal = Concat(trim(Str(UserId)),trim(Str(&SecRnd)),',')
&result = SetCookie('SECURITY',&CookieVal)
Msg( 'Welcome')
Else
Msg('Invalid Password')
EndIf
when none
Endfor
2) El otro lugar donde tenemos que grabar una cookie es cuando se da de alta un usuario nuevo. Es decir, que en la Transacción Users
(TUsers), luego de dar de alta el usuario, tenemos que grabar una cookie en el PC Usuario con el UserId del usuario nuevo y el número de
sesión randómico. Para esto vamos a crear un procedimiento Login con el siguiente código:
&SecRnd = Udp(PGenSesNum,&UserId)
&CookieVal = Concat(trim(Str(&UserId)),trim(Str(&SecRnd)),',')
&result = SetCookie('SECURITY',&CookieVal)
Este procedimiento debería recibir como parámetro la variable &UserId. En la Transacción TUsers, deberíamos agregar en las reglas:
Call(Plogin,UserId) on AfterComplete;
¿Dónde tenemos que leer las Cookies? Es decir ¿dónde debemos invocar a la
función GetCookie?
Como ya dijimos antes, todos los Web Panels del sitio de “acceso limitado a usuarios registrados”, deben realizar el control de la seguridad
leyendo la cookie y comparando los valores obtenidos con los valores almacenados en la tabla de SECURITY. En nuestro caso, en el link
asociado al atributo FlightDsc.
Hagamos el control en el Web Panel “FLIGHTS” de que el usuario tiene que ser un usuario
“registrado” para poder VER DETALLES Y PRECIOS ...
Event Flights.Load
&interesting = Loadbitmap("int_unsel.bmp")
&CookieVal = GetCookie('SECURITY')
Call(PRetStr,&CookieVal,&UsrStr,&SecStr)
&UserId = Val(&UsrStr)
&SecRnd = Val(&SecStr)
&result = Udp(PCheckSession,&UserId,&SecRnd)
Call(HError)
Endif
EndEvent
Notas:
Observe que para el usuario de prueba que se estaba usando en los ejercicios anteriores, al
momento de creado no se tenía en cuenta la seguridad del sistema, por lo cual no fue dado
de alta en la tabla de seguridad, y cualquier intento de realizar una compra con él va a dar
error. Entonces, para probar el ejercicio hecho en este capítulo, dé de alta un nuevo usuario
a través de la Transacción Users.
Patterns es una herramienta, que se puede utilizar tanto desde GeneXus como en forma
independiente. Permitiendo aplicar a una base de conocimiento cierto patrón (pattern), y que se
generen todos los objetos GeneXus necesarios para implementar el patrón, para aquellas instancias
que se hayan seleccionado.
En este capítulo profundizaremos en los patterns y las formas de utilizar dicha herramienta como
medio para obtener una mayor productividad en el desarrollo de las aplicaciones Web.
Generalidades
Es común sentir al desarrollar aplicaciones que algunas partes son muy similares pero no
exactamente iguales.
Por ejemplo, si se tienen clientes y productos, si bien los actores de la realidad (clientes y productos)
son totalmente diferentes, los “Trabajar con” para cada uno de ellos tienen muchas cosas en común:
grid en el form
Esta situación es llamada “Pattern” (patrón) y ha sido un tema muy popular en la industria del
software recientemente.
Dado que con GeneXus trabajamos a nivel de conocimiento y no de código, aplicamos el concepto
de patrones a reusar conocimiento.
Hemos desarrollado un marco de trabajo con las siguientes características:
• Activo: Se generan objetos GeneXus que implementan cierto patrón para una o varias
instancias elegidas.
Descripción de la herramienta
Patterns es una herramienta que es parte de GeneXus 9.0 (Tools / Patterns), que puede ejecutarse
también como aplicación independiente.
Básicamente la herramienta Patterns permite aplicar a una base de conocimiento cierto patrón
(Pattern), y generar todos los objetos GeneXus que implementen el Pattern para aquellas instancias
que se hayan seleccionado. Es importante tener en cuenta que la base de conocimiento debe estar
en diseño para poder utilizarla.
Existe un conjunto de Patterns muy útiles ya definidos (al instalar la herramienta se instalan) para
que el desarrollador pueda comenzar a usar dichos patrones rápidamente.
A su vez la herramienta permite crear Patterns nuevos, siendo esta una tarea un poco más compleja.
Requerimientos
Esta herramienta se puede utilizar únicamente con los generadores .NET y Java. Para obtener más
detalles de los requerimientos de software de instalaciónla ver la siguiente página:
http://wiki.gxtechnical.com/wiki/tiki-index.php?page=PatternsInstallation
Patterns existentes
Work With: “Trabajar con” en Web; genera a partir de una Transacción (o para todas aquellas
Transacciones que se deseen), todos los objetos necesarios para tener una aplicación Web: trabajar
con, views, seguridad, etc..
Bill of materials: Permite generar a partir de una Transacción, otra que representa la relación
compuesto–componente.
OAV: Objeto-Atributo-Valor; genera a partir de una Transacción otras dos Transacciones que
permiten extender la original, con el objetivo de permitir definir atributos en tiempo de ejecución.
Además, seguimos trabajando en la definición de nuevos Patterns. Tenemos un catálogo con una
lista de Patterns, algunos de los cuales ya están implementados y otros sugeridos para una futura
implementación. Para acceder al catálogo:
http://wiki.gxtechnical.com/wiki/tiki-index.php?page=Business+Patterns+Catalog
MasterPage = MyMPage
2) A continuación, mostraremos cómo hacer para modificar los “Instance File”. En este caso
quitaremos algunos atributos del grid de los Work With.
3) Build / Configure GeneXus Integration. Desde esta pantalla configuraremos las opciones de la
integración del resultado de aplicar el pattern Work With en nuestra base de conocimiento.
4) Procederemos a aplicar y generar los objetos resultantes de aplicar el pattern. Para ello,
marcaremos todas las Transacciones y con el botón derecho seleccionamos “Generate, Apply and
Consolidate”, como se muestra aquí.
Uso de la herramienta
A continuación veremos los distintos pasos a seguir para el uso de la herramienta Patterns y como
obtener rápidamente una aplicación Web ejecutando en este caso el Pattern Work With. Donde
los objetos generados estarán basados en la definición que se realizó para ese patrón y a su vez
quedarán generados con código de calidad, y con lo cual se podrá visualizar el aumento de
productividad que se obtiene al utilizar la herramienta.
Paso 1
Cuando se trabaja con la herramienta Patterns con una base de conocimiento por primera vez, se
presenta un diálogo cuyo título es “Workspace Configuration”. Este diálogo permite configurar
algunas opciones relacionadas a la base de conocimiento, otras opciones relacionadas al pattern a
ser aplicado, y otras opciones relacionadas a operaciones de GeneXus (impactar, especificar, etc.)
que pueden ejecutarse utilizando la herramienta Patterns. En este punto inicial puede cerrarse este
diálogo si se desea, y posteriormente es posible ingresar al mismo, mediante el ítem Build /
Configure GX Integration (ver paso 8).
Paso 2
Se debe seleccionar en el combo box mostrado en la barra de herramientas, el pattern que se desea
aplicar:
Paso 4
Debemos obtener un “Instance File” por cada caso al cual queramos aplicar el pattern. El “Instance
file” es un archivo XML con los datos propios de la instancia.
Si bien es posible crear cada “Instance File” de cero, los patterns suelen proveer una funcionalidad
para crear “Instance Files” por defecto, y luego poder modificarlos fácilmente.
• Instance files: por cada situación o instancia a la cual se quiera aplicar el patrón, habrá que
crear un instance file con la información propia de esa instancia en particular (atributos a
mostrar, etc.). Cada instance file es en definitiva un archivo XML con los datos propios de la
instancia.
El resultado que se obtiene del proceso de instanciación de un patrón (procesando los instance files
y template files) es: un conjunto de objetos GeneXus para ser consolidados en la base de
conocimiento.
Paso 5
Cada “Instance File” es un archivo XML con estructura jerárquica, conteniendo cada uno de sus
nodos un conjunto de propiedades. La herramienta Patterns ofrece dos editores, para editar cada
“Instance File” en el panel derecho: el editor XML View y el editor Tree View.
El editor XML View permite editar los instance file directamente en su formato XML. Por su parte el
editor Tree View es mucho más amigable, sencillo de usar, y con interfaz en alto nivel que provee
mayor funcionalidad para ayudar en el proceso de edición. Por todo esto el editor Tree View es el
más usado y recomendado para usuarios no avanzados.
Paso 6
Los “Instance Files” se deben grabar. Para ello, bajo el ítem Instance se ofrecen las opciones Save
(salva el “Instance File” con el que se esté trabajando) y Save All (salva todos los “Instance Files” en
el caso que ya existan, pregunta si se desea reemplazar).
Los “Instance Files” que no se han salvado aún se visualizan con el nombre: <Transaction
Name.Pattern>*. Una vez salvados se visualizan con el nombre: Transaction Name.Pattern (ej:
Country.WorkWith).
Es importante tener en cuenta que si se generan los “Instance Files” por defecto nuevamente a
partir de las Transacciones, serán sobrescritos.
Paso 7
Una vez creados y editados los “Instance Files”, el siguiente paso es que la herramienta genere los
objetos GeneXus que implementan el pattern para las instancias. Para lo cual se cuenta con las
siguientes opciones :
A su vez es importante tener en cuenta que si se selecciona la opción Apply and Consolidate se
efectuarán también las siguientes acciones:
Se configurará como Tema por defecto de la aplicación al Tema Fantastic.
La propiedad del modelo de diseño "Base image path" se configurará con el valor anterior.
Paso 8
Para hacer más fácil todo el proceso, desde la herramienta Patterns, es posible ejecutar las acciones
que se realizan con GeneXus: impactar el modelo, especificar, generar, compilar y ejecutar.
Apply and Consolidate: Al seleccionar dicha opción, es posible ejecutar más acciones además de la
generación de objetos y consolidación. Este combo ofrece las siguientes posibilidades:
Impact, Specify, Compile, Run (Apply and Consolidate + Impact + Specify + Compile + Run)
GeneXus Version: La versión de GeneXus correspondiente a la base de conocimiento se detecta
automáticamente (puede ser 8.0 o 9.0). El modelo se especificará / generará con dicha versión.
Build Actions: Permite seleccionar qué objetos deben especificarse y generarse al seleccionar
Specify and Generate. Las opciones disponibles son:
Build All
Full Specification
Check Specification
Force Generation
Run Command: En esta opción se debe indicar la URL que se ejecutará si se seleccionó la opción
Impact, Specify, Compile, Run. Por ejemplo, se debe escribir:
“http://localhost/services/hwwsocios.aspx”. La URL debe incluir todo el camino, incluyendo el
objeto que se va a ejecutar.
La herramienta Patterns genera un Web Panel homepage y un Procedimiento para listar todos los
objetos del pattern Work With usados. Para ejecutar la homepage, se debe configurar la propiedad
“Run Command” de la siguiente manera:
Mediante GeneXus
Modificando los objetos GeneXus generados. Esta solución presenta la siguiente desventaja: en caso
de querer volver a generarlos con Patterns, se regeneran los objetos, perdiendo los cambios hechos
a los mismos.
Modificando las propiedades de las instancias (en la medida que ofrezcan lo que se
desea).
Nodo Selection
El nodo “Selection” ofrece las propiedades relacionadas al Web Panel Work With que se generará
para la instancia. Sus sub-nodos son:
Modes
Este nodo permite definir en cuáles modos se ofrecerá invocar a la Transacción. Las posibilidades y
sus valores por defecto son:
Insert: True
Update: True
Delete: True
Display: False
Insert Condition
Update Condition
Delete Condition
Display Condition
Si se define una condición asociada a un modo, la invocación para ese modo sólo se habilitará si la
evaluación de la condición es verdadera (Ejemplo: CountryId=10).
Attributes
Este nodo permite definir cuáles atributos se desean mostrar en el grid (y para cada atributo, se
pueden personalizar varias propiedades).
Orders
Permite ofrecer al usuario final varios órdenes posibles para ver el resultado de la consulta (es decir,
las líneas mostrando los datos en el grid). Utilizando el botón derecho del mouse se puede definir un
nuevo orden (su nombre y composición). Cada orden puede estar compuesto por varios atributos
(pudiendo indicar para cada uno de ellos si se desea orden ascendente o descendente). Se
presentará un combobox en el Web Panel Work With ofreciendo todos los órdenes posibles de
seleccionar, para que el usuario final elija uno y los datos se presenten en el grid ordenados por el
mismo.
Filters
Permiten definir condiciones de filtro, para que se muestren en el grid sólo los registros que
cumplan con las mismas.
Nodo View
El nodo “View” por su parte, ofrece las propiedades relacionadas al Web Panel View que se generará
para la instancia. El Web Panel View muestra toda la información de un registro, que fue
seleccionado en el grid del Web Panel Work With (la información del registro es mostrada en una
solapa de un tab control, y además hay una solapa con un grid por cada tabla directamente
subordinada, para mostrar la información relacionada).
Nodo Prompt
El nodo “Prompt” permite modificar las propiedades realcionadas a cada Prompt que es generado
por cada Transaccion de cada Work With. Este Prompt contiene toda la información necesaria para
permitir la ejecución del mismo desde la Transacción y mantiene el mismo estilo que los objetos
generados. Para invocar este objeto, se debe agregar la regla prompt(…) a la correspondiente
Transacción.
Archivos de Configuración
Al crear cada “Instance File” por defecto, podemos observar que las distintas propiedades del
“Instance File” se inicializan con valores por defecto. Dichos valores por defecto para las
propiedades, se especifican en un archivo denominado NombrePattern.config (en nuestro caso
WorkWith.config).
El archivo WorkWith.Config permite configurar algunos aspectos generales que aplicarán a todos los
objetos. Por ejemplo, las Master Pages a ser utilizadas por los objetos Web, los Web Components
utilizados como header y footer, etc..
Para editar este archivo de configuración, la herramienta Patterns ofrece el ítem: Tools/Change
Pattern Configuration, tal como se muestra a continuación:
En este archive se pueden configurar diversas propiedades tales como:
WW Configuration
THEMECLASSES
Esta opción indica las clases a ser utilizadas por el tema por defecto. Se puede utilizar cualquier otra
clase ya definida.
GRID
Page = Page.Rows – Indica cuantas filas se visualizarán en el grid.
SaveGridState – Indica si los Orders, Current Page y Filtros se guardarán para los Web Panels Work
With o no.
TAB
MaxTabs – Indica cuantos Tabs serán visualizados en un View. Si hay más Tabs que los indicados en
MaxTabs, se generará un Scroll para permitir navegar a través de los mismos.
StandardActions
DefaultMode – Indica cuando incluir la acción en un grid por defecto. Aplica a las acciones insert,
update, delete y display.
Context
Esta propiedad implementa el manejo del contexto. Por defecto, la implementación incluye una
variable llamada &Context basada en el SDT Context y un procedimiento llamado LoadContext, que
es invocado en el evento Stara e cada Web Panel. Esta característica puede ser usada, por ejemplo,
para mantener información sobre el usuario conectado a la aplicación (especialmente para la
autenticación/autorización), la empresa corriente para sistemas multi-empresa, etc.. Se puede
modificar la variable y el procedimiento invocado, modificando la sección Context en el archivo
WorkWith.Config. Por ejemplo, se puede usar la variable Context para definir un filtro: EmpCod =
&Context.CurrentEmpCod.
Security
Esta propiedad implementa la seguridad a nivel del objeto. Por defecto, la implementación incluye
un procedimiento llamado IsAuthorized, que es invocado en el evento Start de cada Web Panel, para
controlar la autorzación del acceso a dicho recurso. Si el procedimiento retorna false, significa que el
usuario no tiene autorización para ejecutar la aplicación, y por lo tanto el Web Panel de usuario no
autorizado (NotAutorized) es invocado. En a implementación de ejemplo, este procedure siempre
retorna True, se debería modificar según las necesidades del caso. Es posible modificar el objeto
invocado,modificando la sección Security en el archivo WorkWith.Config.
Después de haber aplicado el pattern Work With seguiremos avanzando en cuanto a la seguidad de
la aplicación. Para lo cual, reutilizaremos el procedure IsAuthorized para mostrar como se
programaría el acceso a los distintos objetos:
Call(PLoadContext, &Context)
&Authorized = Boolean.False
parm(in:&GxObject, out:&Authorized);
INTRODUCCIÓN
Cada vez más, el uso masivo de Internet propicia el desarrollo de aplicaciones de mayor versatilidad
y complejidad para el ambiente Web. Es por esto que está surgiendo la necesidad de aplicar una
reingeniería a las aplicaciones existentes y también, en muchos casos, la necesidad de desarrollar
nuevas aplicaciones para Internet.
Existen varias diferencias entre los ambientes GUI (aplicaciones con Interfaz de Usuario Gráfica) y
Web, las que deberán evaluarse al momento de determinar la conveniencia del tipo de aplicación a
desarrollar. La migración no debería verse como una conversión objeto a objeto sino que
normalmente es una modernización de la aplicación usando otras herramientas tales como Patterns,
GXPortal, GXFlow, Reporting, etc..
En este capítulo veremos los principales aspectos a ser tenidos en cuenta por los usuarios GeneXus.
INTRODUCCIÓN
En el desarrollo de una aplicación Web, la calidad de la interfaz con la que interactúa el usuario
determina el éxito de la aplicación. La calidad de la misma está definida por una serie de pautas y
técnicas. A este conocimiento se le llama “Usabilidad”.
La interfaz de una aplicación Web está determinada a grandes rasgos por la estructura de la
aplicación, el diseño de la misma y de su contenido.
Con estructura de la aplicación nos referimos a la ubicación de los diferentes elementos para que
sean encontrados de forma intuitiva por el usuario y utilizados de forma correcta. Hay que tener
esta estructura bien definida antes de aplicar un diseño.
El diseño del contenido permite que el mismo sea cómodamente leído y correctamente
interpretado.
A lo largo de este capítulo desarrollaremos cada uno de estos puntos para lograr aplicaciones Web
exitosas y fáciles de usar.
Estructura de la aplicación
Diseño de la aplicación
Estructura de la Aplicación
Con estructura de la aplicación nos referimos a la ubicación de los diferentes elementos para que
sean encontrados de forma intuitiva por el usuario y utilizados de forma correcta. Hay que tener
esta estructura bien definida antes de aplicar un diseño.
Es importante que la estructura del sitio esté reflejada en todas las páginas en forma consistente.
Es recomendable:
Navegación
La navegación de una aplicación permite ir a las distintas partes, sectores, páginas de la aplicación
rápidamente y en forma intuitiva. La estructura del sitio se debe reflejar en la navegación permitiendo
contestar las siguientes interrogantes:
¿Dónde estoy?
Dentro del universo de sitios/ aplicaciones Web: Esto se logra mostrando el logo del sitio/ aplicación Web
en todas las páginas. La ubicación habitual del mismo, y por lo tanto el lugar donde el usuario lo irá a buscar,
es la esquina superior izquierda. Esta imagen debe tener siempre un enlace a la página de inicio de la
aplicación o la página principal del sitio.
Usar títulos en cada una de las páginas, dentro del área de contenido de forma
que el usuario sepa dónde se encuentra.
Sitio – página
Usar nombres cortos para las páginas igual que para los sitios de modo que se
puedan visualizar bien en el cabezal de la página.
¿Dónde estaba?
Para indicar las páginas que el usuario ya visitó, conviene dejar los colores de los enlaces con los colores por
defecto del navegador.
Mostrar todas las opciones a donde puede ir el usuario desde la página actual, sin marearlo con demasiadas
opciones. Si las opciones son muchas, conviene agruparlas por áreas o sectores y dentro de los mismos
mostrar submenúes.
Si usa una herramienta de búsqueda, ésta debe de estar en todas las páginas del sitio, en un lugar siempre
visible sin tener que usar las barras de desplazamiento. El lugar más intuitivo es el cabezal superior derecho, o
la columna del menú izquierdo.
Se recomienda hacer esta funcionalidad lo más simple posible de manera que sea fácil de usar. Lo más sencillo
es tener una caja de texto y un botón que diga buscar. El uso de iconos, etiquetas, etc. necesita que el usuario
las interprete y por lo tanto demore unos segundos en entender su uso.
El resultado de la búsqueda debe ser claro, debe mostrar la cantidad de instancias encontradas, el texto usado
para realizar la búsqueda, el título de cada página que contiene el texto buscado y un enlace en ese título a la
página correspondiente.
Menúes
MENÚ SUPERIOR
Tanto en sitios corporativos como en Intranets y Extranets se usa comúnmente un menú superior
que contiene por lo general las siguientes opciones:
1. Página de Inicio
Si bien hay un enlace en el logo de cada página, nunca está de más repetirlo ya que la página inicial es a
la que se retorna con más asiduidad.
2. Acerca de, Acerca de Nosotros, Acerca de La Empresa, La Empresa, Quiénes somos, etc.
Siempre es válido un enlace a información sobre la empresa que representa ese sitio, el producto que se
vende a través del sitio, etc. que respalde la seriedad y veracidad del contenido presentado en el
mismo.
En la zona superior derecha se ubican las herramientas para encontrar páginas y contenido
dentro del sitio, la ubicación de la herramienta de búsqueda y del mapa del sitio.
Este enlace debe conducir a una página que contenga información para contactar a la empresa a
través de teléfonos, emails y direcciones físicas. Esta opción del menú no debe ser un enlace a
un correo electrónico, ya que incomoda al usuario porque ejecuta su aplicación de manejo de
emails.
MENÚ DE ÁREAS
Muchas veces se usa el área de cabezal para ubicar un menú de áreas o categorías dentro de la aplicación o
del sitio. Generalmente se utiliza cuando hay demasiadas opciones para ubicar en el menú izquierdo (más de
10). Categorizar los enlaces y agruparlos en áreas simplifica la navegación haciéndola más intuitiva.
MENÚ IZQUIERDO
Este menú contiene las opciones de navegación del sitio, todos los lugares del sitio a donde se puede acceder.
En muchos sitios el menú izquierdo cambia según el área en la que el usuario se encuentre.
Se debe mantener el mismo diseño del menú, independientemente de las opciones, para que al usuario sepa
cómo usarlo ya que aprendió su uso en otras áreas del sitio.
Links
Cuando se definen links subrayar las palabras importantes y brindar información suficiente
para que el usuario se sienta atraído a seguir el link.
Relacionar la información con links del tipo "más sobre tal tema", o sobre el autor, etc..
Usar “link title” siempre que no sea obvio a donde va el link, para que aparezcan los tooltips:
Velocidad de carga
Público objetivo
Uso de la aplicación
El tiempo que demora en cargarse la totalidad de una página determina la percepción que va a tener
el usuario de ese sitio o aplicación. Si la aplicación demora en cargarse, el usuario pensará que no es
buena, que no le solucionará sus problemas de forma correcta. Si la demora es excesiva, el usuario
puede llegar a pensar que la empresa no es fiable.
Usar texto en vez de imágenes siempre que se pueda (Ej.: para los menúes)
El formato de las imágenes siempre debe de ser .gif o .jpg, nunca .bmp, ya que este formato pesa
mucho más que los anteriores.
Usar herramientas para disminuir el peso de las imágenes. Ej:
http://www.netmechanic.com/GIFBot/optimize-graphic.htm
No usar imágenes animadas.
No usar flash, ya que no sólo demora más la carga de la página, sino que muchas veces requiere que
el usuario instale la tecnología.
No hacer páginas que requieran el uso excesivo de las barras de desplazamiento horizontal. Esto no
sólo ahuyenta al usuario por el tiempo que le consume, sino también por la cantidad de contenido que
se le presenta. Es mejor hacer páginas más cortas, con la información suficiente, o armar más
páginas a partir de una.
Público objetivo
Debe tener en cuenta quién será el público objetivo –a quién se dirige, quiénes serán los usuarios- a
la hora de diseñar y elegir los colores, los tamaños de las letras y tamaños de las pantallas.
Por ejemplo, si el público objetivo está integrado por desarrolladores, se puede hacer un sitio o una
aplicación con letras de tamaño 8 puntos, pero no se recomienda usar este tamaño para un público
masivo.
Uso de la aplicación
Cuando está diseñando también debe considerar cuál es la finalidad de la aplicación para no
entorpecer el uso del servicio que se desea brindar.
Si se trata de un sitio Web donde se ofrece bastante texto para leer no es recomendable que las
páginas tengan sectores que llamen más la atención que el contenido principal de la página. Por
ejemplo, las imágenes animadas son centros de atención. Es realmente molesto tener imágenes
moviéndose en distintas partes de la página cuando se tiene que leer. Se pueden usar imágenes
animadas si su movimiento se detiene una vez presentada la animación. De esta forma, se logra
captar la atención del usuario que ingresa a la página para transmitir el mensaje que se desea con
esas imágenes, y luego, se facilita al usuario la concentración para la lectura del texto principal.
Si el sitio Web es un portal, donde se espera encontrar muchos focos de atención (textos cortos,
muchos links) es más adecuado usar imágenes animadas.
Máximo aprovechamiento de los temas (Themes)
Maximizar el uso de los temas permite ajustar el diseño en tiempo de ejecución. Es recomendable
que cada ítem que se use esté definido en el tema, de forma por ejemplo, que todos los títulos
tengan la misma apariencia y si más tarde se quiere agregar espacio entre el título y el contenido se
pueda modificar automáticamente en todos los títulos de la aplicación. Esto es válido para cada
tabla usada en la aplicación, desde la que contiene las opciones del menú hasta la que contiene el
contenido, los grids, las etiquetas de los formularios, etc..
Escribir lo más corto y conciso posible. Se dice que en Internet hay que escribir entre un
50% y un 25% menos de lo que se escribiría en papel.
Poner las conclusiones al principio y una opción para ver el detalle de esa conclusión.
Tipo de letras
Se deben tener las siguientes consideraciones a la hora de elegir el tipo de letra a utilizar en una
aplicación Web:
El tamaño debe ser adecuado para el público objetivo y para la resolución más usada
Los tipos de fuentes que en general se encuentran instaladas en todas las máquinas son Arial, Verdana y Times New Roman.
Legibilidad
La buena tipografía depende -entre muchas otras variables- del contraste visual entre una fuente y
otra, y entre los bloques de texto, los títulos, y el espacio en blanco alrededor. Lo que más atrae al
ojo es el contraste fuerte con patrones distintivos.
Seguir patrones que conserven la forma de organizar el texto y las imágenes en las distintas páginas
de un sitio o una aplicación permite entender la organización de la información, intuir la ubicación
de más información y se aumenta la legibilidad de la misma.
La lectura va a ser más cómoda cuanto mayor sea el contraste de los colores. El mayor contraste se
logra con fondo blanco y letras negras. Se pueden establecer las combinaciones de colores en el
editor de temas, en la clase "Form" y jugar con las mismas sin tener que cambiar ni una línea de
código.
Márgenes
Los márgenes definen el área de lectura de una página, separando el texto principal de lo que lo
rodea.
Los márgenes y el espacio en blanco se usan para delinear el texto principal de otros elementos de
una página, y usados de igual manera en todas las páginas proveen uniformidad a través del sitio
creando una estructura consistente y una identidad visual.
Es recomendable que los textos principales tengan un margen de 5 a 10 píxeles. Esto se logra en
GeneXus poniendo el texto dentro de una tabla con “BorderWidht” en “0” y “Cellpadding” en “10”.
Los usuarios en Internet en general no leen los textos palabra a palabra, sino que escanean las
páginas tomando algunas palabras de cada párrafo para entender la idea general de la página. La
alineación izquierda facilita este tipo de lectura.
Links de interés
Usabilidad
Sitios con artículos sobre usabilidad y temas relacionados con mejora en los sitios Web:
EN ESPAÑOL
http://usalo.es/
http://www.ciw.cl/
http://www.masterdisseny.com/
http://www.alzado.org/
http://www.cadius.org/
http://accesibilidadweb.blogspot.com/
http://www.proyectoweb.org/
http://www.microsoft.com/spain/empresas/guias/usabilidad/experiencia_usuario.mspx
http://www.pdaexpertos.com/tutoriales/internet_movil/10_puntos_de_usabilidad_y_diseno_web_
para_pdas.shtml
EN INGLÉS
http://www.useit.com/
http://www.usabilitynet.org/
http://usableweb.com
http://www.w3.org/TR/WCAG20/
http://www.handheldusability.info/
http://www.usability.gov/guidelines/
http://www.webusability.com/
http://www.userfocus.co.uk/resources/index.html
http://www.humanfactors.com/downloads/10tips.asp
http://www.htmlcenter.com/
Herramientas
http://www.creatingonline.com/
http://www.gifworks.com/
TOOLBAR DE USABILIDAD
http://www.southbourne.com/accessibility-toolbar.htm
http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-
2d5e1db91038&DisplayLang=en
http://www.anybrowser.com/linkchecker.html
Muchos años atrás visualizamos que las soluciones Web serían la respuesta a muchos problemas
(distribución, disponibilidad, accesibilidad, escalabilidad, etc). Por eso a partir de la versión 6.1 de
GeneXus incluimos generadores para esta plataforma.
En la versión 9.0, además de los generadores para esta plataforma con los cuales se cuenta desde
hace años, se incluyen tecnologías de punta (como Ajax) viabilizando funcionalidades nuevas para el
ambiente Web, muchas de ellas "implícitas" en la versión (sin costo de desarrollo) y
extremadamente complejas de desarrollar "a mano".
El proceso de conversión de una aplicación GUI (Interfaz de Usuario Gráfica) a Web implica conocer
algunas características de esta última plataforma y su relación con las funcionalidades y
características de las soluciones GUI.
Muchas veces no se trata de "convertir" la aplicación o parte de la misma, sino del desarrollo de un
nuevo módulo en esa plataforma. En cualquier caso existe un "paralelismo" entre lo conocido por el
desarrollador (ambiente GUI) y la plataforma nueva a la cual se está enfrentando (Web), lo cual
requiere considerar las diferencias.
En este capítulo profundizaremos tanto en las diferencias como en la conversión de GUI a Web.
Objetivo
El objetivo de este documento es brindar una herramienta de referencia, para asistir en la decisión
de migrar o desarrollar una aplicación GUI, o una aplicación Web. Para analizar las diferencias entre
los dos tipos de aplicaciones se compararán las ventajas y desventajas de las aplicaciones Web
frente a las aplicaciones GUI.
Existe otro artículo (Conversión de Aplicaciones GUI a Web) sobre esta misma temática en donde se
dan los detalles técnicos de cómo realizar esta tarea, por lo que aquí no se mencionarán esos
detalles.
Introducción
APLICACIONES WEB
Se entenderá por aplicaciones Full Web a aquellas aplicaciones en las que la interfaz del usuario es
únicamente realizada utilizando el lenguaje HTML y son accedidas desde un browser. En GeneXus
estas aplicaciones se implementan con objetos Web como ser: Web Panels o Transacciones Web.
Instalación
Las aplicaciones Web presentan varias ventajas tanto en la instalación y actualización como en los
requerimientos necesarios para utilizarlas.
Cliente ‘fino’. Para utilizar la aplicación Web solo se necesita un browser. Los browsers son
distribuidos por Internet y no tienen costo. Generalmente vienen incluidos al instalar el sistema
operativo. Adicionalmente se pueden instalar plugs-in, que son programas que agregan
funcionalidades adicionales al browser. Un ejemplo muy común es el plug-in de Acrobat, utilizado
para visualizar archivos en formato PDF o plugs-in para video o sonido.
Flexibilidad en software y hardware en el cliente. En las aplicaciones Web, el cliente puede tener
instalado cualquier sistema operativo en cualquier versión. Las aplicaciones Web no utilizan tantos
recursos de hardware por lo que el costo de las computadoras clientes es menor y no necesita
actualizaciones frecuentes.
La aplicación solo se instala en el servidor. Generalmente la instalación y actualización de
aplicaciones GUI en arquitecturas cliente / servidor implica, alguna instalación en las computadoras
cliente. En el caso de aplicaciones Java GUI, esta instalación es automática, pero también existe ya
que es necesario bajar la aplicación.
En el caso de una aplicación Web no se requiere ninguna instalación adicional a la del browser, para
poder accederla o acceder a otras aplicaciones Web.
Escalabilidad
Las aplicaciones Web utilizan una arquitectura de tres capas compuesta por la capa cliente, donde
está únicamente el browser, la capa del Servidor Web donde está la aplicación y la capa de datos
donde se encuentra la base de datos.
BD
Independencia
Acceso. La aplicación puede ser accedida desde cualquier lugar que cuente con acceso a Internet.
Esto puede tener un fuerte impacto en el modo de trabajo ya que se pueden acceder a las
aplicaciones desde la oficina, el hogar o incluso desde otros países.
Hosting Services Provider (HSP). La aplicación puede ser instalada en un centro de cómputos propio
o puede contratarse un Hosting Service Provider (son empresas que proveen un centro de cómputos
para aplicaciones Web) e instalarla en los servidores del HSP. Para los usuarios, el acceso a la
aplicación es independiente de donde esté instalada.
Interfaz gráfica
Uniformidad. La forma de navegar por la aplicación Web será siguiendo links o presionando botones
y si bien hay más opciones, estas son las más comunes y se mantendrán por toda la aplicación. Si
bien este modo de interacción es limitado con respecto a las aplicaciones GUI, al ser tan simple y
uniforme en toda la aplicación, al usuario final le resultará sencillo e intuitivo aprender a utilizar
nuevas funcionalidades.
El diseño gráfico es realizado por expertos. Un aspecto sumamente importante en la interfaz grafica
de una aplicación Web es el diseño grafico. Este aspecto sumamente delicado se deja a cargo de
diseñadores gráficos especializados, que hacen que las aplicaciones tengan aspectos atractivos y
funcionales.
El trabajo con los diseñadores gráficos sigue pautas similares a la metodología de prototipación
utilizada en el desarrollo de aplicaciones GeneXus. Cuando los diseñadores tienen listo un prototipo,
es conveniente que los desarrolladores lo evalúen para validarlo desde el punto de vista del
desarrollo.
Para esto se cuenta a partir de la versión 8.0 de GeneXus, con el Editor de Temas, herramienta que
puede ser usada tanto desde GeneXus como en forma independiente, por lo cual flexibiliza
notablemente la interacción con el diseñador gráfico, además de todas las ventajas adicionales que
trae el uso de Temas en el diseño de la aplicación Web. Por detalles sobre Temas ver el documento
Themes.
Impacto del diseño de las páginas Web finales. Si se utilizan demasiadas imágenes, con
muchos botones, el tamaño final de la página, puede ser excesivamente grande, por lo que
se demorará mucho el acceso. La recomendación es cuidar de que las imágenes sean de
pocos Kbytes. Los links de texto son muy livianos, en el caso de una aplicación muy accedida,
puede ser conveniente utilizarlos. Los sitios Web de Amazon y Yahoo, son buenos ejemplos
de interfaces livianas, con pocas imágenes y muchos links de texto.
El diseño debe ser consistente. Por ejemplo la tipografía, los colores, la ubicación de
botones, etc. debe seguir una pauta bien definida, que los desarrolladores deben respetar al
máximo.
El diseño debe ser simple y sencillo. El exceso de detalles gráficos, puede complicar el
desarrollo y evolución del sitio.
Componentización. Es muy importante que la estructura de las páginas pueda ser separado
en componentes, de modo de poder reutilizar los mismos objetos para simplificarle al
usuario el conocimiento del sitio. En GeneXus esto, se implementa utilizando Web
Components.
Interfaz multimedia. Es muy sencillo incluir en las aplicaciones Web características multimedia como
audio, video, imágenes, etc.
Application Service Providers y servicios Web
Los Application Service Providers (ASP), son empresas que brindan servicios y soluciones, basadas en
software, a través de Internet. Ejemplos muy comunes de ASP en portales de Internet son los
proveedores de noticias, banners, clima, etc.. Tener aplicaciones Web habilita a la empresa a
funcionar como ASP, brindando como servicio el uso de las aplicaciones Web desarrolladas.
También habilita a contratar a otros ASP para potenciar las aplicaciones propias.
Transacciones e Integridad transaccional. Las Transacciones Web utilizan la misma arquitectura que
los Web Panels. En la figura se ve la secuencia de acciones que ocurren al someter las Transacciones
Web al servidor.
El tiempo de vida de las UTLs (Unidades de Trabajo Lógicas) en los objetos Web, se mantiene
únicamente durante la ejecución del objeto. Cuando la ejecución termina se deben hacer commit o
roll back. Por lo tanto no es posible definir una UTL a través de varias Transacciones Web. Sin
embargo, es posible mantener la UTL a través de varios procedimientos que se invoquen unos a
otros, siempre que se mantengan dentro de la misma ejecución. En las aplicaciones GUI es común
encontrar que durante varias transacciones se van ingresando datos y luego en la última transacción
se hace el commit de todos los datos ingresados, por lo que se deben contemplar estos casos en la
reingeniería de la aplicación. Las alternativas posibles a esta situación son:
Unificar todas las Transacciones GUI en una sola Transacción Web.
Diferencias en los Web Panels “Trabajar con”. En las aplicaciones Web, los Web Panels de tipo
“Trabajar con” presentan algunas diferencias que en las aplicaciones GUI.
El alto de la pantalla cambia, dependiendo de la cantidad de líneas del grid. En las aplicaciones GUI,
el tamaño de los formularios se determina en el diseño de este y queda fijo en el momento de
ejecución. En las aplicaciones Web, el tamaño de la página Web se puede extender (horizontal o
verticalmente) si se presentan muchas líneas en los grids.
La selección de líneas es diferente. En las aplicaciones GUI, las líneas se seleccionan al hacer clic en
ellas, además se puede seleccionar un rango de líneas, continuo o con líneas salteadas, todo esto sin
necesidad de programación extra. En las aplicaciones Web, la selección múltiple de líneas debe
programarse mediante campos de chequeo.
Una posibilidad es permitir la selección de múltiples líneas y utilizar el carrito de compras (se
describe más adelante).
Se puede usar la propiedad “AllowSelection” de los grids para que sea posible seleccionar de a una
línea.
El modelo del carrito de compras. El carrito de compras, es muy utilizado en los sitios Web con e-
commerce y permite “recordar” los objetos que compran los usuarios. En el carrito de compras se
van seleccionando distintos ítems que se desean comprar. El carrito mantiene almacenado el
contenido hasta que el dueño decide comprar alguno o todos los ítems. Esta idea resulta práctica en
casos como este: Factura de compras. La factura se va armando seleccionando los elementos que la
componen: lista de productos disponibles, lista de clientes, formas de pago, monedas, etc. Cuando
se termino de armar, se construye la factura con toda la información del carrito.
Si se quiere realizar alguna acción a una serie de líneas en un “Trabajar con”, se pueden ingresar en
el carrito y luego automáticamente se van presentando una a una las páginas adecuadas para la
acción determinada, hasta vaciar el carrito.
Ejecución en el servidor. En Web con el uso de la tecnología Ajax las aplicaciones cada vez se
asemejan más a Win, ya que se ejecutan acciones tanto en el cliente como en el servidor. Por más
detalles ver Tipos de diálogo.
Una aplicación Web debe estar disponible los 7 días de la semana, durante las 24 horas del día. Esto
implica un servicio de alta disponibilidad en el cual posiblemente se maneje redundancia de
servidores y de información.
Conclusiones
Las aplicaciones Web son una nueva alternativa a las aplicaciones de interfaz gráfica. Ambos tipos de
aplicación tienen sus características propias por lo que en cada aplicación se debe evaluar si
conviene realizarla como Web o GUI. Los puntos discutidos en este artículo pueden ser considerados
como una guía para tomar esta decisión. Como requisito para tomar una decisión correcta se debe
comprender:
El funcionamiento de la interfaz Web y las limitaciones que ello trae como consecuencia.
Algunos puntos a tener en cuenta para evaluar la creación o migración a aplicaciones Web son:
Requerimientos en el acceso.
Como punto final hay que tener en cuenta la evolución de la aplicación en cuanto a la creación de
nuevos módulos, cantidad de usuarios y mantenimiento.
Objetivo
El objetivo de este documento es describir los principales aspectos técnicos a tener en cuenta al
momento de convertir una aplicación GeneXus de tipo GUI-Windows a una aplicación Web.
Introducción
APLICACIÓN GUI
Entendemos como aplicación GUI (Graphic User Interface) a toda aquella que tiene interfaz gráfica
Windows, compuesta básicamente por los objetos Transacciones, Work Panels, Procedimientos y
Reportes, generadas con los generadores GeneXus Visual Basic, Visual Fox, Java y .Net.
APLICACIÓN WEB
Una aplicación Full Web tiene una interfaz HTML (HyperText Markup Language) y se ejecuta dentro
de un browser. Este tipo de aplicaciones se desarrolla básicamente con los objetos Web de GeneXus:
Web Panels y Web Transactions. Se generan con cualquiera de los generadores Web: Java, .Net.
Reingeniería de la aplicación
La premisa fundamental para convertir una aplicación Win a Web es que los ambientes implicados
(gráfico, html) son diferentes y por lo tanto la conversión implicará algo más que la mera conversión
de los objetos. Deberá programarse con “estilo Web”.
En este documento centralizamos consideraciones a tener en cuenta para los diferentes objetos y
modalidades de programación.
2. Conversión de Transacciones
3. Conversión de Reportes
Se recomienda leer el documento Comparación entre Web Panels y Work Panels donde se comparan
generalidades de ambos tipos de objetos.
Luego de convertir el objeto, se debe editar el código HTML del mismo y quitar los tags <pre> y
</pre> que quedan al principio y al final respectivamente del mismo. Hay que tener en cuenta que la
conversión no crea una tabla con los controles dentro, por lo tanto al quitar los tags mencionados
anteriormente la pantalla se “desarma” y quedan todos los controles juntos. Se aconseja por lo
tanto, crear primero una tabla donde se pueda “arrastrar” los controles y finalmente quitar los tags
<pre> y </pre>.
2. CONVERSIÓN DE TRANSACCIONES A TRANSACCIONES WEB
Se cuenta con un form HTML default por cada Transacción Web (con los atributos de la Transacción,
así como los controles propios de Transacciones Web, como ser el Error Viewer). Luego ese form se
puede modificar a gusto del programador. En algunos aspectos, el comportamiento de las
Transacciones Web es diferente al de las Transacciones con interfaz gráfica por lo tanto se
recomienda la lectura del documento Transacciones Web.
3. CONVERSIÓN DE REPORTES
Una posibilidad para manejar reportes es programar un Web Panel, de forma que el usuario final
pueda imprimirlo con las opciones de impresión del browser.
Manejo de opciones
En el objeto Web Panel, existen algunas alternativas para implementarlo:
1. Agregar en el grid una variable de tipo Combobox y programar las diferentes acciones en el
evento Clic de la misma.
2. Definir una imagen o un text block en el grid por cada una de las opciones y programar la
acción en el evento clic.
3. Si se utiliza un grid Free Style, puede utilizarse en lugar de una imagen con el evento clic, un
botón para cada una de las opciones.
Filtros
Si un Web Panel “Trabajar con” tiene variables que se aplican como filtro a los registros desplegados
en el grid, al seleccionar un registro y llamar a otro objeto (por ej. Transacción Web) que tiene un
Return, se vuelve al Web Panel “Trabajar con” pero se pierden los valores ingresados en los filtros.
Para poder mantener el comportamiento de los Work Panels “Trabajar con” se deberían utilizar
cookies que almacenen los filtros ingresados.
Refresh
En Work Panels “Trabajar con”, es común tener un comando Refresh o Refresh keep dentro de un
evento, luego de llamar a una Transacción. Cuando estos se convierten a Web Panels “Trabajar con”
el Refresh no es necesario, ya que al ejecutar el comando Return hay un Refresh implícito del Web
Panel. Por lo tanto, los comandos Refresh y Refresh keep deben ser eliminados de los eventos
mencionados anteriormente.
Debe considerarse que se puede utilizar únicamente para invocar a objetos sin interfaz. Si se invoca
a otro Web Panel, solamente se ejecuta para el último registro del grid.
En las aplicaciones HTML esto no puede usarse. Las llamadas a un Web Panel solamente pueden
realizarse desde otro Web Panel (mediante el call o el link).
Una alternativa puede ser definir un objeto por cada Tab Dialog.
Otra alternativa es usar código HTML externo que permite simular estos tabs.
MASTER PAGE
En las aplicaciones Web se recomienda la utilización de Master Pages, de forma que permita
centralizar el diseño y el comportamiento de la aplicación en un solo objeto y reutilizarlo en otros
objetos sin requerir programación.
INTRODUCCIÓN
En este capítulo veremos GXportal, herramienta que permite diseñar, administrar y mantener
portales escalables, sin necesidad de programar. Por lo tanto el usuario de GXportal no necesita
tener conocimientos específicos de programación o diseño.
GXportal brinda una interfaz Web amigable desde la cual el usuario, en pocos pasos, construye y
publica la información en el portal.
La practicidad de GXportal asegura la reducción de los costos de desarrollo y mantenimiento, así
como también de los tiempos en llevar las nuevas ideas al mercado (time-to-market).
GXportal
GXportal es la herramienta para construir portales para organizaciones que necesitan conectar a sus
miembros, socios, y clientes a través de Internet en forma rápida, segura y eficiente. Construido
utilizando la tecnología GeneXus, GXportal incorpora vistas de diseño y gestión de contenido
independientes, y funciones de gestión automática del contenido y del diseño que lo hacen único
dentro de las herramientas de colaboración.
SIMPLE
La administración de la información del portal puede ser realizada por personal no especializado,
accediendo al Back End del portal desde cualquier PC conectado a Internet. El proceso de
administración de contenido guía al usuario en el ingreso y mantenimiento de la información.
Permite definir dónde y cuándo se publicará el contenido y cuáles son los roles para cada tarea, lo
que asegura el manejo confiable de la información.
SINGLE SIGN ON
El módulo Single Sign On permite la unificación del control de usuarios de GXportal y aplicaciones
externas.
ARQUITECTURA ESCALABLE
GXportal le permite implementar soluciones que van desde un servidor único para base de datos y
servidor Web, hasta configuraciones con múltiples servidores en diversas ubicaciones.
ADMINISTRACIÓN DE COMUNIDADES
GXportal cuenta con las siguientes herramientas para lograr un ámbito de interacción entre los
distintos integrantes de las comunidades:
• Encuestas
• Foros
• Listas de noticias
• Preguntas Frecuentes
SEGURIDAD
La seguridad está basada en roles, dependiendo de los roles que tenga asignado el usuario se le
presentarán las funcionalidades del Back End a las cuales puede acceder para realizar tareas de
administración.
Figura 2: Seguridad Gxportal. El acceso a la información dependerá de los roles que se le asignen, es
posible restringir el acceso de los usuarios Web a contenidos, menúes, páginas o canales. De esta
forma se logra controlar y segmentar el público del portal.
Principales Beneficios
DISEÑO WEB
El primer paso en la creación de un sitio Web efectivo es la creación de páginas visualmente
atractivas. El diseño de las páginas Web en GXportal se realiza en forma independiente del
contenido y de la funcionalidad del sitio. Los diseñadores Web no necesitan tener conocimientos de
programación ni limitaciones funcionales a la hora de diseñar el “look & feel” de su sitio.
El diseño se realiza en base a plantillas que pueden ser actualizadas en cualquier momento. Las
plantillas son estilos de páginas pre-definidas o definidas por el usuario que se aplican a las páginas
del portal. Cuando se modifica una plantilla, el diseño de las páginas que se basan en ella se actualiza
en forma automática.
El diseño independiente del contenido y el uso de plantillas posibilita la creación sitios cuyo “look &
feel” puede evolucionar junto con las necesidades de sus visitantes, al tiempo que reduce
drásticamente los costos y tiempos de desarrollo y mantenimiento del sitio.
GESTIÓN DE CONTENIDOS
El segundo paso en la creación de un sitio efectivo es asegurar que la información que contiene sea
correcta, esté actualizada, y sea pertinente para sus visitantes. Las funcionalidades de gestión de
contenido de GXportal permiten delegar las tareas de generación de contenido a sus creadores.
Para ello, incorpora workflows para gestionar el proceso de creación, edición, y traducción de
contenidos, y mecanismos de publicación por fecha, de segmentación de contenidos, y de
personalización del sitio por parte de sus visitantes.
GESTIÓN DE COMUNIDADES
El tercer componente fundamental en la creación de un sitio efectivo es la interacción con sus
visitantes. GXportal cuenta con herramientas para lograr un ámbito de interacción óptimo entre los
miembros de su comunidad como newsletters, foros de discusión, encuestas, preguntas frecuentes,
etc..
Las herramientas de gestión de comunidades de GXportal le permiten interactuar con sus visitantes
en forma óptima.
INTEGRACIÓN DE APLICACIONES
El grado máximo de desarrollo de los sitios es el acceso cualquier aplicación en forma remota y
segura a la vez.
Los conectores habilitan la integración a sus páginas de componentes externos tales como código
HTML, Flash, Javascript, XML, aplicaciones o páginas Web externas y Web services.
CONTENIDO
El módulo de contenido permite administrar y gestionar de forma ágil, segura y ordenada los
contenidos que serán publicados en el portal. Guía al usuario en el proceso de ciclo de vida de la
información mediante un workflow asegurando la consistencia de los datos en el momento de su
publicación.
Toda la gestión del contenido se realiza a través de una interfaz Web permitiendo al usuario tener
una visión organizada y centralizada de la información independientemente de donde será
publicada.
DISEÑO
GXportal ofrece a través del módulo de diseño una interfaz amigable e intuitiva mediante la cual el
usuario, sin necesidad de programar, puede diseñar las páginas del portal. Esta tarea se realiza
personalizando cada página, pudiendo reutilizar los diseños de otras.
El usuario puede definir sus propias plantillas y asociarle un conjunto de páginas. De esta manera se
obtiene una reducción en los costos de mantenimiento y permite que los cambios se hagan de
manera rápida, pues los cambios en la plantilla impactan en forma automática en todas las páginas
asociadas.
COMUNIDAD
Las comunidades surgen a partir de los intereses en común que tienen las personas que navegan un
sitio. Por lo tanto, el sitio deberá proveer de las herramientas que hacen posible la creación y
funcionamiento de las comunidades, como ser: foros de discusión, lista de noticias, preguntas
frecuentes, encuestas, etcétera.
GXportal cuenta con las herramientas necesarias para lograr un ámbito de interacción entre los
distintos integrantes de las comunidades.
SEGURIDAD
Contar con herramientas de segmentación permite controlar a que tipo de información puede
acceder cada usuario y controlar el acceso a determinadas áreas del portal que son privadas y
destinadas a determinados usuarios. La seguridad definida por GXportal le permite contar con la
definición de roles que desee de manera de poder segmentar el público objetivo de la mejor manera
posible y además de contar con el soporte de protocolo seguro que le dé la tranquilidad al usuario
de que la información se envía de manera totalmente privada y segura.
Tecnologías Soportadas
• Sistemas de Administración de Bases de Datos (DBMS): IBM DB2 UDB, Microsoft SQL Server,
Oracle, MySQL
1. DISEÑO
En esta etapa se realiza un análisis con el fin de determinar objetivos del portal, público o
comunidades a las cuales se dirigirá el portal, que información se quiere publicar y de que forma se
segmentará dicha información. De este análisis se debe obtener lo siguiente:
2. CONSTRUCCIÓN
Durante esta etapa se trabaja directamente desde el Back End de GXportal definiendo las plantillas
de diseño que surgieron del diseño gráfico de la etapa anterior. Luego en base a estas plantillas se
crean las páginas del portal basándolas en las plantillas definidas. Además se realiza el ingreso de los
contenidos del portal mediante los grupos de usuarios que se definieron y utilizando las
herramientas de workflow provistas por GXportal para este cometido.
En esta etapa se debe culminar con la capacitación de los usuarios involucrados en la administración
del contenido. Y se debe hacer un seguimiento de la evolución del contenido y de los usuarios en el
portal para analizar cuales son los cambios a realizar en el portal de manera de estar en constante
evolución y poder dar un mejor servicio a través de él.
INTRODUCCIÓN
Existen otras características interesantes para el desarrollo de aplicaciones Web, que presentamos
en este capítulo.
Menú de Opciones
Funciones de acceso al header de un objeto Web
Manejo HTTP
WAP
Web Services
WebWrapper
Menú de Opciones
A la hora de crear los menúes de opciones en las aplicaciones Web, básicamente surgen dos formas
de implementarlos desde GeneXus. Una de las soluciones posibles es implementarlo con JavaScripts
y otra solución es con grids FreeStyle. Siendo la primera la más utilizada hasta el momento.
Como otra alternativa se puede contar con Gxportal, herramienta que brinda soluciones para los
menúes e incluso Patterns aunque no genera menúes, si genera una serie de links que permiten
navegar por toda la aplicación (tanto en el header y como los recents links).
Introducción
Esta funcionalidad provee a los usuarios GeneXus una forma de poder utilizar el protocolo HTTP en
sus programas. Para ello se crearon los tipos de datos HttpClient, HttpResponse y HttpRequest.
Descripción
Los tres tipos de datos que se definen para interactuar con http son:
HttpClient
Permiten leer los datos del request y grabar el response. Son objetos disponibles sólo en
Procedimientos Web.
HTTPCLIENT
Este objeto refleja una conexión http. Puede usarse desde cualquier objeto GeneXus.
Propiedades
A continuación se detalla la lista de propiedades:
Host
Define el nombre del host.
Tipo- String
Port
Define el puerto del host.
Tipo- String
Secure
Indica si el protocolo es http o https.
Tipo- Boolean
Timeout
Determina el Timeout de la conexión.
Tipo- Integer
BaseURL
Indica la URL base de los request que se hagan al host.
Tipo- String
StatusCode
Retorna el código de error HTTP.
Tipo- Integer
ReasonLine
Retorna el texto del error HTTP.
Tipo- String
ErrCode
Retorna si ocurrió algún error en algún comando, en cuyo caso retorna un valor distinto de cero.
Tipo- Integer
ErrDescription
Retorna el mensaje del error si ocurrió alguno en algún comando.
Tipo- String
Basic y Digest
Son constantes que determinan un tipo de autenticación. Se utilizan en el método AddAuthentication.
Basic=0 : Para autentificar se envía el usuario y password sin encriptar.
Digest=1: Para autentificar se envía el usuario y password encriptados.
ProxyHost y ProxyPort
Permiten especificar un proxy http. En ambiente windows se utiliza automáticamente el que esta configurado
en la máquina.
ProxyHost- String
ProxyPort- Integer
Métodos
AddHeader(<Name>, <Value>)
Agrega un header con el valor dado.
Ejemplo: AddHeader(“User-Agent”, “GeneXus”)
<Name>- String
<Value>- String
AddVariable(<Name>,<Value>)
Agrega una variable al ‘form’.
<Name>- String
<Value>- String
AddString(<Value>)
Agrega el contenido del string al buffer de datos a enviar.
<Value>- String
AddFile(<Value>)
Agrega el contenido del archivo al buffer de datos a enviar.
<Value>- String
Execute(<Method>,<URL>)
Ejecuta un método en la URL definida. Se pondría solo la parte final de la URL
Ejemplo: execute("POST", "/servlet/awebproc")
<Method>- String
<URL>- String
ToString()
Retorna un String con todo el “cuerpo” del response.
ToFile(<FileName>)
Graba en un archivo el contenido del stream.
<FileName>- String
GetHeader(<Name>,<Value>)
Retorna en <Value> el valor del header convertido al tipo de la variable.
<Name>- String
<Value>- Anytype
Propiedades
Method
Retorna el método HTTP.
Tipo- String
ServerHost
Retorna el nombre del servidor
Tipo- String
ServerPort
Retorna el puerto en el servidor
Tipo- Integer
Secure
Indica si se esta utilizando HTTPS. Si el valor retornado es 1, se está utilizando HTTPS; si es 0, se está
utilizando http.
Tipo- Integer
ScriptPath
Retorna la porción de URL correspondiente el nombre del directorio virtual.
Tipo- String
ScriptName
Retorna el nombre del objeto con la extensión correspondiente que se esta ejecutando, tal como aparece en
la URL.
Tipo- String
Referrer
Retorna la URL del llamador.
Tipo-String
QueryString
Retorna la porción de la URL que está después del signo “?”; o sea los parámetros.
Tipo- String
RemoteAddress
Devuelve la dirección del cliente.
Tipo- String
ErrCode
Retorna si ocurrió algún error en algún comando, en cuyo caso retorna un valor distinto de cero.
Tipo- Integer
ErrDescrption
Retorna el menaje del error si ocurrió alguno en algún comando.
Tipo- String
Métodos
GetVariable(<Variable>)
GetHeader(<Header>)
Retorna un String con el valor del header <Header>.
<Header>- String
ToString()
Retorna un String con todo el ‘cuerpo’ del request.
ToFile(<FileName>)
Graba en un archivo el contenido del stream.
<FileName>- String
HTTPRESPONSE
Este objeto permite escribir el response http. Puede instanciarse sólo en el contexto de un
Procedimiento Web.
Propiedades
ErrCode
Retorna si ocurrió algún error en algún comando, en cuyo caso retorna un valor distinto de cero.
Tipo- Integer
ErrDescrption
Retorna el menaje del error si ocurrió alguno en algún comando.
Tipo- String
Métodos
AddHeader(<Name>,<Value>)
Agrega un header con el valor dado.
Ejemplo: AddHeader(“User-Agent”, “GeneXus”)
<Name>- String
<Value>- String
AddString(<Value>)
Agrega el contenido del string al buffer de datos a enviar.
<Value>- String
AddFile(<Value>)
Agrega el contenido del archivo al buffer de datos a enviar.
<Value>- String
XMLReader.openRequest(HttpRequest)
Se utiliza en un WebProc para leer un xml que viene en el body del http request.
XMLReader.openResponse(HttpClient)
Se utiliza en cualquier objeto para leer como XML lo que devolvió un request.
XMLWriter.openRequest(HttpClient)
Se utiliza para enviar un XML en el body de un http request.
XMLWriter.openResponse(HttpResponse)
Se utiliza en un Procedimiento Web para escribir un XML que se retornara en el body del http
response.
Ejemplo
Este ejemplo muestra como un objeto GeneXus llama a otro vía http, pasándole parámetros en un
XML y recibiendo los mismos también en un XML. El XML a enviar tiene la forma:
<parameters>
<a>valor</a>
<b>valor</b>
</parameters>
El XML que se devuelve es igual, con los valores de ‘a’ y ‘b’ modificados.
&client.host = "localhost"
&client.port = 88
&writer.openRequest(&client)
&writer.WriteStartElement("parameters")
&writer.WriteElement("a", &A)
&writer.WriteElement("b", &B)
&writer.WriteEndElement()
&writer.close()
&client.execute("POST", "/servlet/awebproc")
&reader.openResponse(&client)
&reader.read()
&reader.read()
&a = val(&reader.value)
&reader.read()
&b = val(&reader.value)
&reader.close()
&reader.openRequest(&Request)
&reader.read()
&reader.read()
&a = val(&reader.value)
&reader.read()
&b = val(&reader.value)
&reader.close()
&a = &a + 1
&b = &b + 1
&writer.openResponse(&Response)
&writer.WriteStartElement("parameters")
&writer.WriteElement("a", &A)
&writer.WriteElement("b", &B)
&writer.WriteEndElement()
&writer.close()
Consideraciones para el generador Java
En caso de que se ejecute en otra plataforma, es necesario especificar el proxy como una ‘System
Property’ desde la línea de comandos del intérprete, por Ej.:
Introducción
En los últimos años tanto Internet como la telefonía celular han tenido un gran crecimiento y se han
hecho accesibles a millones de personas. Es posible ahora unir estas dos tecnologías accediendo de
forma fácil y rápida a la información que brinda Internet desde los teléfonos celulares (ó móviles).
GeneXus permite generar salidas para Internet móvil, generando objetos con contenido WML. Esto
aplica a Web Panels, generando tanto para Java como .NET.
Algunas definiciones
WML
Lenguaje de Tags basado en XML. Es interpretado por los celulares WAP compatibles. Es parecido al
HTML, pero tiene menos potencia y soporta algunas cosas que el HTML no y es bastante más estricto
en la sintaxis.
WML VS HTML
Por el tamaño de la pantalla, es imposible traducir o ver de forma satisfactoria una página de Web
normal (HTML) en un celular. El tamaño, los tipos de letra, las imágenes y la cantidad de información
que se soporta en el Web no se puede soportar en un microbrowser y no es práctico hacerlo.
La navegación, además, es diferente, el usuario no tiene mouse, ni teclado por lo que el ingreso de
datos debe ser limitado y la navegación, mucho más simple.
MICROBROWSER
Es un software instalado en el teléfono o dispositivo inalámbrico que interpreta el WML (y el
WMLScript, WTAI, etc.) y despliega la información en la pantalla. Es posible acceder a emuladores de
celulares y sus microbrowser. Algunos de los más conocidos son UP Browser (Unwired Planet) de
Phone.com, RS380 Ericsson, Nokia, etc..
Arquitectura
Descripción
Para generar Web Panels con contenido WML, se implementó una nueva propiedad (a nivel de
objeto) denominada “Tag Language”.
HTML
WML
El valor por defecto es HTML para cualquier objeto Internet. Con el valor WML es posible generar
objetos con contenido WML, estos podrán ser vistos desde un browser WAP.
Requerimientos
http://www.openwave.com/products/developer_products/sdk/
El producto es sin cargo, para acceder al mismo se debe realizar la registración en dicha página.
Diseño
Se deben definir los Web Panels como hasta el momento y configurar la propiedad “Tag Language”
en “WML”.
En el diseño del objeto se deben tener en cuenta las siguientes limitaciones del lenguaje generado
(WML):
Los objetos WML están limitados en el tipo y cantidad de controles que se soportan así
como en el tamaño de las páginas debido a la cantidad de memoria de los móviles y el
tamaño de la pantalla.
Las pantallas permiten entre 4 a 8 líneas de texto, dependiendo del móvil, por lo que no se
recomienda que las pantallas superen estos tamaños. No es conveniente que se tenga scroll
en una pantalla de teléfono celular.
o Edit
o Textblocks
o Texto libre
o Tablas simples
No se soportan:
o Campos LongVarchar
o La letra ñ
o Tag <BR>
o Botones
o Cookies
o Encriptación de parámetros
o Link
o Ispassword
o Visible
o Enabled
El softbutton del teléfono (botón que se encuentra en la parte superior izquierda), se asocia
al Evento Enter.
Ejecución
Luego de generado el objeto se debe ejecutar desde el emulador celular, esto se realiza escribiendo
la dirección donde se encuentra el Web Panel en la barra de direcciones del mismo.
Ejemplo
Se desea desplegar un texto de prueba en un teléfono celular, los pasos a seguir son los siguientes:
3. Ejecutar el UP.Simulator.
El texto completo del error se debe visualizar en el “Phone information’” (ventana DOS
que se ejecuta detrás del emulador).
http://www.gxtechnical.com/main/Hdcenter.aspx?2,5,36,408
Errores comunes
Error Síntoma
“Error : Invalid element ‘br’ in contents of Se debe a un tag <BR> en el Source del objeto
card.”
“Error : Uncompiled data from http <head>.” La página no es WML es HTML, se debe
configurar la preference ‘Tag Language=WML’
“Error : Missing entity “ntilde” Hay algún dato con la letra ñ y el microbrowser
no lo puede interpretar.
“Error : Invalid element ‘P’ in content of ‘p’. Se introdujo algun tag <P> anidado, esto no es
excpectde PCDATA | em | b …” válido en WML
Consideraciones
El editor no toma en cuenta algunas restricciones necesarias para WML y puede generarse
código no válido, es preciso en estos casos modificar el source en el editor de diseño de
GeneXus.
Existen algunos Tags HTML (no válidos en WML) generados por el editor. Por ejemplo el Tag
<BR> es generado por la combinación de teclas Shift+Enter en el editor.
Textblock y variables deben generarse entre <P> y </P>. La generación de estos Tags se da
con un enter al final del edit o modificando Código en el Tab “Source”.
Grids o tablas no deben limitarse por tags <P>. Es posible generar este código con algunas
combinaciones de teclas.
Igualmente no es recomendable modificar el código WML (bajo el tab “HTML Source” )
pues pueden dar errores en ejecución.
INTRODUCCIÓN
Cada vez se escucha más el concepto de “Web Services”, fundamentalmente relacionado con
Internet y el futuro de una arquitectura orientada a servicios. Es por esta razón, que GeneXus incluye
la posibilidad de desarrollar y consumir Web Services.
Comenzaremos con una introducción al concepto de Web Services para luego realizar ejercicios
prácticos que permitan profundizar los conocimientos adquiridos.
Web Services
En los últimos tiempos ha surgido con mucha fuerza el concepto de Web Services, incluso
afirmándose que el mismo cambiaría la forma de programar las aplicaciones orientadas a Internet
hacia una arquitectura orientada a servicios. Todo esto se ha visto potenciado luego del anuncio de
Microsoft de su nueva estrategia .NET que está basada en el modelo de Web Services.
Este documento describe qué son los Web Services y cómo es la arquitectura general del modelo,
adicionalmente se provee una introducción de los estándares en los cuales se basa este modelo
como ser SOAP, WSDL y UDDI.
¿Qué es un Web Service?
Un Web Service es una aplicación que puede ser descripta, publicada, localizada e invocada a través
de una red, generalmente Internet. Combinan los mejores aspectos del desarrollo basado en
componentes y la Web.
Al igual que los componentes, los Web Services son funcionalidades que se encuentran dentro de
una caja negra, que pueden ser reutilizados sin preocuparse de cómo fueron implementados. A
diferencia de la actual tecnología de componentes, no son accedidos por medio de protocolos
específicos del modelo de objetos como ser RMI, DCOM o IIOP; sino que son accedidos utilizando
protocolos Web como ser HTTP y XML.
La interface de los Web Services está definida en términos de los mensajes que el mismo acepta y
retorna, por lo cual los consumidores de los Web Services pueden ser implementados en cualquier
plataforma y en cualquier lenguaje de programación, sólo tiene que poder crear y consumir los
mensajes definidos por la interface de los Web Services.
La idea básica consiste en que un proveedor publica su servicio en un corredor, luego un consumidor
se conecta al corredor para encontrar los servicios deseados y una vez que lo hace se realiza un lazo
entre el consumidor y el proveedor.
SOAP es el elegido en este caso; SOAP es un protocolo liviano para el intercambio de información.
Más adelante en este documento lo veremos con más detalle.
Un lenguaje común y extensible para describir los servicios
La opción en este caso es WSDL. Es un lenguaje basado en XML desarrollado en forma conjunta por
IBM y Microsoft. Lo veremos con más detalle más adelante en este documento.
Una forma de descubrir los servicios en Internet
UDDI se utiliza en este caso; el mismo especifica un mecanismo para publicar y localizar los
servicios por parte de los proveedores y consumidores respectivamente. Se verá con más
detalle más adelante en este documento.
Ventajas y retos
Los Web Services apuntan a ser la piedra fundamental de la nueva generación de sistemas
distribuidos. Estos son algunos puntos para fundamentar esta afirmación:
Interoperabilidad
Cualquier Web Service puede interactuar con otro Web Service. Como los Web Services pueden ser
implementados en cualquier lenguaje, los desarrolladores no necesitan cambiar sus ambientes de
desarrollo para producir o consumir Web Services.
Ubicuidad
Los Web Services se comunican utilizando HTTP y XML. Por lo tanto cualquier dispositivo que
soporte estas tecnologías puede implementar o acceder Web Services. Muy pronto estarán
presentes en teléfonos, autos e incluso máquinas expendedoras, las que avisarán a la central
cuando el stock sea menor al indicado.
El concepto detrás de los Web Services es fácil de entender, incluso existen toolkits de vendedores
como IBM o Microsoft que permiten a los desarrolladores crear Web Services en forma rápida y fácil.
Soporte de la Industria
Todas las empresas de software importantes soportan SOAP, e incluso están impulsando el
desarrollo de Web Services. Por ejemplo la nueva plataforma de Microsoft .NET está basada en Web
Services, haciendo muy simple el desarrollo de los mismos que luego podrían ser consumidos por un
Web Service desarrollado utilizando VisualAge de IBM y viceversa.
A la vez hay ciertos retos técnicos que los Web Services tienen que sortear para poder tener éxito. Muchos
de estos retos están relacionados con el ambiente abierto en el que tienen que sobrevivir. Estos son algunos
de esos puntos:
Descubrimiento
¿Cómo se anuncia un Web Service para ser descubierto por otro servicio? ¿Qué pasa si el servicio se
cambió o se movió luego de ser anunciado?
WSDL y UDDI son dos nuevos estándares que manejan este punto.
Confiabilidad
Algunos Web Services son más confiables que otros. ¿Cómo puede ser medida esa confiabilidad y
comunicada? ¿Qué pasa cuando un Web Service está off-line en forma temporaria? ¿Localizamos y
utilizamos un servicio alternativo brindado por otra empresa o esperamos a que el servicio esté de nuevo
on-line?
Seguridad
Muchos Web Services son publicados para ser utilizados sin ninguna restricción, pero muchos otros van a
necesitar autenticación para que los utilicen sólo los usuarios autorizados. ¿Cómo autentifica a los
usuarios un Web Service? ¿Lo hace a nivel del método que lo implementa o utiliza otro Web Service para
realizar la autenticación?
Responsabilidad
En caso de que el Web Service no sea de acceso libre, ¿Cómo puedo definir cuántas veces un
consumidor puede acceder al Web Service una vez contratado? ¿Cómo se cobra su uso? ¿Cómo se indica
que un servicio ya no está más en línea?
Tecnologías asociadas
El modelo de Web Services está basado en ciertas tecnologías emergentes que es el resultado del
trabajo de varias compañías y organizaciones entre las cuales se destacan IBM y Microsoft. Estas
tecnologías son SOAP, WSDL y UUDI.
Está basado en XML y potencialmente puede ser utilizado en combinación con una variedad de
protocolos de comunicación, siendo el más utilizado HTTP. Por lo tanto se utiliza HTTP para
transportar la información, y XML para representar la misma.
El mensaje SOAP consiste en un elemento envelope SOAP obligatorio, un cabezal SOAP opcional y un
cuerpo SOAP obligatorio como un documento XML. El cabezal SOAP es utilizado para definir
información acerca del requerimiento, mientras que el cuerpo SOAP contiene el método llamado y
los parámetros con los que se llama al mismo.
Todo esto es un modelo de mensajes request/response con una forma de describir un conjunto de
métodos y pasarle a los mismos parámetros. Esto parece la base del protocolo RPC y de hecho es el
uso más común de SOAP. El potencial es entregar esto sobre Internet utilizando HTTP para realizar
comunicaciones entre organizaciones permitiendo realizar comunicaciones entre aplicaciones con
diferente plataforma, sistema operativo y lenguaje de programación.
A continuación se muestra un mensaje SOAP embebido en un request HTTP:
Este ejemplo invoca al servicio StockQuote llamando al método GetLastTradePrice con el símbolo
DIS por parámetro.
Si usted quedó asustado por la aparente complejidad del protocolo SOAP pensando lo engorroso
que sería armar los mensajes de requerimiento y parsear los mensajes de respuesta despreocúpese;
la mayoría de los lenguajes de programación proveen o proveerán soporte para realizar esto. La idea
fundamental consiste en utilizar algún objeto al cual se le brinda un WSDL y se le indica qué método
se quiere llamar y con qué parámetros. Esto arma en tiempo de ejecución el mensaje SOAP, lo
manda y parsea el resultado adjudicándoselo a alguna variable en forma trasparente para el usuario
como si hubiera hecho un call común.
Type: Describe los tipos no estándar usados por los mensajes (Message).
Message: Define los datos que contienen los mensajes pasados de un punto a otro.
PortType: Define una colección de operaciones brindadas por el servicio. Cada operación tiene un
mensaje de entrada y uno de salida que se corresponde con algún Message antes definido.
Binding: Describe los protocolos que se utilizan para llevar a cabo la comunicación en un
determinado PortType; actualmente los protocolos soportados son SOAP, HTTP GET, HTTP POST y
MIME, siendo SOAP el más utilizado.
Port: Define una dirección (URL) para un determinado Binding.
El mismo define dos mensajes (Simple.foo y Simple.fooResponse), luego define un método llamado
“foo” el cual recibe el mensaje Simple.foo y retorna el mensaje Simple.fooResponse. A continuación
se define un binding para el método foo asociándolo con el protocolo SOAP. Por último se da una
URL física que implementa lo antes descrito.
Interfaz e implementación
La estructura básica de archivo con formato WSDL podría ser dividido en dos partes lógicas: la
interfaz del servicio, y la implementación del mismo.
Contiene una definición abstracta y reusable del servicio que puede ser instanciada y referenciada
por distintos proveedores del mismo.
Port, Service.
A partir de esta división lógica se puede definir por medio de una Interfaz del servicio un estándar
para realizar, por ejemplo, órdenes de compras que puede ser reutilizada e implementada por todas
las empresas, sin tener que redefinir cada una de ellas la interfaz.
Si al igual que con SOAP se siente preocupado por la complejidad de los archivos WSDL de nuevo
despreocúpese; la mayoría de los lenguajes de programación proveen o proveerán herramientas
para generar en forma automática el archivo WSDL a partir de un determinado método o función.
Cada bindingTemplate tiene asociado un tModel, el cual brinda informacíon sobre las
especificaciones del servicio, por ejemplo, cómo tienen que ser los mensajes que el servicio espera
y responde, etc.
Un tModel puede ser asociado con elementos bindingTemplate de distintas empresas que
brindan la misma especificación del servicio. Utilizando entonces los tModels se pueden
encontrar todas las empresas que brindan tal servicio.
Por más información sobre el esquema UDDI:
http://www.uddi.org/pubs/ProgrammersAPI_v2.pdf
API UDDI
El acceso al registro UDDI, ya sea para realizar búsquedas o para ingresar o modificar un registro, se puede
realizar a través de una página Web que implemente el acceso o utilizando ciertas interfaces (Web Services)
que provee la especificación de UDDI. Estas interfaces están descriptas en una API, que puede ser dividida en
dos partes lógicas, la API de consultas y la API de publicación.
Por más información sobre la API UDDI: http://www.uddi.org/pubs/ProgrammersAPI_v2.pdf
Un ejemplo
Las formas en que se pueden realizar negocios utilizando Web Services son muy variadas. El
consumidor podría pagar por utilizar los servicios brindados por un proveedor, o el proveedor podría
pagar para que aparezcan los servicios que él ofrece en un determinado consumidor, o incluso
existen casos en los cuales ni el consumidor ni el proveedor pagan por consumir o proveer los
servicios en forma respectiva. Este es el caso que se presenta a continuación.
Este es un ejemplo de uso de Web Services en el cual ni el consumidor ni los proveedores pagan; a
ambos les sirve este intercambio ya que la compañía de aviones le brinda un valor agregado a sus
clientes, y los hoteles y rentadoras de autos están expuestos a ser contratos por potenciales clientes.
Es más, estas empresas no publicaron sus servicios para que fueran exclusivamente utilizados por la
compañía aérea, sino que los mismos pueden ser descubiertos y utilizados por cualquier empresa
que los necesite.
Claramente se muestra en este ejemplo el gran poder de los Web Services, y la ventaja que tendrán
las empresas que los sepan utilizar en forma adecuada con respecto a las otras. Imagínese en este
caso si usted fuera a reservar boletos de avión y pudiera elegir por una compañía que además de
reservar los boletos le permitiera hacer la reserva de hotel, y otra que no; ¿por cual haría la reserva?
Por otro lado imagine que usted es dueño de una rentadora de autos y sabe que su competencia
está brindando sus servicios en un portal de una compañía aérea y usted no, ¿qué haría?
XML
Introducción
Hoy en día, se pueden encontrar muchísimos sitios Web que brindan servicios on-line como por
ejemplo reservas de asientos para espectáculos, aviones, reportes meteorológicos, etc.; para poder
brindar estos servicios a los usuarios, los diseñadores y los programadores Web deben combinar los
datos y la presentación en un documento HTML. Muchas veces el proveedor de determinada
información no es quien la va a “procesar” (sea esto publicarla en un sitio, ingresarla en una
aplicación, etc).
Descripción
El lenguaje XML está compuesto por etiquetas que describen el contenido del documento. Un
elemento XML queda definido por una etiqueta de comienzo y otra de fin con el valor del elemento
entre ambas etiquetas. Los elementos pueden estar anidados y además pueden contener en forma
opcional, uno o más atributos. Los atributos son usados para adjuntar información secundaria a los
elementos.
<time>08:00</time>
<area>
<city>Montevideo</city>
<country>Uruguay</country>
</area>
<measurements>
<skies>partly cloudy</skies>
<temperature>26</temperature>
<wind>
<direction>SW</direction>
<windspeed>6</windspeed>
</wind>
<humidity>87</humidity>
<visibility>10</visibility>
</measurements>
</weather-report>
El ejemplo anterior está compuesto únicamente por elementos XML, pero el mismo podría
redefinirse, de forma que la información correspondiente al área estuviese representada por
atributos, como se representa a continuación:
<time>08:00</time>
<measurements>
<skies>partly cloudy</skies>
<temperature>26</temperature>
<wind>
<direction>SW</direction>
<windspeed>6</windspeed>
</wind>
<humidity>87</humidity>
<visibility>10</visibility>
</measurements>
</weather-report>
Si bien el hecho de estar compuesto por etiquetas hace que sea parecido a HTML, hay una diferencia
muy importante: en un documento XML no hay información acerca de cómo deben ser presentados
los datos. Así, como HTML provee etiquetas específicas para formatear un documento, XML provee
un marco para crear etiquetas.
Resumiendo, XML es un lenguaje estándar definido por el Consorcio World Wide Web para permitir
grabar y leer datos en forma estructurada con formato estándar independiente de aplicaciones y
vendedores.
Protocolo SOAP
Introducción
SOAP es un protocolo “liviano” basado en XML, para invocar procedimientos en forma remota
(Remote Procedure Call). Utiliza cualquier protocolo que permita transportar mensajes de texto,
siendo HTTP el más utilizado.
Su especificación describe el contenido que debe tener un mensaje XML para ser usado en una
invocación remota.
Cualquier aplicación que cumpla la especificación puede invocar y proveer servicios sin importar en
que lenguaje o plataforma esté implementado, lo único necesario es que la aplicación sea capaz de
interpretar el mensaje SOAP que recibe, realizar el procesamiento que el mensaje requiera, y
devolver otro mensaje SOAP con la respuesta.
En las aplicaciones generadas por GeneXus se utiliza SOAP para invocar a objetos en forma remota,
usando HTTP como protocolo de transporte.
Alcance
Los objetos llamadores son los que invocan servicios mediante SOAP.
Los objetos llamados son los que brindan un servicio invocado mediante SOAP.
Descripción
Algunas de las ventajas de utilizar este protocolo en aplicaciones GeneXus son la posibilidad de
desarrollar servicios Web, así como el poder hacer invocaciones entre objetos de diferentes
generadores (por ej. llamar desde Java a .NET).
Servidor
Para indicar en GeneXus que un objeto main va a ser llamado utilizando el protocolo SOAP, se
deberá seleccionar el valor “SOAP” en la propiedad “Options/Call Protocol”. Nos referiremos en
adelante a dichos objetos como “Servidores” o “Servicios Web”. Solo pueden ser reportes o
procedimientos, sin ningún tipo de interfaz con el usuario.
Se requiere un servidor Web que haga el hosting de los servicios a ser invocados.
Los programas Servidores reciben la invocación http, procesan el mensaje SOAP que envía el Cliente
con sus parámetros, realizan la acción requerida, y generan otro mensaje SOAP de respuesta
(eventualmente con los parámetros modificados).
Cliente
Los objetos que van a invocar al servicio Web, a los que llamaremos “Clientes”, pueden ser cualquier objeto
GeneXus. La invocación se hace con el comando call() de GeneXus.
Los programas Clientes realizan las tareas necesarias para ensamblar el mensaje SOAP, hacer la invocación
http, y desensamblar la respuesta, obteniendo los parámetros modificados en forma automática. Todo esto
se realiza en forma automática y transparente para el usuario.
Locations
Para indicar cual va a ser la ubicación de los servicios invocados se utiliza un esquema conocido
como Locations.
Manejo de errores
Mayor que 0 y menor que 10000: Algún parámetro retornado por el servidor no tiene el
nombre esperado. El código de error indica la posición del parámetro que ocasionó el
conflicto.
Menor que 0 y mayor que -10000: Sucedió un error al interpretar el XML de respuesta.
Sucederá por lo general si la respuesta no es XML o no es XML bien formado. Si se toma el
valor absoluto del código de error el resultado corresponderá a un código de error del
objeto XMLReader. De todas formas, getSOAPErrMsg() retornará una descripción del error.
Menor que -10000: Sucedió un error en la comunicación HTTP. Si se toma el valor absoluto
del código de error y se le resta 10000 el resultado corresponderá a un código de error del
objeto HTTPClient. De todas formas, getSOAPErrMsg() retornará una descripción del error.
-20004: El servidor retornó que hay un error en el pedido SOAP realizado por el cliente. En
este caso getSOAPErrMsg() retornará un mensaje conteniendo el código y el mensaje de
error retornados por el servidor. Si el servidor es un procedimiento o reporte GeneXus,
retornará alguno de los códigos de error descriptos más abajo.
-20001: El mensaje recibido es un XML válido pero no es un mensaje SOAP válido (igual que
en el cliente).
-20002: El método llamado no es el esperado. (El método SOAP de los objetos GeneXus
siempre se llama “Execute”).
A continuación se detallan los mecanismos para proveer y consumir Web Services con GeneXus.
Proveer
Para proveer Web Services con GeneXus se debe definir un objeto Procedimiento o Reporte, que
debe ser de tipo main, y asociado a un generador Web.
Se debe publicar el objeto en un servidor Web, con lo que el Web Service queda operativo para ser
invocado.
El WSDL del servicio queda disponible agregando el parámetro wsdl a la URL del mismo. Por
ejemplo:
http://server/baseurl/aservice.aspx?wsdl
Consumir
Se utiliza el WSDL Inspector, que permite importar la definición del servicio que se desea consumir.
Se debe indicar el WSDL del mismo, y el utilitario definirá los tipos de datos necesarios para poder
consumirlo desde GeneXus.
En el caso de que el Web Service utilice tipos de datos estructurados, los mismos serán agregados a
la base de conocimiento al importar la definición con el WSDL Inspector.
Además, es necesario configurar la propiedad de objeto Location. Esto servirá luego para configurar,
en los objetos GeneXus que vayan a invocar al Web Service, la ubicación del mismo (host, port, etc.).
Práctico: Creación de Web Service Genexus
En esta sección crearemos un Web Service GeneXus, y veremos como consumirlo desde una
aplicación GeneXus.
Supongamos que quisiéramos publicar un servicio de nuestro sitio Web, por ejemplo un ranking con
los 10 destinos más elegidos.
Lo primero es definir un SDT con las siguientes características, que nos permita almacenar la
información de los destinos que nos interesa publicar:
Nombre: Destinationsdt
Structure Type
CountryId Identifier
CountryName Character(20)
CityId Identifier
CityName Character(20)
Definiremos una variable que nos permita contar la cantidad de ciudades: &Qty, más una variable
que permita almacenar toda la colección de destinos más elegidos (Destination) junto con una
variable que cargue cada uno de los items de esa colección de destinos (DestinationItem).
Las variables a definir entonces son las siguientes:
Name Type
Qty N(2)
Destination S(Destinationsdt)
DestinationItem S(Destinationsdt.DestinationsdtItem)
&Qty = 1
&DestinationItem.CityId = CityId
&DestinationItem.CityName = CityName
&DestinationItem.CountryId = CountryId
&DestinationItem.CountryName = CountryName
&Destination.Add(&DestinationItem)
&Qty +=1
if &Qty > 10
exit
endif
endfor
Rules:
parm(out:&Destination);
Resulta necesario que el procedimiento sea main, y configurar la propiedad “Call protocol” con el
valor “SOAP”.
Luego de generar y compilar el procedimiento Ranking, verifique el Web Service generado
automáticamente por GeneXus, digitando la siguiente URL en el browser:
http://localhost/practico/aranking.aspx?wsdl
A continuación crearemos un Web Panel que será el consumidor del Web Service “Ranking”
recientemente creado.
En general un Web Service será externo a la base de conocimiento, por lo cual vamos a crear una
nueva base de conocimiento para crear ese Web Panel al que llamaremos ViewRanking. Como se
describe a continuación.
Observe que el método del Web Service es “Execute” y el tipo de datos que
devuelve es “Destinationsdt”.
Cuando se hace clic en el botón “Add Reference” se definen los tipos de datos
además de toda la información necesaria para poder consumir el Web Service.
3. Creación del Web Panel ViewRanking, para eso definiremos las siguientes
variables:
Name Type
CityId Character(3)
CityName Character(20)
CountryId Character(3)
CountryName Character(20)
Destination S(Destinationsdt)
DestinationItem S(Destinationsdt_DestinationsdtItem)
Rank O(org_tempuriaction_.Ranking)
El form del Web Panel ViewRanking contendrá un grid con las variables &CityId, &CityName,
&CountryId y &CountryName. Y se deberá programar los eventos Refresh y Load del Web
Panel, como se muestra a continuación:
Event Refresh
EndEvent // Refresh
Event Grid1.Load
&CityId = &DestinationItem.CityId
&CityName = &DestinationItem.CityName
&CountryId = &DestinationItem.CountryId
&CountryName = &DestinationItem.CountryName
load
endfor
EndEvent // Grid1.Load
Una de las características interesantes de los Web Services, es que podemos agregar valor a nuestro
sitio Web, sin necesidad que el usuario deba ir a otro sitio. Es importante evitar “perder” el usuario
al llevarlo a otras páginas Web.
Lo que queremos ver en esta sección es como incluir un Web Service externo no GeneXus en nuestra
aplicación (ya hemos visto en este capítulo un ejemplo de como crear y consumir un Web Service
hecho con GeneXus).
Lo que haremos es importar un Web Service que provée Google. Google es una compañía
especializada en la búsqueda de información en la Web. En su página Web (http://www.google.com)
se puede ingresar una lista de palabras por las cuales buscar y retorna todos los sitios Web en las
cuales encontró esas palabras. Esta misma funcionalidad Google la provee por medio de un Web
Service.
El WSDL Inspector permite a partir del WSDL de un Web Service definir los tipos de datos necesarios
en GeneXus para poder consumir el Web Service en forma transparente, sin tener que preocuparse
de los protocolos involucrados en el proceso y la definición del mismo.
Entonces, el procedimiento a seguir para incluir el Web Service de Google en el sitio Travel Agency
es el siguiente:
Notar en el costado inferior izquierdo los tipos de datos complejos que va a crear
GeneXus para consumir el Web Service en forma adecuada.
4. Presionar el botón “Add Reference” para que GeneXus cree en la base de conocimiento
todo lo necesario para consumir el Web Service.
Nombre Tipo
Ws GoogleSearch.GoogleSearchService
Return GoogleSearchResult
ResultElements ResultElementArray
ResultElement ResultElement
Ya están definidas en el xpz el resto de las variables necesarias para hacer el ejercicio.
Luego, debemos programar el evento search.click de la siguiente forma:
Event search.click
&Key = "3yHXpPZQFHKdexiyPjqTPYNqVvnYj8cZ"
&MaxResult = 10
&Filter = 1
&SafeSearch = 1
&Return=
&Ws.doGoogleSearch(&Key,trim(&Query),&Start,&MaxResult,&Filter,&Restrict,&Safesearch,&Lr,&
Ie,&Oe)
&ResultElements = &Return.resultElements
&searchTime = &return.searchTime
EndEvent
En este evento se realiza la invocación al método doGoogleSearch del Web Service. Los resultados
son devueltos en una Collection de un tipo de datos estructurado, el que es definido
automáticamente en GeneXus por el WSDL Inspector.
Event Grid1.Load
Title.Caption = &ResultElement.title
&url = &resultElement.URL
Title.LinkTarget = "_BLANK"
Title.Link = link(&ResultElement.URL)
&Summary = &ResultElement.snippet
&cachedsize = &resultelement.cachedSize
grid1.Load()
Endfor
EndEvent
En este evento se recorre la Collection con los resultados devueltos por el Web Service y se realiza la
carga del grid.
Nota: La especificación del Web Service del ejemplo, se puede leer de:
http://www.google.com/apis/reference.html
Introducción
Cuando se produce un error al realizar una llamada SOAP desde GeneXus, es bastante difícil en
ocasiones saber donde se encuentra el problema. Es necesario contar con alguna forma de poder
efectuar un debug.
En este documento se presentan una serie de pasos para verificar cuando se produce una situación
de este tipo, así como también se detalla el uso de un utilitario de libre distribución que puede
resultar de utilidad.
Aunque este documento está orientado específicamente a las llamadas SOAP, también aplica en
forma general a la detección de problemas utilizando los tipos de datos HTTP.
Descripción
Cuando se produce un error en una llamada SOAP, es conveniente verificar ciertos puntos en el
siguiente orden:
Una causa obvia del fallo puede ser el hecho de que el Web Service al que se está invocando no esté
operativo, ya sea porque el servidor está caído u otras causas.
Para verificar esto se puede invocar al archivo WSDL, en el caso de que el Web Service haya sido
desarrollado con GeneXus, se deberá llamar a la siguiente URL en un browser:
http://servidor:port/url_base/servicio?wsdl
Por ejemplo, para invocar al servicio que devuelve la Edición de las noticias de ARTECH, sería:
http://www.gxtechnical.com/cgi-bin/adevedicion.exe?wsdl
Deberá visualizarse un archivo XML válido y no un error HTTP . Por ejemplo algo como:
- <types>
<schema targetNamespace="http://www.gxtechnical.com/cgi-
bin/adevedicion.exe?type" xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
elementFormDefault="qualified" />
</types>
- <message name="DevEdicion.Execute">
</message>
.
2) Verificar que la llamada se hace a la URL correcta
Otro punto a verificar es que la URL a la que se está invocando sea la correcta.
Entonces se deben verificar los valores de dichas propiedades, para lo cual se deberá definir una
variable de tipo Location (en caso de que no existir) y asignarla al location del objeto llamado,
utilizando la función GetLocation(). Se pueden entonces evaluar las propiedades, asignándolas por
ejemplo a variables que se despliegan por pantalla. Algo similar a:
.
&Loc = GetLocation(“<Nombre_location>”)
&Host = &Loc.Host
&Port = &Loc.Port
&URLBase = &Loc.BaseUrl
call(PMiServicio,......)
Otro valor a considerar es la extensión agregada al nombre del objeto, esto dependerá del
generador asociado al main correspondiente.
Para tener la seguridad de que la invocación se está realizando con la extensión correcta, remitirse al
punto 4.
.
&Loc = GetLocation(“<Nombre_location>”)
&Host = &Loc.Host
&Port = &Loc.Port
&URLBase = &Loc.BaseUrl
call(PMiServicio,......)
&ErrCode = GetSoapErr()
&ErrCodeDsc = GetSoapErrMsg()
Si los puntos anteriores no nos llevaron a la solución del problema, es conveniente verificar el
Request y el Response HTTP que se generan. Existen varias herramientas con las que se puede hacer
esto, en particular mostraremos tcpTrace, un utilitario de libre distribución que puede obtenerse en
http://www.pocketsoap.com/tcptrace/. El mismo no necesita instalación, es solamente un
ejecutable.
Mirando el header del Request se puede verificar que la URL base y la extensión que se están
generando sean correctas. El body (lo que esta después de la línea que comienza con Content-
lenght) es el mensaje SOAP de la llamada, debe ser un XML bien formado.
En la ventana inferior derecha se ve el Response del Web Service. Si se devolvió algún error HTTP, el
mismo se puede visualizar en el header del mismo, y en el body se muestra alguna descripción. En el
caso de que el servicio finalizó en forma exitosa, se devuelve un código 200, y en el body aparece el
Response SOAP (a partir de la línea en blanco posterior al header). El mismo también deberá ser un
XML bien formado (para verificar esto se puede copiar y pegar el contenido, salvarlo como un
archivo con extensión XML, y abrirlo con un browser).
WSDL Inspector
Introducción
El WSDL Inspector permite a partir del WSDL de un Web Service definir los tipos de datos necesarios
en GeneXus para poder consumir el Web Service en forma transparente sin tener que preocuparse
de los protocolos involucrados en el proceso y la definición del mismo.
Descripción
El WSDL de un Web Service es un archivo que describe al mismo; brinda toda la información
necesaria para poder consumirlo.
GeneXus brinda una herramienta llamada WSDL Inspector que permite a partir del WSDL de un Web
Service definir en la base de conocimientos todo lo necesario para poder consumir los métodos del
Web Service en forma transparente.
Para acceder al WSDL Inspector hay que ejecutar la opción Tools / WSDL Inspector. La misma está
solamente accesible desde Design.
En “Web Service URL” se debe ingresar el camino hacia el WSDL. Puede ser referenciado por medio
del protocolo http (por ej. http://api.google.com/GoogleSearch.wsdl ) o file (por ejemplo:
file:C:\Servicios\AmazonWebServices.wsdl).
Una vez ingresado el camino del WSDL se debe presionar el botón “Inspect”, con lo cual en caso de
no existir ningún error se mostrará la información de los distintos métodos que brinda el Web
Service, junto con los tipos de datos necesarios para poder consumirlos.
Para poder “importar” la información necesaria dentro de la base de conocimiento que permita
consumir el Web Service se debe presionar el botón “Add Reference”.
En la imagen anterior se muestra la información de un Web Service simple, el cual cuenta con un
solo método llamado BabelFish que recibe dos parámetros de entrada de tipo Character y retorna
otro parámetro de tipo Character.
El siguiente ejemplo muestra otro caso en el cual el Web Service cuenta con más de un método y se
necesita definir nuevos tipos de datos (ArrayOfNewsCategoty, NewsCategoty,
ArrayOfBusnessShortNews, BusnessShortNews):
Add Reference
De esta forma se puede definir una variable a la cual asignarle el tipo de datos definido para el Web
Service y utilizando los métodos de la misma poder invocar a los distintos métodos que el Web
Service provee. Si para consumir el método se necesitan tipos de datos estructurados hay que crear
variables con los tipos de datos estructurados creados por el Inspector.
De esa forma se puede definir una variable a la cual asignarle ese tipo de datos; llamaremos a la
misma “ws”.
Luego podremos invocar utilizando la variable “ws” a cualquiera de los métodos que el Web Service
provee (en este caso solo uno) de la siguiente forma:
Eso es todo!, de esta forma se puede invocar a un Web Service en forma sencilla sin tener que
preocuparse de los protocolos involucrados en el proceso y la definición del mismo; solamente se
tuvo que dar la ubicación de su WSDL y GeneXus se encargó de esconder la complejidad y definir un
tipo de datos que represente al Web Service.
MÉTODO CON TIPO DE DATOS ESTRUCTURADO
Ahora vamos a consumir un Web Service que utiliza dos tipos de datos estructurados.
(com_swanandmokashi.Horoscope)
ZodiacSign Character(9999)
DailyForecast Character(9999)
&array = &ws.GetHoroscope()
&SodiacSign = &item.ZodiacSign
&ForeDailiy = &item.DailyForecast
load
endfor
Donde:
De esta forma se consume un Web Service que usa tipos de datos estructurados.
Nota: En el caso de tipos de datos booleanos, se debe utilizar el tipo de datos numérico N(1). El valor
1 se corresponde con el True, y el 0 con el False.
De la misma forma que con el llamado de los procedimientos SOAP, es posible modificar diferentes
parámetros de la invocación de Web Services utilizando los locations.
El nombre del location (indicado en el tag <GXLocation name=> del archivo location.xml, que debe
utilizarse es el nombre que GeneXus le asigna al tipo de datos creado por el WSDL Inspector para el
servicio, sustituyendo el último punto (.) por un underscore (_).
Por ejemplo, en el caso del Web Service de Horóscopo anterior, en GeneXus el tipo de datos para el
servicio muestra:
com_swanandmokashi.Horoscope
com_swanandmokashi_Horoscope
El archivo location.xml debe de estar en el directorio corriente y sólo se toma en cuenta en tiempo
de ejecución.
Por ejemplo si se quiere redireccionar el Web Service a localhost:88 se tiene que tener un
location.xml de la siguiente forma:
<GXLocations>
<GXLocation name="com_swanandmokashi_Horoscope">
<Common>
<Host>localhost</Host>
<Port>88</Port>
</Common>
<HTTP>
<BaseURL>/HomePage/WebServices/</BaseURL>
</HTTP>
</GXLocation>
</GXLocations>
Ejemplo
En GXOpen se encuentra una base de conocimiento de ejemplo en la cual se consumen tres Web
Services; GXChart (servidor de gráficas), Babelfish (traductor de textos) y GetJoke (provee chistes
agrupados por categorías).
Consideraciones
Para consolidar objetos que tengan variables de tipos de datos asociados a Web Services, es
necesario previamente agregar la referencia con el WSDL Inspector en la base de conocimiento
destino. Otra opción es copiar los archivos asociados al Web Service desde el directorio
<dir.KB>\kbdata\usrtypes de la base de conocimiento origen a la destino (se generan dos archivos
con extensiones .ari y .xml por cada Web Service agregado, que contienen las definiciones del
mismo). Además, luego de consolidarlo, es necesario en el objeto borrar y volver a definir la/s
variable/s de ese tipo, de lo contrario se producirá un error de especificación:
Cuando se compila un objeto main se compilan todos los tipos de datos definidos en lugar de
compilar solamente los usados por ese main.
Locations
Introducción
Se busca permitir configurar las invocaciones a objetos main GeneXus en forma remota, cuando se
utilizan diferentes protocolos, por ej. llamadas vía SOAP. Dichas configuraciones se pueden hacer tanto usando el
tipo de datos Location de GeneXus como el archivo location.xml.
Alcance
Aplica a los siguientes objetos: Transacciones, Work Panels, Web Panels, Reportes, Procedimientos.
Para los siguientes generadores: .NET, Java, Visual Basic y Visual FoxPro.
Descripción
Cada programa main de GeneXus tiene asignado un location. Éste es un nombre lógico al que se le
hace corresponder una ubicación válida para el caso de que el objeto sea invocado, según el
protocolo que se utilice.
Necesitamos entonces describir las características de este location, para lo que se utiliza el siguiente
esquema:
En primer lugar, se asigna al objeto a ser invocado un nombre lógico, configurando el mismo en la
propiedad Location de dicho objeto.
Será necesario entonces poder configurar los locations, según los diferentes protocolos que se
utilicen para la invocación del objeto. Existen tres instancias posibles para realizar esto:
1) En tiempo de generación.
Es decir que las propiedades especificadas en tiempo de ejecución mediante código tendrán
preferencia sobre las especificadas en tiempo de ejecución mediante un archivo y éstas a su vez
tendrán preferencia sobre las especificadas en tiempo de generación para permitir mayor
dinamismo en la configuración de los locations.
Propiedades
Se describen a continuación las propiedades disponibles para describir el location en el archivo XML:
HOST
Especifica la dirección del servidor correspondiente al location.
&Location.Host = “www.soaplocation.com”
Ejemplo en XML
<Host>www.soaplocation.com</Host>
PORT
Especifica el puerto en el servidor correspondiente al location.
&Location.Port = 8080
Ejemplo en XML
<Port>8080</Port>
BASEURL
Especifica la URL base del location, en caso de utilizar el protocolo HTTP. La URL final tiene la forma
http://Host:Port/BaseUrl/pgmname. Si se necesitan varias BaseUrls sobre el mismo servidor se
deberá definir un location para cada una.
&Location.BaseURL = “/mydirectory/soap/”
Ejemplo en XML
<BaseURL>/mydirectory/soap/</BaseURL>
SECURE
Especifica si los llamados al location se harán mediante un protocolo seguro o no, en caso de utilizar
el protocolo HTTP. Si esta propiedad tiene el valor 1 se utilizará el procolo HTTPS.
&Location.Secure = 1
Ejemplo en XML
<Secure>1</Secure>
TIMEOUT
Especifica el tiempo, en segundos, a esperar por una respuesta del servidor. Si el valor es 0, la espera
es indefinida.
&Location.Timeout = 1
Ejemplo en XML
<Timeout>1</Timeout>
AUTHENTICATION
Especifica si se utilizará autentificación con el servidor o no.
&Location.Authentication = 1
Ejemplo en XML
<Authentication/>
AUTHENTICATIONMETHOD
Especifica el método de autentificación con el servidor, en caso de utilizarla. Los posibles valores son
los mismos que en el objeto HTTPClient.
&Location.AuthenticationMethod = 1
Ejemplo en XML
<Authentication>
<Method>1</Method>
</Authentication>
AUTHENTICATIONREALM
Especifica el realm para la autentificación con el servidor, en caso de utilizarla.
&Location.AuthenticationRealm = “MyRealm”
Ejemplo en XML
<Authentication>
<Realm>MyRealm</Realm>
</Authentication>
AUTHENTICATIONUSER
Especifica el nombre de usuario para la autentificación con el servidor, en caso de utilizarla.
&Location.AuthenticationUser = “Name”
Ejemplo en XML
<Authentication>
<User>Name</User>
</Authentication>
AUTHENTICATIONPASSWORD
Especifica la contraseña para la autentificación con el servidor, en caso de utilizarla.
El valor por defecto es “”.
&Location.AuthenticationPassword = “MyPassword”
Ejemplo en XML
<Authentication>
<Password>MyPassword</Password>
</Authentication>
El archivo location.xml utilizado para describir los locations empleados en la base de conocimiento
debe tener el siguiente formato:
<GXLocations>
<GXLocation name=”NombreDelLocation”>
<Common>
Propiedades
</Common>
<Protocolo>
Propiedades
</Protocolo>
<Protocolo>
Propiedades
</Protocolo>
.
.
<Protocolo>
Propiedades
</Protocolo>
</GXLocation>
</GXLocations>
Las propiedades en el elemento Common aplican a todos los protocolos. Las propiedades
especificadas en un protocolo en particular tendrán prioridad sobre estas.
Para poder modificar las propiedades de un location en tiempo de ejecución es necesario definir una
variable de tipo Location y asignarle alguna de las locations existentes. Esto se puede hacer con la
función getLocation( LocationName) que toma como parámetro una cadena con el nombre de algún
location existente y devuelve un tipo Location.
Por ejemplo si definimos la variable &Loc de tipo Location y tenemos algún procedmiento con la
propiedad location en “MyLocation”, podemos ejecutar &Loc = getLocation( “MyLocation”) y luego
modificar sus propiedades. Las modificaciones así realizadas son globales. En cualquier momento
posterior en que se haga un llamado a un procedimiento en dicho location se tendrán en cuenta las
últimas propiedades asignadas.
<GXLocations>
<GXLocation name=”Location1”>
<Common>
<Host>www.soapserver1.com</Host>
<BaseURL>/soap/services/</BaseURL>
<Timeout>30</Timeout>
</Common>
</GXLocation>
<GXLocation name=”Location2”>
<Common>
<Host>www.soapserver2.com</Host>
<Port>80</Port>
</Common>
<HTTP>
<BaseURL>/webservices/</BaseURL>
<Port>8080</Port>
<Secure>1</Secure>
<Authentication>
<User>UserName</User>
<Password>Password</Password>
</Authentication>
</HTTP>
</GXLocation>
</GXLocations>
Con este archivo location.xml (usado tanto en tiempo de generación como en tiempo de ejecución),
los locations Location1 y Location2 tendrán las siguientes propiedades:
Port 80 8080
Secure 0 1
Timeout 30 0
Authentication 0 1
AuthenticationMethod 0 0
Introducción
El objetivo del tipo de datos XMLWriter es proveer la posibilidad de grabar archivos XML de un modo
más sencillo que las funciones incluidas en versiones anteriores. El documento XML contiene una
introducción a dicho lenguaje.
Alcance
Aplica a los siguientes objetos: Transacciones, Work Panels, Web Panels, Reportes, Procedimientos.
Para los generadores: .NET, Java, Visual Basic y Visual FoxPro.
Descripción
Para poder crear un archivo XML desde un objeto GeneXus, se debe definir una variable de un nuevo
tipo de datos denominado XmlWriter (xmlwrt) y luego invocar a los métodos necesarios para crear
los nodos que lo componen.
Métodos
MÉTODOS BÁSICOS
Open([FileName])
FileName – Character
OpenToString()
El contenido del buffer puede ser consultado por medio de la propiedad ResultingString.
WriteStartElement(<ElementName>)
Comienza un elemento compuesto. Este elemento puede tener subelementos, por lo que es
valido anidar llamadas a WriteStarElement/WriteElement.
<ElementName> - Character
WriteElement(<ValueName>, <ElementValue>)
<ValueName>- Character
<ElementValue>- Character
WriteText(<Value>)
Genera character data con el string <Value>. Se sustituyen los caracteres especiales
por secuencias de caracteres (el '<' se sustituye por '<', el '>' por '>', etc.).
<Value> - Character
WriteRawText(<Value>)
Genera cualquier texto sin sustituir los caracteres especiales por secuencias de
caracteres.
<Value> - Character
WriteAttribute(<AttriName>, <AttriValue>)
Asigna un atributo al último elemento. Es decir, al elemento que se creó con la última
invocación a WriteStartElement(<ElementName>) o WriteElement(<ValueName>,
<ElementValue>).
<AttriName> - Character
<AttriValue> - Character
WriteEndElement()
Close()
Cierra el documento.
OTROS MÉTODOS
WriteComment(<Comment>)
Ejemplo:
<Comment> - Character
WriteEntityReference(<Entity>)
Ejemplo:
&Entidad;
<Entity> - Character
WriteCData(<DataValue>)
Ejemplo:
<![CDATA[value]]>
<DataValue> - Character
WriteProcessingInstruction(<Action>, <Value>)
Escribe el registro del tipo processing instruction indicado por <Action> y <Value>.
Ejemplo:
<Action> - Character
Enconding - Character
WriteDocType(<DocName> [,SubSet])
<DocName> - Character
SubSet – Character
WriteDocTypeSystem(<DocName>,<uri> [,SunSet])
Escribe la declaración DOCTYPE del documento XML con una declaración de tipo
SYSTEM. Si se incluye un SubSet se ingresa entre corchetes al final de la declaración.
Ejemplo:
<DocName> - Character
<uri> - Character
SubSet – Character
Ejemplo:
<DocName> - Character
<PubId> - Character
<uri> - Character
Subset - Character
PROPIEDADES
Indentation
Define cuantos caracteres se utilizan para indentar el código generado. Por defecto es 2.
IndentChar
Define el carácter que se utiliza para indentar el código generado. Por defecto se utiliza un
espacio en blanco.
ErrCode
Retorna un valor mayor que cero en caso de haber ocurrido un error durante la generación
del documento XML.
ErrDescription
Contiene la descripción del error ocurrido cuando ErrCode tiene un valor distinto de cero.
ResultingString
Permite consultar el valor del documento XML que se encuentra en un buffer interno
cuando el documento se creó a partir del método OpenToString().
En esta sección se describen las funcionalidades disponibles para generar documentos XML que
utilizan namespaces.
MÉTODOS
WriteNSStartElement(<LocalName> [,Prefix, NameSpaceURI])
Este método es análogo al WriteStartElement.
Si se indica un NameSpaceURI que no está en el ámbito de definición del elemento, o este
tiene un prefijo diferente del parámetro Prefrix, se crea automáticamente el atributo
xmlns:prefix=URI
<LocalName> - Character
Prefix - Character
NameSpaceURI - Character
<LocalName> - Character
NameSpaceURI - Character
WriteAttribute(<LocalName>, <Value>)
Cuando se trabaja con documentos con name sapace, el método WriteAttribute tiene un
comportamiento especial para algunos atributos. Si el nombre del atributo es “xmlns” o
comienza con “xmlns:” se registra la definición del atributo como la definición de un
namespace.
De esta forma, en futuras invocaciones de un método WriteNSStartElement o
WriteNSElement puede determinarse el prefijo correspondiente a una determinada URI.
&writer.Open(‘ejemplo.xml’)
&writer.WriteNSStartElement(‘a’)
&writer.WriteAttribute(‘xmlns:p1’, ’http://www.artech.com’)
&writer.WriteAttribute(‘xmlns’, ‘http://defecto.com’)
&writer.WriteAttribute(‘att’, ‘a1’)
&writer.WriteNSElement(‘b’, ’http://www.artech.com’)
&writer.WriteAttribute(‘att’, ‘a1’)
&writer.WriteAttribute(‘p1:att2’, ‘a2’)
&writer.WriteNSElement(‘b’, ’http://www.genexus.com’)
&writer.WriteAttribute(‘xmlns:p1’,’http://www.genexus.com’)
&writer.WriteAttribute(‘xmlns:p2’,’http://www.artech.com/segundo’)
&writer.WriteAttribute(‘p2:att1’, ‘a1’)
&writer.WriteEndElement()
&writer.Close()
<a
xmlns:p1="http://www.artech.com"
xmlns="http://defecto.com"
att="a1">
<p1:b
att1="a1"
p1:att2="a2"
/>
<p1:b xmlns:p1="http://www.genexus.com"
xmlns:p2="http://www.artech.com/segundo"
p2:att1="a1"
/>
</a>
Ejemplo
El siguiente procedimiento genera un archivo llamado Reunion.xml que contiene datos de una
reunión, indicando que integrantes participaron de la misma, y cuales son las tareas de cada uno.
&filexml.open('Reunion.xml')
&filexml.WriteStartDocument()
&filexml.WriteStartElement('REUNION')
&filexml.WriteAttribute('Fecha', dtoc(ReuFch) )
&filexml.WriteElement('FECHA', dtoc(ReuFch) )
&filexml.WriteComment('Descrpción de la reunión')
&filexml.WriteCData(ReuDsc )
&filexml.WriteStartElement('INTEGRANTES')
for each
&filexml.WriteElement('INTEGRANTE', ReuPerNom )
endfor
&filexml.WriteEndElement()
&filexml.WriteStartElement('TAREAS')
for each
&filexml.WriteStartElement('TAREA')
&filexml.WriteElement('RESPONSABLE', ReuTarPerNom)
&filexml.WriteCData(ReuTarDsc )
&filexml.WriteEndElement()
endfor
&filexml.WriteEndElement()
&filexml.WriteEndElement()
&filexml.Close()
El archivo reunion.xml contiene:
<REUNION Fecha="06/03/01">
<FECHA>06/03/01</FECHA>
<INTEGRANTE>Juan Pedro</INTEGRANTE>
<INTEGRANTE>Laura</INTEGRANTE>
<INTEGRANTE>Diego</INTEGRANTE>
<INTEGRANTE>Florinda</INTEGRANTE>
</INTEGRANTES>
<TAREAS>
<TAREA>
<RESPONSABLE>Juan Pedro</RESPONSABLE>
</TAREA>
<TAREA>
<RESPONSABLE>Florinda</RESPONSABLE>
</TAREA>
<TAREA>
<RESPONSABLE>Laura</RESPONSABLE>
</TAREA>
<TAREA>
<RESPONSABLE>Diego</RESPONSABLE>
</TAREA>
</TAREAS>
</REUNION>
Introducción
El objetivo del tipo de datos XMLReader es proveer la posibilidad de leer el contenido de los archivos
XML. El documento XML contiene una introducción a dicho lenguaje.
Alcance
Aplica a los siguientes objetos: Transacciones, Work Panels, Web Panels, Reportes, Procedimientos.
Y para los siguientes generadores: .NET, Java, Visual Basic y Visual FoxPro.
Descripción
Para poder leer el contenido de un archivo XML desde un objeto GeneXus, se debe definir una
variable de un nuevo tipo de datos denominado XmlReader y luego invocar a los métodos y
propiedades necesarios para obtener la información de los nodos que lo componen.
La idea básica del funcionamiento es la siguiente: existe un método Read() que se comporta a
manera de cursor avanzando al siguiente nodo del archivo, luego utilizando ciertas propiedades
como por ejemplo Name y Value se puede obtener los datos del nodo, en este caso el nombre y el
valor del mismo. De esta forma utilizando el método Read() se “navega” a lo largo del documento en
forma secuencial obteniendo los distintos nodos del mismo.
Métodos
MÉTODOS BÁSICOS
Open(<FileName>)
File Name es el nombre de un archivo XML o una URL con un archivo XML. Puede
usarse la propiedad ErrCode para consultar el éxito de la operación.
<FileName> – Character
OpenFromString(<DocXML>)
Read()
Este método se utiliza para ir obteniendo en forma secuencial los distintos nodos del archivo
abierto. Invocando al mismo se avanza al siguiente nodo y retorna un valor entero mayor
que cero si se leyó un nodo y cero en caso contrario.
ReadType(<NodeTypeConstraint> [,NameConstraint])
Al igual que el método Read(), este método avanza al siguiente nodo pero que cumpla con
las restricciones indicadas y retorna un valor entero mayor que cero si se leyó un nodo y
cero en caso contrario.
La restricción <NodeTypeConstraint> especifica cuales son los tipos de nodos que
quiero leer. Se especifica indicando las constantes del tipo de nodo concatenadas
por medio del carácter “+”
<NodeTypeConstraint> – Character
NameConstraint – Character
GetAttributeByIndex(<Index>)
Retorna el valor del atributo en la posición <Index> del nodo actual obtenido por el
método Read o ReadType.
<Index> – Integer
GetAttributeByName(<Name>)
Retorna el valor del atributo de nombre <Name >del nodo actual obtenido por el
método Read o ReadType.
<Name> – Character
ExistsAttribute(<Name>)
Retorna 1 si el atributo de nombre <Name> del nodo actual obtenido por el método Read o
ReadType existe y 0 en caso contrario.
Sólo es válido para nodos de tipo Element.
<Name> – Character
Close()
Cierra el documento.
OTROS MÉTODOS
SetDocEncoding (<Encoding>)
ANSI
US-ASCII
UTF-8
UTF-16
ISO-8859-1
<Enconding> - Character
SetNodeEncoding(<Encoding>)
Permite establecer la codificación de caracteres utilizada para los valores retornados por el
objeto XMLReader al programa GeneXus.
Los valores posibles de <Enconding> son:
ANSI
UTF-8
<Enconding> - Character
Skip()
ReadRawXML()
Indica que se va a utilizar el “schema” de la <URI> para validar el XML del [Namespace]
indicado.
Si no se indica [Namespace], se toma el del atributo targetNamespace del esquema.
Para utilizar este método hay que indicar en la propiedad ValidationType que se
realice validación por esquema o automática.
<URI> – Character
Namespace – Character
Propiedades
PROPIEDADES BÁSICAS
Nodetype
1 - Element
2 - EndTag
4 - Text
8 - Comment
16 - WhiteSpace
32 - Cdata
64 - ProcessingInstruction
128 - DocumentType
ElementType
EndTagType
TextType
CommentType
WhiteSpaceType
CDataType
ProcessingInstructionType
DoctypeType
Estas propiedades contienen valores constantes que pueden utilizarse para comparar el resultado de
la propiedad NodeType o con el método ReadType.
Name
Retorna el nombre del nodo actual obtenido por el método Read o ReadType.
Value
Retorna el valor del nodo actual obtenido por el método Read o ReadType.
Solo es válido para los nodos de tipo Text, Comment, ProcessingInstruction, DocumentType
y Element
IsSimple
Indica si el nodo actual obtenido por el método Read o ReadType responde a una estructura
del tipo <Elemento>Valor</Elemento>
AttributeCount
Retorna la cantidad de atributos que posee el nodo actual obtenido por el método Read o
ReadType.
EOF
ErrCode
Retorna un valor mayor que cero en caso de haber ocurrido un error durante el
procesamiento de un documento XML.
ErrLineNumber; ErrLinePos
Retorna la descripción del error en caso de que ErrCode sea distinto de cero.
OTRAS PROPIEDADES
ReadExternalEntities
Esta propiedad booleana(1/0) indica si deben leerse las entidades externas parseadas que
forman parte del documento XML que se esté procesando (esto incluye el subconjunto
externo del DTD). Si la lectura está habilitada, el objeto XMLReader leerá y procesará en
forma transparente para el usuario toda referencia a archivos o URLs externas que sean
incluidas por el documento. En caso contrario, las referencias a entidades externas son
ignoradas.
RemoveWhiteSpaces
Esta propiedad booleana(1/0) indica si deben eliminarse los espacios en blanco, tabuladores
y finales de línea del inicio y fin del valor de un nodo de tipo TEXT o ELEMENT.
RemoveWhiteNodes
Esta propiedad booleana(1/0) indica si deben pasarse por alto los nodos de tipo WhiteSpace
al procesar un documento.
SimpleElements
Esta propiedad determina si los elementos con una estructura simple como la siguiente:
<elemento>valor</elemento> o <elemento/>
ValidationType(.NET y Java)
Esta propiedad determina como se va a validar el XML leído.
Los valores posibles son:
0 – No se realiza validación
1 – Validación automática
2 – Validación por medio de DTD
3 – Validación por medio de un “Schema”
4 – Validación por medio de XDR (Solo .NET)
StopOnInvalid(Solo .NET)
Esta propiedad booleana(1/0) indica si el parser tiene que parar cuando detecta un error de
validación, pero el xml está bien formado.
Si el valor es 0 el método Read() retornará 1 aunque haya habido un error de validación y la
forma de detectar el error es controlando el valor de la propiedadErrCode.
En esta sección se describen las funcionalidades disponibles para procesar documentos XML que
utilizan namespaces.
MÉTODOS
Los siguientes métodos retornan los distintos componentes del nombre de un atributo indicado por
<Index>.
Sólo son válidos para nodos de tipo Element.
GetAttributeName(<Index>)
GetAttributePrefix(<Index>)
GetAttributeLocalName(<Index>)
GetAttributeURI(<Index>)
<Index> - Integer
PROPIEDADES
Las siguientes propiedades sólo son válidas para nodos de tipo Element y EndTag.
Name
Retorna el nombre completo prefijo:nombrelocal.
Prefix
Retorna el prefijo que representa al namespace del nombre.
LocalName
Retorna el nombre sin el prefijo que representa al namespace.
NameSpaceURI
Retorna el URI usado para identificar al namespace.
Cuando un elemento no está calificado con un namespace, las propiedades Name y LocalName
coinciden.
Entity references
Por defecto, tanto las entidades internas como externas son procesadas automáticamente
reemplazando las referencias por sus valores. El procesamiento de las externas sin embargo puede
ser desactivado usando la propiedad ReadExternalEntities.
MÉTODOS
Los siguientes métodos permiten acceder a la notación y entidad referenciadas por un atributo de tipo
ENTITY.
El atributo puede especificarse por medio de su posición en el texto o por su nombre y no se verifica que sea
de tipo ENTITY. Si ninguna declaración fue hecha en el DTD del documento para el valor atributo se devuelve
una cadena vacía.
Sólo son válidos para nodos de tipo Element.
GetAttEntityValueByName(<Name>)
GetAttEntityNotationByIndex(<Index>)
GetAttEntityNotationByName(<Name>)
<Index> - Integer
<Name> - Character
Ejemplo
<REUNION Fecha="06/03/01">
<FECHA>06/03/01</FECHA>
<INTEGRANTE>Juan Pedro</INTEGRANTE>
<INTEGRANTE>Laura</INTEGRANTE>
<INTEGRANTE>Diego</INTEGRANTE>
<INTEGRANTE>Florinda</INTEGRANTE>
</INTEGRANTES>
<TAREAS>
<TAREA>
<RESPONSABLE>Juan Pedro</RESPONSABLE>
</TAREA>
<TAREA>
<RESPONSABLE>Florinda</RESPONSABLE>
<TAREA>
<RESPONSABLE>Laura</RESPONSABLE>
</TAREA>
<TAREA>
<RESPONSABLE>Diego</RESPONSABLE>
</TAREA>
</TAREAS>
</REUNION>
Este procedimiento GeneXus lee el archivo y obtiene los integrantes de la reunión.
&readfile.open(‘Reunion.xml’ )
&readfile.ReadType(1, 'INTEGRANTES')
&readfile.read()
&Integrante = &readfile.value
&readfile.read()
enddo
&readfile.close()
Este procedimiento GeneXus lee el archivo y obtiene las tareas de un integrante de la reunión.
&readfile.open(‘Reunion.xml’)
If &exito = 0
Exit
Endif
enddo
If &exito <> 0
&readfile.read()
&tareas = &readfile.value
else
&tareas = Nullvalue(&tareas)
Endif
&readfile.close()
Consideraciones generales
Glosario
Las siguientes definiciones fueron extraídas de “Extensible Markup Language (XML) 1.0 (Second
Edition)”; por más información referirse a http://www.w3.org/TR/2000/REC-xml-20001006; y para el
caso de los Namespaces referirse a http://www.w3.org/TR/1999/REC-xml-names-19990114/
Character data: Markup takes the form of start-tags, end-tags, empty-element tags, entity
references, character references, comments, CDATA section delimiters, document type
declarations, processing instructions, XML declarations, text declarations, and any white
space that is at the top level of the document entity (that is, outside the document element
and not inside any other markup).
All text that is not markup constitutes the character data of the document.
Entities: An XML document may consist of one or many storage units. These are called
entities; they all have content and are all (except for the document entity and the external
DTD subset) identified by entity name.
A parsed entity's contents are referred to as its replacement text; this text is considered an
integral part of the document.
An unparsed entity is a resource whose contents may or may not be text, and if text, may be
other than XML. Each unparsed entity has an associated notation, identified by name.
Beyond a requirement that an XML processor make the identifiers for the entity and
notation available to the application, XML places no constraints on the contents of unparsed
entities.
Parsed entities are invoked by name using entity references; unparsed entities by name,
given in the value of ENTITY or ENTITIES attributes.
Entity reference: Refers to the content of a named entity.
CDATA sections may occur anywhere character data may occur; they are used to escape
blocks of text containing characters which would otherwise be recognized as markup. CDATA
sections begin with the string "<![CDATA[" and end with the string "]]>".
Standalone document declaration: Markup declarations can affect the content of the
document, as passed from an XML processor to an application; examples are attribute
defaults and entity declarations. The standalone document declaration, which may appear
as a component of the XML declaration, signals whether or not there are such declarations
which appear external to the document entity or in parameter entities.
Document type declaration: XML provides a mechanism, the document type declaration,
to define constraints on the logical structure and to support the use of predefined storage
units. An XML document is valid if it has an associated document type declaration and if the
document complies with the constraints expressed in it.
The XML document type declaration contains or points to markup declarations that
provide a grammar for a class of documents. This grammar is known as a document type
definition, or DTD. The document type declaration can point to an external subset (a special
kind of external entity) containing markup declarations, or can contain the markup
declarations directly in an internal subset, or can do both. The DTD for a document consists
of both subsets taken together.
XML namespaces provide a simple method for qualifying element and attribute names used
in Extensible Markup Language documents by associating them with namespaces identified
by URI references.
Tipo de Datos WebWrapper
Introducción
WebWrapper es un tipo de datos de GeneXus que permite encapsular la ejecución de los objetos
Web (el código HTML generado). En particular permite enviar el contenido de un Web Panel por
mail.
Aplica a los siguientes objetos: Transacciones, Web Panels y Procedimientos, tanto para el generador
Java como .NET.
Descripción
Para poder enviar el contenido de un Web Panel vía mail desde un objeto GeneXus es necesario
definir una variable de tipo WebWrapper, para luego aplicar los métodos y propiedades necesarios.
La idea es capturar el contenido de un Web Panel en su código HTML, y enviar éste vía mail, por lo
tanto hay que tener en cuenta que el cliente de correo que reciba el mail debe tener la capacidad de
interpretar lenguaje HTML, en caso contrario verá el código del Web Panel.
PROPIEDADES
BaseURL: Es la dirección Base del Web Panel.
La dirección base determina el servidor y directorio virtual al que apuntarán los links y a donde se irá
a buscar el Web Panel en caso de que se presione algún botón. La dirección base es agregada al
código HTML que devuelve el método GetResponse.
MÉTODOS
GetResponse: Retorna el código HTML que devolvería el objeto Web especificado en la propiedad
Object con los parámetros allí indicados.
Ejemplo
El siguiente ejemplo es un procedimiento que ilustra como enviar por mail, mediante Outlook, el
Web Panel Hnotify para cada registro de la tabla USERS. Dicha tabla tiene clave primaria UserId, el
cual se pasará como parámetros al Web Panel Hnotify. También tiene entre sus atributos
secundarios a UserName, con el nombre del usuario, y UserMail, con la dirección de correo el
electrónico del usuario.
Variables Definidas:
&Wrap.BaseURL = “http://myserver/mysystem/”
&MailMsg.To.New(UserName, UserMail)
&MailMsg.HTMLText = &Wrap.GetResponse()
&Oulook.Send(&MailMsg)
EndFor
Consideraciones Generales
Los objetos Web Panel de GeneXus, no son estáticos, por este motivo al enviarlos vía mail, en
realidad se está enviando una imagen estática. Por lo tanto cualquier evento que se produzca en el
Web Panel que realice un post al servidor (por ejemplo hacer clic en un botón, disparar un
procedimiento, etc.) producirá que se abra el Web Panel en el browser, en la dirección especificada
en la propiedad BaseURL.
Si se desea hacer un WebWrapper de un Web Panel que incluya imágenes, se puede hacer de dos
maneras:
Poner en el Web Panel las imágenes en forma absoluta, el inconveniente de esto es que el
usuario debe estar conectado en el momento de leer el mail.
Poner en el Web Panel las imágenes relativas y mandarlas como archivos adjuntos en el mail. En
este caso la ruta de la imagen no debe incluir directorios (por ej.: /imágenes/logo.jpg) si no
hacer referencia directamente a la misma (por ej.: logo.jpg).
Si se utiliza un objeto WebWrapper para mandar un Web Panel mediante mail, y dicho Web Panel
tiene un botón o evento clic, el comportamiento al apretar dicho botón (o control con evento clic)
en Outlook XP difiere del de Outlook 2000 y Outlook Express.
Por ejemplo, si se tiene un evento asociado a un botón que graba algo en la base de datos y asigna
cierto valor a una variable que está en el form. En Outlook 2000 y Outlook Express, al apretar dicho
botón en el mensaje se ejecutará el evento, por lo que se hará el cambio a la base de datos, y se
abrirá un browser donde se verá en el form la variable con el valor que se le asignó en el evento. En
Outlook XP se ejecutará el evento, haciendo el cambio en la base de datos, pero el form de
respuesta nunca se mostrará. Luego se abrirá un browser donde se desplegará el form sin modificar
la variable.
Otro ejemplo: el evento asociado al botón modifica la base de datos y hace un call a otro Web Panel.
En Outlook 2000 y Outlook XP, al apretar el botón se hace la modificación a la base de datos y se
abre un browser donde se muestra el Web Panel llamado. En Outlook XP se hace la modificación a la
base de datos pero no se muestra nada, ni siquiera se abre el browser.
Hay dos formas en las cuales podemos cambiar nuestra programación para asegurarnos de que el
comportamiento sea el mismo en los 3 clientes de mail:
Event Refresh
else
endif
End Event
INTRODUCCIÓN
Los objetos GeneXus pueden comunicarse entre ellos o con otros programas externos.
Un objeto GeneXus puede llamar a, o ser llamado por, otro objeto pudiendo intercambiar
información a través de parámetros.
En el siguiente cuadro se muestran las invocaciones válidas entre los distintos objetos Web.
C:\Documents and Settings\jiriarte\Desk top\cursointernet90\C ursoInternet90\C urso_no_presencial_'Desarrollo_de_aplicaciones_para_Internet_con_GeneXus'\14_ComunicacionentreObjetos\01_Introduccion_files\image001.g if
Nota:
Es importante tener en cuenta que no todas las combinaciones siempre son válidas. Verificar las combinaciones válidas
en el documento Invocación desde un objeto a otro.
Invocación desde un objeto a otro
Para invocar desde un objeto Web GeneXus a otro objeto GeneXus o programa externo, contamos
con el comando/regla CALL, el comando/función LINK y la función UDP:
CALL – Es una regla o comando (ya que dependiendo del objeto GeneXus en el que se vaya
a usar, se podrá escribir en la sección de reglas, eventos, u otra parte del objeto) para llamar
a un objeto GeneXus o a un programa externo, siendo posible pasarle parámetros.
UDP – (User Defined Procedure) Es una función que permite llamar a un objeto GeneXus o
programa externo al cual se le podrán pasar parámetros, y retornará al menos un valor
como resultado de su ejecución.
LINK - El comando o función link es equivalente al comando CALL para llamar a páginas
estáticas o redireccionar a una URL. Este comando puede ser utilizado dentro de cualquier
evento de un objeto Web con excepción del evento Load. El resultado de la utilización de
este comando es el redireccionamiento en forma automática a la URL especificada dentro
del mismo.
Tanto al utilizar CALL como UDP para invocar desde un objeto GeneXus, a otro objeto GeneXus o programa
externo, cuando se ejecute la invocación, se pasará el control al programa llamado, y al finalizar éste su
ejecución, devolverá el control al llamador en el caso en que el objeto llamado no tenga form, retornándole
parámetros si los hay. Si el objeto al cual se invoca tiene salida en pantalla, este último pasa a tener el
control total, por lo tanto si tenía código por ejecutar el llamador luego de esta invocación, no se ejecutará.
Es importante tener en cuenta que los objetos Web ejecutan en el servidor y por consiguiente no pueden
realizar llamadas a programas externos que tengan salida en pantalla, ya que la ejecución de dicha llamada
cancelaría por time-out. En resumen, desde un objeto Web, se puede llamar a otro objeto Web o a un
Procedimiento o Reporte que no tengan salida en pantalla.
Utilizando CALL, se puede invocar a un objeto GeneXus o programa externo, tanto sin pasarle
parámetros, como pasándole.
Y utilizando UDP, es posible invocar a un objeto GeneXus o programa externo, con la particularidad de que el
programa llamado retornará necesariamente al menos un valor al programa que lo invocó.
El comando LINK permite llamar a páginas estáticas o redireccionar a una URL y en el caso que corresponda
permite pasarle parámetros.
Sintaxis
Link( usr-pgm | ’url’ [{parm1, parmn}…] )
Donde:
Por ejemplo:
Event ENTER
Link(‘http://www.ARTech.com.uy’)
Endevent
Consideraciones
Si el Procedimiento ha sido invocado desde un Web Panel o una Transacción Web o vía HTTP (por
ej.: con la propiedad “Call Protocol” en “HTTP”), podrá también invocar con un CALL o LINK a una
URL HTTP (por ej.: llamar a un Web Panel o a una Transacción Web).
Se debe considerar que dicha invocación no será ejecutada sincrónicamente. Será ejecutada como
un redireccionamiento al objeto invocado al final de la ejecución Web.
Un procedimiento llamado desde la línea de comando, por ejemplo, no puede invocar a un Web
Panel. Pero sí se puede utilizar la función opendocument() para abrir una URL en el browser.
Ejemplo
En este ejemplo se muestra como se realiza la ejecución de distintos objetos cuando desde un
procedimiento se invocan Web Panels o Transacciones Web.
Procedimiento prc01:
call(hwbp01)
for each
A=B
endfor
Procedimiento pproc02:
call(hwbp01)
..
call(hwbp02)
Event 'one'
pprc01.call()
EndEvent
Resultado: El Web Panel hwbp01 será ejecutado antes del "endevent", después del for each.
Event 'two'
pprc02.call()
EndEvent
Event 'three'
pprc02.call()
hwbp03.call()
EndEvent
Internamente, en cada sentencia call se setea una variable interna con el nombre del objeto al cuál,
al final de la ejecución en el servidor, la redirección irá.
INTRODUCCIÓN
En este capítulo veremos los requerimientos necesarios para los generadores .NET y Java. Tanto para
el desarrollo de aplicaciones Web como para la puesta en producción.
También profundizaremos en las propiedades necesarias para una aplicación Web, ya sean
propiedades propias de cada generador como también propiedades independientes del generador.
Requerimientos .NET
Además de los requerimientos básicos de GeneXus 9.0 (espacio en disco, cantidad de memoria, etc.)
para cada equipo de desarrollo, se debe contar con el software mencionado a continuación.
Plataforma .NET
SQL Server
ADO.NET utiliza el Data Provider de Microsoft para SQL Server (el cual se instala con el Framework).
No se requiere el cliente SQL Server.
Oracle
Se debe tener el Cliente de Oracle versión 8.1.7.5 o superior, de esta forma se instala el Data
Provider correspondiente. El valor “Server Name” de las DBMS option hace referencia al Service
Name definido en la instancia del Oracle.
Se necesita la V5R3 del iSeries Client Access con un service level igual o superior a SI20055. La menor
versión testeada del server es la V5 R1.
MySQL
MySQL soporta diferentes motores, GeneXus utiliza el InnoDB
(http://dev.mysql.com/doc/mysql/en/InnoDB.html).
La menor versión soportada del server es 3.23.58. El driver cliente para .NET se puede obtener
desde:
http://sourceforge.net/projects/mysqldrivercs.
Informix
No tiene acceso ADO.NET, se debe acceder con ODBC. La versión del DBMS puede ser 7.0 o Informix
Foundation 2000. En el cliente debe estar instalado el cliente con la versión correspondiente. Se
recomiendan los drivers de Intersolv o Informix.
PostgreSQL
Servidor Web
Se deberá contar con el servidor Web Internet Information Server 5.0 o superior.
INTRODUCCIÓN
Existe una API especificada por Sun Microsystems que se llama “Java Servlet API”. Esta API define la
forma de ejecutar lo equivalente a los objetos Web de GeneXus, por lo tanto, el generador Java, por
cada objeto Web de GeneXus, genera lo que se llama un Servlet.
Los Servlets proveen una gran cantidad de ventajas que el generador Java aprovecha, como por
ejemplo, la utilización de un pool de conexiones a la base de datos y la multiplataforma.
A su vez, el generador Java provee una funcionalidad adicional que consiste en que los objetos Web
pueden enviar la página HTML comprimida, para que sea descomprimida en tiempo real por el
browser. La compresión se realiza sólo si el browser indica que es capaz de descomprimirlo. Esta
opción puede deshabilitarse con la propiedad “Auto Compress HTTP Traffic”, para contemplar el
hecho de que algunos browsers no reporten correctamente su capacidad para descomprimir las
páginas, y no las puedan desplegar correctamente. En las pruebas que hemos realizado, esta
funcionalidad se ha comportado de forma correcta con todos los browsers.
Requerimientos Java
Además de los requerimientos básicos de GeneXus 9.0 (espacio en disco, cantidad de memoria, etc.)
para cada equipo de desarrollo, es necesario contar con cierto software de desarrollo Java para la
compilación y ejecución de las aplicaciones generadas y el software necesario para el acceso a la
base de datos (drivers JDBC).
JDK/JRE (Java Development Kits Compiladores y Máquinas Virtuales)
Para la compilación y ejecución de los programas es necesario contar con alguno de los
Development Kits del mercado. Los principales son los de Sun, Microsoft e IBM.
JDK DE SUN
Para instalar el JDK de Sun, se debe bajar del Web site de Sun la última versión del JDK para Win32,
ejecutar el EXE descargado, y seguir las instrucciones.
SDK DE MICROSOFT
El SDK de Microsoft no está disponible en internet ni se comercializa más. En ese caso se podrá usar
el compilador del JDK de Sun (javac.exe), que es gratuito.
C:\WINDOWS\system32>jview
Opciones:
/a ejecuta AppletViewer
Nombre de clase:
Argumentos:
Si no está disponible o está desactualizado (esto es, con una versión anterior al 5.00.3805), entonces
se puede obtener con Windows Update.
La otra alternativa es usar el intérprete de Sun, java.exe, que forma parte del SDK de Sun.
Para la instalación simplemente se debe descomprimir el zip hacia una carpeta, y mover ésta hacia
donde quiera hacerse la instalación. El directorio de instalación contendrá dos subdirectorios: bin,
que tiene el compilador (jikes.exe) y doc, que contiene instrucciones de uso y licencia.
Para poder utilizar este compilador es necesario que esté instalada alguna versión del JDK de Sun,
dado que requiere de sus bibliotecas de clases.
En cuanto a las versiones de este software se recomienda utilizar las últimas liberadas de cada uno
de ellos, pero no versiones beta.
Driver JDBC
Los drivers JDBC (equivalentes a ODBC) permiten efectuar conexiones con bases de datos.
Dependiendo del DBMS y del tipo de acceso a la base de datos que se utilice, puede ser necesario
obtener uno u otro tipo de driver JDBC. Generalmente se utilizan los drivers de tipo 4, que se
presentan a continuación junto con otros tipos de driver.
Los números de tipos de driver corresponden a una numeración que fijó SUN.
DRIVERS JDBC
CLIENTE DBMS
La aplicación GeneXus-Java se comunica con los DRIVERS JDBC. A los DRIVERS JDBC se les configura
un parámetro para indicar que la conexión es a cierto Data Source. Y finalmente con la información
definida en el Data Source, se establece la conexión del cliente con el Servidor Manejador de Base de
Datos (DBMS).
Las implementaciones actuales de estos drivers no son muy fiables, por lo que no se recomienda su
utilización en ambientes de producción. Sin embargo, existe un caso por el cual utilizar el driver tipo
1: algunas versiones de AS/400 no soportan los dirvers JDBC, de modo que la única forma de
implementar una aplicación Java en 2 capas, en esos casos, sería mediante este tipo de driver
llamado también Bridge JDBC-ODBC.
Tipo 2: Java -> Protocolo DBMS
Con esta implementación, en el cliente se tienen los DRIVERS JDBC que se comunican directamente
(en forma nativa) con el CLIENTE Oracle, Sybase, Informix, DB2, o cualquier otro DBMS.
De esta forma, entonces, al igual que el driver de tipo 1, este también requiere que se instale en
cada máquina cliente, los DRIVERS JDBC y CLIENTE DBMS.
En general los drivers tipo 2, también llamados Native-API Partly-Java, se comunican muy rápido
con la base de datos, siendo en teoría, los más performantes. Salvo por ésto, este tipo de driver no
presenta demasiadas ventajas con respecto a las otras alternativas.
Esta clase de driver traduce llamadas JDBC en un protocolo de red independiente del DBMS y luego,
a un protocolo de DBMS.
Un Servidor JDBC, realiza la tarea de middleware, siendo capaz de conectar un cliente Java a
diferentes bases de datos.
La implementación del Servidor JDBC se realiza mediante la instalación de un software que sabe
“escuchar” los requerimientos del CLIENTE JDBC y traducirlos a llamadas nativas para los DBMSs.
Una ventaja que posee el driver tipo 3, también conocido como net-protocol all-Java, es que no requiere
instalación en los clientes, según el DBMS. Como contrapartida, este driver requiere la instalación del
Servidor JDBC.
Merant DataDirect SequeLink Java Edition es un driver de tipo 3 que se ha probado para SQL Server y
Oracle.
Nota: Para ejecutar Applets, en 2 capas, si se utiliza el driver tipo 3, el Servidor JDBC deberá
encontrarse en el mismo host que el Servidor Web, por ser el Servidor JDBC el que resolvería la
conexión. En este caso, sería posible efectuar conexión con un DBMS que no se encuentre en el
mismo host que el Servidor Web.
Tipo 4: Java -> DBMS
El driver tipo 4 convierte llamadas JDBC directamente en el protocolo de red usado por el DBMS.
Esto permite llamadas directas desde la máquina del cliente al servidor del DBMS y es una solución
práctica para el acceso a Intranets.
Requieren más código, por lo que si se usa en 2 capas hay que bajar más código al cliente, y la
performance suele ser algo menor que la de los otros drivers (esto puede depender mucho del
driver, de la cantidad de conexiones simultaneas, etc). De todas formas, este es el tipo de driver más
común, y el que se usa más en general.
Dado que muchos de estos protocolos son propietarios, los proveedores de bases de datos son la
principal fuente de este tipo de driver.
I-net Software
WebLogic jDriver
AsToolBox
Merant
Nota: Para ejecutar Applets, en 2 capas, si se utiliza el driver tipo 4, el DBMS deberá encontrarse en
el mismo host que el Servidor Web pues no se permite a un Applet establecer una conexión con otra
máquina que no sea el servidor de donde provino.
Browser
Para utilizar el generador Java, no es necesario tener ningún un browser instalado, sin embargo, se
recomienda tener tanto Internet Explorer como Netscape para probar el correcto funcionamiento de las
aplicaciones.
Dependiendo de la versión del Java Development Kit que se utilice, el browser puede requerir el Java Plug-In,
por lo que sería necesario disponer de este software también.
Visualización de Reportes
Para poder visualizar reportes PDF desde el browser, debe tenerse instalado Adobe Acrobat Reader.
Un Servidor Web
Un Motor de Servlets
El Servidor Web y Motor de Servlets, son dos servicios que se requieren (en un mismo servidor físico,
o no) para poder ejecutar Servlets.
En teoría, las aplicaciones GeneXus pueden ejecutarse con cualquier Motor de Servlets que sea
compatible con la especificación de Servlets 2.1 o posterior.
Algunos de los motores que se han utilizado exitosamente son:
JRun en Windows
Por su parte, el JavaServer Web Development Kit, se instala automáticamente con la instalación del
Motor de Servlets, y permite que el desarrollador pueda compilar los Servlets (objetos Web de
GeneXus).
A continuación explicaremos los pasos en orden, que se deben seguir para configurar y utilizar estos
requerimientos. Explicaremos en forma conceptual y genérica cada punto, y tomaremos a modo de
ejemplo, la opción de utilizar el Motor de Servlets RESIN para Windows, en forma local, con el fin de
mostrar un ejemplo práctico concreto.
Para ejecutar una aplicación Web Java, se debe configurar un motor de servlets; para ello se deben
realizar algunos pasos, que si bien varían un poco según el motor de servlets que se vaya a utilizar,
básicamente los pasos a seguir, son similares.
Cada motor de servlets crea y maneja una “Webapp”. El nombre Webapp resulta de la abreviación
de "Web application" y consiste en un directorio base, que contiene a su vez una estructura de
subdirectorios determinada, en la cual se deben distribuir los archivos que sean necesarios para la
ejecución de una aplicación Web.
Los tipos de archivos involucrados en la ejecución de una aplicación Web, pueden ser los servlets
(archivos .class), contenido estático y librerías adicionales (archivos .JAR).
Pasos a seguir
Una vez visto este concepto, pasemos a detallar entonces los pasos a seguir para configurar un
motor de servlets:
2) Definir una Webapp o bien identificar cuál es la Webapp por defecto para utilizarla.
5) Tests:
A modo de ejemplo, si se utiliza RESIN en Windows, en forma local, se deben seguir los siguientes
pasos:
5) Tests:
a. Para verificar que el RESIN haya levantado bien, se debe ejecutar el servlet que viene
de ejemplo accediendo de la siguiente forma:
http://localhost:8080/examples/basic/servlet/HelloServlet
b. Para verificar que se estén tomando las clases standard de GeneXus y cuál versión,
se debe ejecutar:
http://localhost:8080/servlet/com.genexus.Webpanels.gxver
A continuación se detalla el significado de cada una de las opciones que figuran en el diálogo de
configuración de la opción del menú Build / Run (F5).
Compiler Path: Determina el path del compilador (csc.exe), este se encuentra bajo el directorio de
instalación del Framework en:
C:\WINNT\Microsoft.NET\Framework\v1.1.4322
Virtual Directory: Determina la URL base de ejecución, esta contiene el directorio virtual a ser
creado (si no existe) por GeneXus en el Internet Information Service (IIS) local. El momento de la
creación es luego de la compilación y reorganización.
Para la ejecución de aplicaciones Web con Java, se debe configurar las siguientes propiedades:
Platform
Se debe seleccionar el ambiente de compilación y ejecución, es decir cuál Java Development Kit se
utilizará. Las posibilidades son:
Microsoft SDK
Sun JDK
Classpath
En classpath se referencian las clases necesarias para compilar los servlets (clases correspondientes
al JavaServer Web Development Kit). El archivo puede llamarse servlet.jar o jsdk.jar o jsdk22.jar
(dependiendo del Motor de Servlets que se utilice) y por lo general se encuentra en el subdirectorio
Lib del Motor de Servlets. Estas clases se deben referenciar en el classpath, además, del resto de los
archivos de clase que se requieran referenciar en dicha variable de entorno.
Compiler Path
El compilador del Development Kit de Sun se llama javac.exe, mientras que el compilador del
Development Kit de Microsoft se llama jvc.exe. Ambos compiladores se encuentran en el
subdirectorio BIN del JDK / SDK.
Make Path
Aquí se debe especificar la ubicación del programa de make que se desea utilizar. La función del
programa de make es procesar los archivos .mak, que indican las precedencias entre archivos para
compilar.
Microsoft provee un programa de make (sin costo) llamado nmake.exe, que es el que se recomienda
usar.
Sun no provee un programa de make, por lo que para compilar con el JDK de Sun se puede utilizar el
programa de make de otros proveedores, como el de Microsoft.
Si se opta por compilar con Jikes de IBM se sugiere utilizar el programa de make que provee
Microsoft.
Interpreter path
El intérprete de Sun se llama java.exe mientras que el de Microsoft se llama jview.exe. Ambos
intérpretes se encuentran en el subdirectorio BIN del JDK / SDK. El intérprete de Microsoft es uno los
programas básicos provistos junto con el sistema operativo. Es decir, normalmente Windows incluye
jview, en el directorio C:\WINDOWS\system32, independientemente de si el JDK está instalado o no.
JIKES de IBM, por su parte, incluye solamente compilador. Si la ejecución es en Windows, se suele
elegir el intérprete de Microsoft, de lo contrario el de Sun.
Normalmente se recomienda utilizar plataforma y compilador de Sun, pero con el intérprete jview y
el programa nmake, ambos de Microsoft.
Este campo es para especificar la URL que el browser utilizará como base para la ejecución de los
objetos Web.
Propiedades avanzadas
Si no se marca dicha opción, se puede ingresar el path del browser a utilizar. Adicionalmente, los
JDK/SDK’s incluyen un programa llamado appletviewer que permite ejecutar Applets.
COMPILES OPTIONS
Permite especificar parámetros que se desee pasar al compilador elegido cada vez que GeneXus lo
llame. El compilador especificado en “Compiler Path” debe poder reconocer estos parámetros. Por
defecto, está dado el parámetro “–O”, que permite generar código optimizado para la ejecución, sin
información para el programador.
Si se dispone del SDK de Sun y se desea ver las opciones posibles para el compilador, puede
invocarse desde línea de comandos como:
javac -help
-O 1.1 -target
INTERPRETER OPTIONS
Análogo al anterior, permite especificar parámetros opcionales que quieran pasarse al intérprete.
Con SDK de Sun, las opciones disponibles pueden verse con:
java –help
MAKE OPTIONS
Permite especificar opciones para el comando make especificado en “Make Path”. Por ejemplo, si se
utiliza el nmake de Windows, para ver las opciones disponibles, ejecutar desde una consola de DOS:
nmake -help
En los modelos GeneXus, existen propiedades que aplican exclusivamente a los objetos Web.
Algunas a nivel del modelo de diseño por lo que aplican a toda la base de conocimiento y otras se
encuentran a nivel de los generadores (por lo que aplican al modelo de prototipo o producción que
lo utilice).
Propiedades generales
Estas propiedades se definen a nivel del modelo de Diseño. Se setean mediante la opción File / Edit
Model / Properties teniendo abierto el modelo de diseño. Las relacionadas con objetos Web son:
Base Image Path
A nivel de cada modelo, existen algunas propiedades (en la sección Web Information) que aplican
exclusivamente a los objetos Web.
FOCUS CONTROL
Esta propiedad permite determinar si los objetos Web, al mostrar su página, intentan posicionar el
foco en el primer control de entrada (no read-only) o dejan librado al browser la posición del foco.
Browser dependent
Existe también la propiedad a nivel de objeto con los mismos valores que la propiedad del modelo y
también el valor “Use model's property value”.
PROTOCOL SPECIFICATION
Esta propiedad permite especificar el protocolo a utilizar en la URL generada para invocar a los
objetos Web.
Unsecure (HTTP)
Secure (HTTPS)
Do not specify
El valor por defecto es “Unsecure (HTTP)”, que fuerza a generar HTTP como protocolo en la llamada
al Web Panel e indica que el protocolo a utilizar es el Hypertext Transfer Protocol.
El valor “Secure HTTPS”: fuerza a generar HTTPS como protocolo e indica que el protocolo a utilizar
es el Secure Hypertext Transfer Protocol. Para utilizar este protocolo es necesario disponer de un
servidor seguro.
El valor “Do not specify” indica que no se especificará un protocolo particular, sino que se utiliza el
mismo protocolo empleado para acceder al Web Panel actual.
En el caso de tener aplicaciones con un esquema mixto: algunas páginas seguras y otras no, la
propiedad del modelo deberá configurarse con el valor “Do not specify” y para cambiar el protocolo
deberá hacerse un link al objeto indicando expresamente el protocolo a utilizar.
BEFORE CONNECT
La propiedad “Before Connect” ha sido implementada para cambiar las propiedades de la conexión
en forma dinámica en tiempo de ejecución.
Para utilizar esta característica, se requiere un Procedimiento GeneXus. Este Procedimiento debería
establecer las propiedades de conexión en tiempo de ejecución; será ejecutado inmediatamente
antes que el pedido de cualquier conexión sea ejecutado por la aplicación para interactuar con la
base de datos.
AFTER CONNECT
Esta propiedad permite llamar a un procedimiento GeneXus, inmediatamente después de ser
asignada la conexión en una aplicación. Esta implementación permite apoyarse en los mecanismos
de auditoría.
EXPOSED NAMESPACE
Por medio de esta propiedad se puede indicar el valor del namespace del SOAPAction del Web
Service.
Propiedades de .NET
Estas propiedades se definen a nivel del modelo .NET y se setean mediante la opción File / Edit
Model / Properties teniendo abierto dicho modelo.
Determina el namespace de la aplicación. Los programas generados por GeneXus y compilados con
.NET se encuentran disponibles bajo el namespace indicado por esta propiedad. El default es
GeneXus.Programs. Sirve para los usuarios avanzados que quieren hacer algún tipo de deployment
en el GAC (Global Assembly Cache).
Indica si se generaran los archivos necesarios para compilar el developer menú. El valor en “No” es
útil para evitar el armado del makefile del developer menú, este es muy costoso ya que debe
generar todos los response file (*.rsp) cada vez que se compila un objeto.
Valores:
Para generar el “Key” que identifica al objeto, el generador al momento de compilar busca un
key.snk en el directorio dataxxx, si no hay: genera uno. (se requiere el SDK en el ambiente de
desarrollo para ejecutar el sn.exe y generar el archivo con la Key).
Además se debe configurar en la variable de ambiente “path” el camino a sn.exe para que la
encuentre el compilador ("C:\PROGRAM FILES\MICROSOFT.NET\SDK\V1.1\bin"), de lo contrario da
el error "Before compile error: The system cannot find the file specified"
Los programas estándar provistos por el generador tienen strong names independiente del valor de
la propiedad.
Compiler Flag
La información de esta propiedad se incluirá en el .rsp que se usa para compilar los assemblies. Es
útil por ejemplo, para generar información de debug (incluyendo el string “/debug”) o para incluir
una dll dentro del namespace (/r:xxx.dll ).
Config HttpHandlers Section
La información de esta propiedad determina cómo se mapean los assemblies en ejecución.
Valores:
HttpHandler for each object: Una entrada en el web.config por cada assembly. Aquí se
mapea el request del aspx con el assembly GeneXus.Programs.object (bin\object.dll).
HttpHandlerFactory: Hay una sola entrada para todos los objetos en el web.config, en donde
se indica un objeto al que pedirle el mapeo.
ASHX: No hay mapeos en el web.config, se genera un archivo ashx por cada objeto que
realiza el mapeo con el assembly GeneXus.Programs.object
El valor HttpHandler for each object es más rápido en ejecución pero más lento en la carga inicial.
Además permite tener objetos (*.aspx) no generados con GeneXus, con HttpHandlerFactory esto
no es así.
HttpHandlerFactory es más rápido para prototipar pero más lento en cada llamada porque el
mapeo se resuelve en cada requerimiento. Esta opción puede enviar mensajes de error poco
descriptivos, lo que dificulta la prototipación.
El valor ASHX, es similar a Handler Factory, crea un archivo físico con el nombre del objeto y
extensión ashx, el cual es invocado en ejecución.
Access Method
Determina qué tipo de acceso se va a utilizar para acceder a la base de datos. El método de acceso
especificado será utilizado para acceder a cada uno de los data stores.
Valores:
Valor por defecto: Depende del DBMS asociado al data store Default.
Valores:
Caching Section
Las siguientes tres propiedades aplican cuando la propiedad “Enabled Caching” está en “Yes”.
La diferencia entre la propiedad “Time to Time” y la propiedad “Hardly Ever”, es permitir definir
distintos puntos de persistencia en las tablas del modelo.
PROPIEDAD CHANGE FREQUENCY
Si bien el “cache” se realiza a nivel de sentencia, es a nivel de tabla que se configura, permitiendo
seleccionar el tiempo en que los datos van a persistir en memoria antes de ir a buscarlos
nuevamente a la base de datos. Para poder configurar este tiempo se utiliza esta propiedad, que se
configura a nivel de tablas, en modo de diseño.
Valores:
Log Level
Esta propiedad permite configurar el nivel de trace de acceso a la base de datos con conexión
ADO.NET.
Valores:
0. Off
1. Fatal
2. Error
3. Warn
4. Info
5. Debug
6. All
Esta propiedad escribe el tag <log4net threshold=...> del archivo web.config y client.exe.config (para
modelos Web y Gui respectivamente). En el caso de modelos web también se escribe el tag <trace
enabled=true />.
Propiedad Maximum Cached cursors per connection
Uno de los costos más importantes en las operaciones ODBC/ ADO.NET es el de preparar las
sentencias SQL. La preparación incluye la compilación y validación de la sintaxis de dicha sentencia
por parte del servidor.
Los programas generados en .NET realizan un manejo inteligente de los cursores abiertos, de modo
que no haya que volver a preparar cursores que ya fueron preparados. Para eso se mantiene un pool
de cursores preparados, cuyo tamaño por defecto es de 100 cursores. Si se desea cambiar este
número, se puede cambiar el valor de esta propiedad.
Servlet Directory
Generation Mode
Para ejecutar los Servlets, una vez compilados, deben estar en un directorio específico de la
estructura obtenida al instalar el Motor de Servlets. La misma varía en cada caso, dependiendo del
Motor de Servlets que se utilice.
Propósito
Es necesario especificar este valor antes de generar, ya que se utiliza para la generación del
archivo de make.
El path debe ser relativo al cliente, es decir un path visto desde el PC en el que se está
trabajando con GeneXus.
Se copiarán además de los archivos .class, los archivos .cfg, los cuales contienen la
información de las propiedades ingresadas; por lo tanto, si se modifica algún valor de las
propiedades del modelo, es necesario volver a generar y compilar algún objeto Web.
Además, para que se tome en cuenta este cambio al ejecutar, es necesario reiniciar el
servidor de servlets.
Ejemplos de valores
H:\servlets - Si el motor de servlets está instalado en una máquina mapeada con el “drive”
H y servlets es el nombre del directorio donde deben residir los servlets.
Propósito
Indica el directorio donde los servlets buscarán el contenido estático (imágenes, javascritps y
styles.css) utilizado en los objetos Web correspondientes. Los servlets siempre ejecutan en el
servidor, por lo que este directorio debe especificarse relativo al directorio correspondiente a la
“base URL” de la webapp.
Nota: Cambiar el valor de esta propiedad no implica regenerar la aplicación, sino solo un objeto Web. Si está
en producción, sólo basta con modificar el archivo client.cfg.
Ejemplo de valores
Si se crea un directorio llamado “images” bajo el directorio raíz del webapp donde se instalaron los
servlets, y a él se copian todas las imágenes necesarias, y en diseño sólo se especifica el nombre de
la imagen, entonces en esta propiedad habría que poner /images.
Propiedad Static Content directory seen from client
Propósito
Permite especificar el directorio donde se transferirán los JavaScripts (archivos *.js) que se generan
para los menubars de objetos Web y Web Panels generados como estáticos. En tiempo de
compilación, el generador los copiará al directorio especificado.
Notas:
En este mismo directorio también habrán archivos de imágenes que se utilicen en los
objetos Web. Los mismos se deben copiar manualmente a este directorio, y en los
programas generados se referenciarán utilizando el valor de la propiedad “Static Content
Base URL” concatenada con el nombre de cada imágen.
El path especificado debe ser relativo al cliente, es decir un path visto desde el PC en el que
se está trabajando con GeneXus.
Ejemplos de valores
X:\images - Si el servidor Web está instalado en una máquina, mapeada con el “drive” X y
es el directorio “images” el utilizado para dejar el contenido estático.
Propósito
Los objetos Web, en Java, pueden enviar la página HTML comprimida, de modo que sea
descomprimida en tiempo real por el browser. La compresión se realiza solamente si el browser
indica que es capaz de descomprimirlo.
Valores
Generation Mode
Esta propiedad permite especificar si los objetos Web del modelo se generarán como objetos
dinámicos (acceden a la base de datos) o como páginas HTML inteligentes (Smart Static Panels).
También existe la posibilidad de generar Smart Static Panels a pedido mediante el valor “Create
Static panels on request” de esta propiedad. Si se elige este valor, cuando se ejecuta un Web Panel,
chequea si existe un .html que corresponda a sí mismo, con los parámetros que se le pasaron. Si
existe, se redirecciona la llamada a dicho html. Si no existe, se crea el .html y luego se redirecciona.
Existe también la propiedad a nivel de objeto con los mismos valores que la propiedad del modelo y
también el valor “Use model's property value”.
Requerimientos
Servidor Web
Instalación en el servidor
El directorio bin del modelo (donde se encuentran las dlls de cada objeto)
Los java script ( *.js)
El archivo Web.config
Instalación en el Cliente
Cliente Web, solamente alcanza con un browser. Para el caso de Internet Explorer la mínima versión
soportada es I.E. 6.0. Para poder visualizar los Resportes PDF debe tener instalado el Adobe Acrobat
Reader.
Introducción
Los servlets pueden ser ejecutados por motores de servlets (Tomcat, Resin, Jrun, etc.), o por
servidores J2EE (WebSphere, BEA Weblogic, etc.).
Configurar en forma adecuada los distintos motores de servlets o servidores J2EE, para ejecutar las
aplicaciones Web Java, tiene cierta complejidad; se necesita conocer en cual directorio deben ir los
servlets, en cual directorio deben ir los archivos adicionales (driver JDBC, classes adicionales, etc.) y
dónde colocar el contenido estático. Además, una vez que se hace funcionar todo en un ambiente
de prototipo hay que llevarlo a producción, es decir, configurar todo esto en el cliente. Entonces, el
generador Java provee el War Deployment, que es un “output processor” del Deployment Wizard,
que permite empaquetar en un sólo archivo, todo lo necesario, para la instalación y ejecución de
una aplicación Web Java, en los distintos motores de servlets, o servidores J2EE, de forma sencilla.
El War Deployment genera archivos con extensión .WAR (Web Archive Resource), los cuales son
básicamente archivos .JAR a los cuales se les cambia la extensión a .WAR. Estos archivos
empaquetan servlets, contenido estático, librerías adicionales y un archivo con formato XML, al cual
se le llama descriptor, que contiene cierta información de la aplicación Web como por ejemplo el
nombre de la aplicación, nombre de los servlets, mapeos, etc.).
Configuración
Para distribuir una aplicación Web, se debe ejecutar el Deployment Wizard, a través del Win
Developer Menu. Este, permitirá seleccionar los objetos Web main para los que se desee armar el
deployment, y luego automáticamente se abrirá el WAR Deployment para el armado del .WAR.
Dentro del .WAR se incluirá todo lo necesario para ejecutar el objeto Web main y todos los llamados
por él, más todos los archivos que se encuentren en el directorio indicado en la propiedad “Static
content directory seen form client”.
Deploy this Location Sirve para confirmar que se desea armar un .WAR para la Location
actualmente seleccionado.
Web Application Name Este es el nombre que identifica a la aplicación Web. Para algunos
motores de servlets va a ser utilizado luego en la URL para invocar los
servlets.
Additional Libraries Aquí se deben agregar todos las librerías adicionales para ejecutar la
aplicación; el caso más común es el de los drivers JDBC.
Additional Files Esta es una estructura de directorios (que por defecto es vacía) en la
cual se puede agregar todo el contenido estático que se necesite para
ejecutar la aplicación.
En el tab “Deployment Descriptor” se edita el descriptor del .WAR a generarse, en formato XML.
El propósito de este anexo es explicar una serie de conceptos sobre cómo funciona el Web.
Para esto es necesario conocer el significado de ciertos conceptos que vamos a usar frecuentemente
a lo largo del curso.
Como la intención de este capítulo es establecer el lenguaje común que utilizaremos a lo largo del
curso en lo que a Internet se refiere, trataremos de dar una visión intuitiva de los temas para no
aburrir al lector con detalles innecesarios.
Internet
WWW
Página Web
URL
Protocolo HTTP
HTML
Aplicación Web
o Servlets
o Asp.net
Javascript
Intranet
Internet es el nombre genérico que recibe la unión de todas las redes de comunicación a nivel
mundial. Se podría definir como una red global en la que se unen todas las redes que utilizan
protocolos TCP/IP y que son compatibles entre sí.
Web o WWW
El World Wide Web (Web o WWW) es uno de los muchos servicios ofrecidos en la red Internet.
Es un sistema de información con interfaz gráfica, fácil de usar, que emplea la red Internet como
medio de transmisión y permite navegar para buscar documentos en Internet. Estos documentos,
como también los links que existen entre ellos forman un "Web" de información.
El Web permite saltar o "hyperlink" de una página Web (o Web page) a otras.
Los sitios Web (Web sites) son como los libros (libros electrónicos) y las páginas Web son como las
páginas específicas de estos libros. Estas páginas pueden contener noticias, imágenes, sonidos, 3D,
etc. Además pueden estar ubicadas en computadoras de cualquier parte del mundo.
Los libros electrónicos mantienen el concepto básico del libro, y además, brindan la oportunidad de
disponer de una estructura no lineal, la que permitirá, entre otras cosas, decidir el orden en el que
se desea recibir la información.
Algunos de los servicios disponibles en Internet aparte de la Web son el acceso remoto a otras
máquinas (SSH y telnet), transferencia de archivos (FTP), correo electrónico (SMTP), boletines
electrónicos (news o grupos de noticias), conversaciones en línea (IRC y chats), mensajería
instantánea (MSN Messenger, ICQ), transmisión de archivos, etcétera.
Página Web
Una página Web es un documento de la World Wide Web normalmente en formato HTML .
Una página Web típicamente, incluye texto, imágenes y enlaces hacia otros documentos de la red,
pudiendo además contener animaciones, sonidos, programas en Java, y cualquier otro tipo de
documento, por medio de plugins y otras tecnologías.
Actualmente las páginas Web ya no están únicamente enfocadas para ser visualizadas, sino que cada
vez son más dinámicas permitiendo que el visitante participe en ellas mediante menúes interactivos,
encuestas, votaciones, etc.
En el Web se distinguen básicamente dos tipos de páginas. Las páginas estáticas y las páginas
dinámicas.
Las páginas estáticas son las más sencillas, se crean usando un editor de páginas Web o bien
escribiendo directamente el código HTML.
Mientras que se ajustan muy bien a los requerimientos iniciales de hacer promoción y obtener
alguna venta ocasional, o bien la venta masiva de muy pocos productos, no se adecuan a la mayor
parte de las necesidades de la venta.
La desventaja que presentan es que el mantenimiento de las mismas implica un alto costo si se
realizan cambios con frecuencia, ya que una persona debe realizar las modificaciones
correspondientes.
Algunos ejemplos de estas páginas son: Información general, Marketing, Información similar a la que
se distribuye en folletos y documentos. Tienen la ventaja de brindar un acceso rápido y cómodo a
información y brindar direcciones de correo electrónico para información y soporte.
Las páginas dinámicas son creadas en el momento en que son referenciadas por el usuario. Si bien
tienen un estilo base, la información desplegada en las mismas es dinámica.
Son interactivas, ya que permiten que la página a visualizar pueda ser creada en base a la
información ingresada por el usuario. Por ejemplo, una consulta de los pedidos pendientes de una
orden de compra.
Las páginas dinámicas permiten interactuar con una base de datos, por lo que son una poderosa
herramienta para impulsar los negocios de la empresa.
Al utilizar este tipo de páginas, la actualización se realiza en forma automática, pues al acceder a la
página se accede a la base de datos con la información actualizada.
Algunos ejemplos que se prestan para una aplicación que utilice páginas dinámicas:
Home Banking: operaciones varias sobre cuentas bancarias.
Venta directa: Compra de artículos desde la casa, similar a la compra por catálogo.
Las aplicaciones Web desarrolladas con GeneXus generan normalmente páginas dinámicas (porque
acceden a la base de datos).
Intranet
Una Intranet es una red de Área Local (LAN) privada empresarial o educativa que proporciona
herramientas vía Internet, las cuales tienen como función principal proveer lógica de negocios para
aplicaciones de captura, reportes, consultas, etc. con el fin de auxiliar la producción de dichos grupos
de trabajo; es también un importante medio de difusión de información interna a nivel de grupo de
trabajo. No necesariamente proporciona Internet a la organización; normalmente, tiene como base
el protocolo TCP/IP de Internet y, por ser privada, puede emplear mecanismos de restricción de
acceso a nivel de programación como lo son usuarios y contraseñas de acceso o incluso a nivel de
hardware como un sistema firewall que pueda restringir el acceso a la red organizacional.
Aplicación Web
Una aplicación Web es aquella que los usuarios usan accediendo a un servidor Web a través de
Internet o de una Intranet.
Son populares debido a la practicidad del navegador Web como cliente “ligero”. Otra razón
importante de su popularidad es la habilidad para actualizar y mantener aplicaciones Web sin
distribuir e instalar software en miles de potenciales clientes.
Tecnologías
Para poder comprender mejor la tecnología escondida detrás de las aplicaciones desarrolladas para el Web,
es necesario aclarar algunos conceptos adicionales.
Los diferentes lenguajes utilizan diferentes tecnologías para generar las páginas dinámicas.
Inicialmente surgió la tecnología CGI y luego las Web Classes las cuales fueron utilizadas en versiones
anteriores de GeneXus por los generadores C/SQL y Visual Basic respectivamente para desarrollar
aplicaciones Web.
Actualmente, las tecnologías empleadas son los servlets y los asp.net por los generadores Java y .NET
respectivamente.
SERVLETS
La palabra servlet deriva de otra anterior, applet, que se refería a pequeños programas escritos en Java que
se ejecutan en el contexto de un navegador Web. Por contraposición, un servlet es un programa que se
ejecuta en un servidor Web.
El uso más común de los servlets es generar páginas Web de forma dinámica a partir de los parámetros de la
petición que envíe el navegador Web.
ASP.NET es otra alternativa de Microsoft para el desarrollo de aplicaciones Web. Esta tecnología se
desarrolló para la nueva plataforma .NET y se trata de una evolución de las ASP o Active Server Pages.
También en este caso se trata de aplicaciones que ejecutan en el servidor y envían el HTML resultante al
cliente. Los programas en el servidor son .dll’s que se invocan con extensión .aspx.
Las aplicaciones Web utilizan también código JavaScript para permitir mayores funcionalidades.
JavaScript
JavaScript es un lenguaje interpretado orientado a las páginas Web, con una sintaxis semejante a la del
lenguaje Java.
Se ha convertido en un verdadero lenguaje de programación que aporta la potencia de cálculo del navegador
para aumentar la usabilidad de aplicaciones Web con técnicas avanzadas como Ajax.
Ajax
Ajax es una arquitectura y no una tecnología. Ajax stands for Asynchronous JavaScript XML.
Incorpora:
Ajax transforma la experiencia del usuario Web de una experiencia discontinua, donde los usuarios
deben esperar por la respuesta del servidor luego de cada solicitud de una página, en una
experiencia continua y unida, donde los usuarios interactúan con una interfase que rápidamente
responde, sin importar las conexiones al servidor que pasana ser invisibles al usuario..
URL
Cuando visualizamos una página Web con Netscape, Internet Explorer o cualquier otro navegador,
los links (visualizados subrayados y generalmente en color azul), contienen información oculta que
apunta a la ubicación del recurso al que se hace referencia.
Se puede pensar una URL como un puntero estándar a un recurso Internet. El recurso podría ser un
gráfico, un sonido o simplemente un archivo de texto.
Las URL’s también pueden usarse para iniciar sesiones telnet, ftp y otros servicios.
En muchos casos es conveniente conceptuar una URL como el equivalente de estándar DOS para
nombre y path de un archivo.
De hecho una URL puede apuntar a un archivo en la máquina local y también puede apuntar a un
archivo específico de un directorio específico en una máquina remota.
Sintaxis
protocol://host/path/filename[?parm1,…,[parmn]]
Ejemplo: www.genexus.com
Una URL absoluta empieza siempre por el protocolo, es seguido de dos puntos (":") y de una parte
específica del esquema.
Una URL relativa comprende sólo la parte específica del protocolo de una URL, o de algún
componente de seguimiento de aquella parte. El protocolo y componentes principales se infieren del
contexto en el cual aparece la referencia URL: es decir del documento que contiene la referencia.
Protocolo HTTP
El protocolo HTTP es un protocolo sin estado, es decir, que no guarda ninguna información sobre
conexiones anteriores. Al finalizar la transacción todos los datos se pierden.
Está basado en el modelo cliente-servidor: un cliente HTTP abre una conexión y realiza su solicitud al
servidor, el cual responde generalmente el recurso solicitado y la conexión se cierra.
4) Se cierra la conexión: Si el servidor retornó el recurso solicitado, el browser realizará la carga del
mismo y será desplegado al usuario.
<Línea inicial>
Header-1: value-1
...
Header-n: value-n
En las solicitudes van tres campos separados por un espacio en blanco: "Método recurso
VersiónDelProtocolo". Por ejemplo: "GET /path/to/file/index.html HTTP/1.0".
La línea inicial de una respuesta tiene tres campos separados por un espacio: "versiónDelProtocolo
códigoRespuesta Mensaje". Por ejemplo: "HTTP/1.0 200 OK" o bien "HTTP/1.0 404 Not Found".
La característica de ser un protocolo sin estado, popularizó el uso de cookies, que son archivos que
se almacenan en el computador que puede leer un sitio Web al establecer conexión con él, y de esta
forma reconocer a un visitante que ya estuvo en ese sitio anteriormente. Gracias a esta
identificación, el sitio Web puede almacenar gran número de información sobre cada visitante,
ofreciéndole así un mejor servicio. (Más adelante profundizaremos en cookies.)
Existe también una variante de este protocolo, que brinda comunicaciones seguras en Internet
denominado https. También profundizaremos en este concepto más adelante en este curso.
HTML
Es el lenguaje en el cual están escritos los documentos del WWW. Es un subconjunto especializado
del lenguaje más general SGML (Standard Generalized Markup Language).
El lenguaje HTML está compuesto por una serie de códigos o tags ubicados dentro de un documento
ASCII, que son traducidos por un Web browser como Netscape, Internet Explorer, etc., en
instrucciones específicas para formatear el documento que se va a desplegar en la pantalla. Entre
dichos tags están incluidos los tags de hyperlinks, que permiten especificar enlaces hacia otros
recursos en el Web.
Un documento HTML consiste en texto que compone el contenido del documento y tags, los cuales
definen la estructura y apariencia del documento. La estructura de un documento HTML es simple.
Cada documento tiene un cabezal (head) y un cuerpo (body), delimitados por los tags <head> y
<body>. El cabezal es donde se indica un título al documento y donde se indican otros parámetros
que el browser podría utilizar en el momento de desplegar el documento. El cuerpo es donde se
coloca el contenido propiamente dicho del documento HTML. Esto incluye el texto a desplegar y
otros controles que indican al browser cómo desplegar el texto. Los tags también referencian
archivos de efectos especiales como imágenes y sonido e indican los hot spots que enlazan el
documento a otros documentos.
<HTML>
<HEAD>
</HEAD>
</BODY>
</HTML>
el cual se vería en un browser de la siguiente forma:
Web Server
Un servidor web es un programa que implementa el protocolo HTTP (hypertext transfer protocol), el
cual está diseñado para transferir páginas web.
Un servidor web se encarga de mantenerse a la espera de peticiones HTTP llevada a cabo por un
cliente HTTP que solemos conocer como navegador. El navegador realiza una petición al servidor y
éste le responde con el contenido que el cliente solicita.
A modo de ejemplo, al teclear www.genexus.com en nuestro navegador, éste realiza una petición
HTTP al servidor de dicha dirección. El servidor responde al cliente enviando el código HTML de la
página; el cliente, una vez recibido el código, lo interpreta y lo muestra en pantalla. Como vemos con
este ejemplo, el cliente es el encargado de interpretar el código HTML, es decir, de mostrar las
fuentes, los colores y la disposición de los textos y objetos de la página; el servidor tan sólo se limita
a transferir el código de la página sin llevar a cabo ninguna interpretación de la misma.
Sobre el servicio web clásico podemos disponer de aplicaciones web. Éstas son fragmentos de
código que se ejecutan cuando se realizan ciertas peticiones o respuestas HTTP. Hay que distinguir
entre:
el cliente web es el encargado de ejecutarlas en la máquina del usuario. Son las aplicaciones tipo
Java o Javascript: el servidor proporciona el código de las aplicaciones al cliente y éste, mediante el
navegador, las ejecuta. Es necesario, por tanto, que el cliente disponga de un navegador con
capacidad para ejecutar aplicaciones (también llamadas scripts). Normalmente, los navegadores
permiten ejecutar aplicaciones escritas en lenguaje javascript y java, aunque pueden añadirse más
lenguajes mediante el uso de plugins.
el servidor web ejecuta la aplicación; ésta, una vez ejecutada, genera cierto código HTML; el servidor
toma este código recién creado y lo envía al cliente por medio del protocolo HTTP.
Las aplicaciones de servidor suelen ser la opción por la que se opta en la mayoría de las ocasiones
para realizar aplicaciones web. La razón es que, al ejecutarse ésta en el servidor y no en la máquina
del cliente, éste no necesita ninguna capacidad adicional, como sí ocurre en el caso de querer
ejecutar aplicaciones javascript o java. Así pues, cualquier cliente dotado de un navegador web
básico puede utilizar este tipo de aplicaciones.
Web Browser
Un navegador web o web browser es una aplicación que permite al usuario recuperar y visualizar
documentos de hipertexto, comúnmente descritos en HTML, desde servidores web de todo el
mundo a través de Internet.
Los navegadores actuales permiten mostrar o ejecutar: gráficos, secuencias de vídeo, sonido,
animaciones y programas diversos además del texto y los hipervínculos o enlaces.
Ejemplos de otros navegadores utilizados son Nestcape Navigator, Firefox, Mozilla, etc..
Thin Client
Un Cliente Liviano (Thin client) es una computadora (cliente) en una arquitectura de red cliente-servidor
que tiene muy poca o ninguna lógica del programa, por lo tanto depende principalmente del servidor central
para las tareas de procesamiento.
La palabra liviano se refiere a lo pequeña que es la imagen de arranque, quizás no más grande que la
requerida para conectar a la red y arrancar un navegador web.