Objeto WEB Panel

Anuncio
OBJETO WEB PANEL
246
Características
• Permiten definir consultas interactivas a la base de
datos.
• Son flexibles por lo que se prestan para múltiples
usos.
Los web 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.
El término “interactivamente” se refiere a que el usuario podrá ingresar en la pantalla de un web panel una
y otra vez distintos valores de filtros, y consultar a continuación los datos que concuerden con los mismos.
Además, sobre los datos consultados, el usuario podrá realizar distintas acciones, como veremos.
Los web panels no permiten la actualización de la base de datos, sino sólo su consulta1.
El objetivo primordial de este objeto GeneXus 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.
En este capítulo estudiaremos algunos detalles de este tipo de objeto.
-------------------------------------------------------------------------------------------------------------------A menos que se utilicen en combinación con los business components (estudiados más adelante)
1
247
Elementos
•
Algunos de ellos son:
• Web Form
• Reglas
• Condiciones
• Subrutinas
• Eventos
• Propiedades
• Ayuda
• Documentación
Los elementos de los web panels son:
Web Form: Cada web panel contiene un form Web, el cual debe ser diseñado por el analista agregándole
variables, atributos, así como otros controles, para que el usuario pueda interactuar con el mismo.
Reglas: Las reglas de un web panel permiten definir ciertos comportamientos puntuales de dicho objeto.
Por ejemplo, declarar qué parámetros recibe, definir qué variables no queremos que sean aceptadas en el
form sino utilizadas para desplegar información, etc.
Condiciones: Es para definir las condiciones que deben cumplir los datos a ser recuperados (filtros).
Subrutinas: Son rutinas locales al web panel.
Eventos: Los web panels emplean la programación orientada a eventos. Este tipo de programación permite
definir código ocioso, que se activa en respuesta a ciertas acciones provocadas por el usuario o por el
sistema. En esta sección de un web panel es donde se define el código ocioso asociado a los eventos que
pueden ocurrir durante la ejecución del web panel.
Propiedades: Son características a
comportamiento general del web panel.
ser
configuradas para definir
ciertos
detalles referentes al
Ayuda: Permite la inclusión de texto de ayuda, que los usuarios podrán consultar en tiempo de ejecución
del web panel.
Documentación: Permite la inclusión de texto técnico como documentación para los desarrolladores.
248
Clasificación de web panels
• Web panels de Entrada
• Web panels de Salida
• Web panels Mixtos
Todo web panel tiene un form asociado, y en el mismo, contrariamente al comportamiento del form de una
transacción, los atributos que se incluyan serán de salida, y las variables que se incluyan serán de
entrada.
Es fácil de comprender que el objetivo del form de un web panel es exactamente el contrario al objetivo del
form de una transacción, ya que:
• a través del form de una transacción se ingresan los valores de los atributos en la base de datos.
• a través del form de un web panel, se consultan / recuperan los valores de los atributos de la base de
datos.
Es por esto que los atributos son de entrada en las transacciones y de salida en los web panels.
Y en lo que respecta a las variables, las mismas son de salida en las transacciones y de entrada en los web
panels.
La siguiente clasificación describe los distintos usos posibles de los web panels:
· Web panel de entrada: le damos este nombre a un web panel que tiene la única función de aceptar
valores digitados por el usuario (esto significa que su form contendrá únicamente variables).
· Web panel de salida: le damos este nombre a un web panel que tiene la única función de mostrar
información (esto significa que su form contendrá únicamente atributos, pudiendo también contener
variables a las cuales se les haya cambiado el comportamiento por defecto de ser de entrada, definiéndolas
de salida y cargándoles valores explícitamente).
· Web panel mixto: le damos este nombre a un web panel que permite tanto ingresar valores como
mostrar información (en este caso su form contendrá tanto variables como atributos, o bien sólo variables,
algunas con el comportamiento por defecto de ser de entrada y otras definidas explícitamente de salida y
cargándoles valores).
Vale aclarar que esta clasificación es independiente de la herramienta; es decir, GeneXus internamente no
clasifica a los web panels.
249
Web panel de Entrada
Event Enter
¾ Las variables adquieren el valor digitado luego de
presionar algún botón.
Event Enter
RList.call( &NombreClienteInicial, &NombreClienteFinal )
endevent
Denominamos web panels de entrada a aquellos web panels cuya única función es que el usuario realice
ingresos de valores por medio de los mismos. Por lo tanto, sus forms contendrán solamente variables.
Por ejemplo, un web panel de entrada puede contener dos variables &NombreClienteInicial y
&NombreClienteFinal como se muestra arriba. En tiempo de ejecución, el usuario podrá ingresar valores en
las variables &NombreClienteInicial y &NombreClienteFinal dado que en los web panels las variables son
por defecto de entrada.
En el evento Enter del web panel (asociado al botón Confirm), se invocará a un reporte, al cual se le
pasarán por parámetro las variables &NombreClienteInicial y &NombreClienteFinal para que el reporte liste
todos los clientes cuyos nombres se encuentren en el rango solicitado:
Event Enter
RListClienteRange.call( &NombreClienteInicial, &NombreClienteFinal )
EndEvent // Enter
De modo que la definición de este web panel de entrada es para que el usuario ingrese el rango de
clientes a listar, y al seleccionar el botón Confirm, se ejecute el reporte correspondiente.
250
Web panel de Salida
tabla base:
CLIENTE
Regla:
parm(in:ClienteId);
Denominamos web panels de salida a aquellos web 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 en los forms de web panels son indefectiblemente de salida1. Otra posibilidad es incluir en el
form variables, pero habrá que cambiarles su comportamiento por defecto de ser de entrada, a ser de
salida, y cargarles valores explícitamente2.
El web panel mostrado arriba ha sido creado para exhibir los datos de un cliente. Se necesita invocarlo
desde otro objeto, pasándole por parámetro el código del cliente del cual se quiere mostrar la información.
Para resolver esto, una vez creado el web panel “Ver Datos del Cliente”:
• se han agregado los atributos que se desean visualizar en su form
• se ha definido la regla: Parm(in: ClienteId); en la sección de reglas del objeto
Tan sólo definiendo esto obtendremos el comportamiento deseado.
¿Qué concluirá GeneXus acerca de este web panel, cuando lo especifiquemos?
Primeramente GeneXus observará que los atributos incluidos en el form pertenecen a las tablas CLIENTE y
PAIS respectivamente. El siguiente diagrama de Bachman explicita la relación entre ambas tablas:
-------------------------------------------------------------------------------------------------------------------CLIENTE
PAIS
Al contrario de lo que sucede con los atributos en las transacciones (salvo los inferidos o los que tienen
regla noaccept o propiedad Enabled deshabilitada).
2 El comportamiento por defecto de las variables también es opuesto entre Web Panels y Transacciones.
1
251
Teniendo en cuenta la relación entre las tablas involucradas, GeneXus descubrirá que deberá recorrer la
tabla CLIENTE y acceder a la tabla PAIS por el concepto de tabla extendida. La tabla PAIS no podrá ser
elegida para ser recorrida porque su tabla extendida no incluye a la tabla CLIENTE.
Así es que GeneXus determinará un for each asociado al web panel, en este caso con tabla base CLIENTE;
nosotros no escribimos el for each, pero GeneXus lo infiere automáticamente.
A su vez, como en la regla parm definida en el web panel se recibe un atributo, el mismo actuará como
filtro por condición de igualdad. Es decir, que al ejecutarse la recorrida de la tabla CLIENTE (accediendo a la
tabla PAIS para traer el nombre de país), se filtrará por el código de cliente recibido por parámetro.
Concluyendo, se recorrerá la tabla CLIENTE, con condición de filtro por el cliente recibido en la regla parm y
se mostrarán los datos en la pantalla. El nombre del país del cliente (PaisNombre) se inferirá por el
concepto de tabla extendida y se mostrará también en la pantalla.
Decimos que este web panel tiene tabla base, y la misma es CLIENTE. Esto significa que el web panel
tiene un for each implícito / automático asociado, cuya tabla base es CLIENTE.
252
Web panel de Salida
grid: Se cargan los
registros de la base de
datos correspondientes
en archivo temporal
Regla:
parm(in:ClienteId);
tabla base:
FACTURA
Este web panel ha sido creado para mostrar las facturas de determinado cliente. Se necesita desde otro
objeto, invocar a éste, pasándole por parámetro el código del cliente del cual se quieren mostrar sus
facturas.
Para resolver esto, una vez creado el web panel “Ver Facturas Cliente”:
• se han agregado los atributos que deseamos visualizar en su form (utilizando el control grid para mostrar
las N facturas del cliente en cuestión)
• se ha definido la regla: Parm(in: ClienteId); en la sección de reglas del objeto
Este web panel, a diferencia del anterior no es plano, pero continúa siendo un web panel de salida, ya que
lo único que hace es mostrar datos de la base de datos, sin permitir que el usuario ingrese nada.
Cuando se incluye un grid en un form, se está indicando que se va a mostrar una cantidad indefinida de
datos (en este caso, facturas).
Dado que en este web panel hay involucrados atributos de las tablas CLIENTE y FACTURA y que la relación
entre ambas tablas es:
FACTURA
CLIENTE
GeneXus determinará que recorrerá la tabla FACTURA y accederá a la tabla CLIENTE por el concepto de
tabla extendida. La tabla CLIENTE no podrá ser elegida para ser recorrida porque en su tabla extendida no
se encuentra la tabla FACTURA.
De modo que GeneXus determinará un for each implícito asociado al web panel, con tabla base FACTURA,
accediendo a la tabla CLIENTE por el concepto de tabla extendida.
Como en la regla parm definida en el web panel, se recibe un atributo, el mismo actuará como filtro por
igualdad. Es decir, que al ejecutarse la recorrida a la tabla FACTURA accediendo a la tabla CLIENTE, se
filtrará por el código de cliente recibido por parámetro.
Decimos que este web panel tiene tabla base, y la misma es FACTURA. Esto significa que el web panel
tiene un for each implícito/automático asociado, cuya tabla base es FACTURA.
253
Web panel Mixto: “Work With”
•Event Enter
•Evento Usuario
Tabla Base:
CLIENTE
Las
variables
adquieren
el valor
digitado
luego de
presionar
algún
botón
generales
versus
particulares
Los web panels no tienen por qué ser sólo de entrada o sólo de salida. El web panel que se muestra arriba es
de entrada/salida (mixto), su form contiene tanto variables como atributos.
La funcionalidad de este web panel es cargar en el grid los datos de todos los clientes cuyos nombres
cumplan con la condición de filtro especificada. La idea es digitar sobre la variable &ClienteNombre el valor
de filtro deseado, y a continuación presionar el botón Buscar para que se ejecute la consulta en el
servidor y el resultado de la misma sea cargado en la página.
El evento asociado al botón Buscar puede ser el Evento Enter (evento del sistema) ó cualquier evento
definido por el usuario (volveremos sobre esto más adelante).
Las condiciones de filtro pueden definirse de dos maneras posibles:
• A nivel de un grid en particular (botón derecho sobre el grid/Conditions): de hacerlo así, se tratará de
condiciones particulares para ese grid (las que se muestran arriba).
• A nivel de todo el web panel (en la sección Conditions del objeto): de hacerlo así, se tratará de
condiciones globales, es decir que aplicarán a todos los grids del web panel en los que tenga sentido
aplicarlas (más adelante veremos web panels con múltiples grids).
En el web panel del ejemplo tenemos un sólo grid, por lo cual ambas opciones serían equivalentes desde el
punto de vista lógico. Sin embargo es recomendable escribir las condiciones a nivel del grid ya que en un
futuro podrán agregarse más grids al web panel. Además teniendo las condiciones a nivel del grid se
optimiza al momento de la especificación (ya que en caso contrario, GeneXus deberá estudiar para cada grid
si aplicar las condiciones generales a ese grid particular o no).
¿Qué lógica inferirá GeneXus al momento de la especificación del Web Panel?
Como los atributos involucrados en el web panel pertenecen algunos a la tabla CLIENTE y otros a la tabla
PAIS, y en la tabla extendida de CLIENTE está la tabla PAIS, GeneXus determinará que la tabla a recorrer es
CLIENTE y que accederá por su extendida a la tabla PAIS para cargar el valor del atributo PaisNombre. Es
decir, GeneXus determinará un for each implícito asociado al web panel, con tabla base CLIENTE.
Las condiciones definidas antes (a nivel de grid) se incluirán en el for each implícito (como cláusulas
where), de modo tal que al ejecutarse la consulta, se recorrerá la tabla CLIENTE, filtrando por dichas
condiciones.
Es importante considerar que tanto en las condiciones globales del web panel, como en las condiciones
locales a un grid de un web panel, es posible utilizar la cláusula when al igual que cuando se definen filtros
en los objetos reportes y procedimientos.
254
Web panel ¿con tabla base?
• Decimos que un web panel es “con tabla base” cuando GeneXus
puede determinar un for each implícito asociado a él.
• Es decir, si bien el analista no escribe un for each explícitamente
en el web panel para efectuar la consulta, GeneXus lo determina
automáticamente (por eso lo llamamos: for each implícito).
• Tabla base del for each implícito = Tabla base del web panel.
• Un Web Panel es “sin tabla base” cuando GeneXus no puede
determinar una tabla de la base de datos a recorrer para mostrar
la información que se presenta en el form.
• En este caso en el form solamente aparecen variables (y no
atributos).
Un web panel es con tabla base cuando de los atributos que aparecen, GeneXus puede determinar una
tabla de la base de datos a recorrer para, recuperando sus registros, mostrar la información que aparece
en los atributos del web panel.
De este modo, es como si hubiéramos escrito un for each para navegar esa tabla base y trabajar con
algunos atributos de la misma, y de la extendida.
Si en el Web Panel no aparecieran atributos, sino solo variables, evidentemente GeneXus no podrá
determinar una tabla a ser navegada. En este caso el web panel será sin tabla base.
255
Orden de los datos a recuperar
• Botón derecho sobre el grid:
Para definir que una consulta se efectúe ordenando por ciertos atributos, 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 del menú pop up que se muestra arriba.
A continuación, se presentará el diálogo para que se ingresen los atributos por los que se desea ordenar.
Definir esto es equivalente a definir la cláusula order en el comando for each, y se aplica todo lo visto en
dicho tema: desde que para ordenar en forma descendente por un atributo se debe encerrar el atributo entre
paréntesis (), la creación de índices temporales cuando no exista un índice físico correspondiente a los
atributos de ordenamiento, así como la posibilidad de utilizar la cláusula when para condicionar la aplicación
de ese order.
En nuestro web panel “Trabajar Con Clientes” ordenamos los clientes que se listan en el grid por
ClienteNombre.
El poder definir order para un grid permite entre otras cosas optimizar la consulta, cuando se establecen
condiciones de filtro. Así, si en las conditions generales y/o las del grid particular, siendo la tabla base
CLIENTE establecemos los filtros, teniendo dos variables ingresadas por el usuario:
ClienteNombre >= &clienteNombreInicio;
ClienteNombre <= &clienteNombreFin;
Entonces, de no especificar un orden por ClienteNombre, se deberá recorrer toda la tabla, de principio a fin,
para cargar los registros que cumplan con las condiciones. Especificando un order optimizamos la consulta.
Nota: Solamente si el form del web panel no tiene ningún grid (atributos sueltos), 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.
256
Eventos en web panels
• En los web panels se utiliza la programación dirigida por
eventos.
• Eventos disponibles en web panels:
– Evento Start
– Evento Refresh
– Evento Load
– Evento Enter
– Eventos de Usuario
– Evento Click asociado a control
Dado que la programación de los Web Panels está dirigida por eventos, para poder programar
adecuadamente un objeto de este tipo es necesario conocer los eventos existentes y el momento y orden
en que éstos se disparan.
257
Evento Start
• Es un evento del sistema, que ocurre automáticamente siempre
que se hace Get o Post y es el primer evento que se ejecuta.
• 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.
• Ejemplo: se puede utilizar para que un control del form no
aparezca visible, para cargar un bitmap, para asociarle un Link a
otro control, etc.:
Event Start
&var.Visible = 0
&Update = LoadBitmap("images/edit.gif")
newControl.Link = Link(TCliente)
endevent
En el ejemplo, tendremos 3 controles en el form: la variable de nombre var, la de nombre Update de tipo
Bitmap y un control de nombre newControl que puede ser, por ejemplo, un control imagen.
En el evento Start se le asigna a la propiedad Visible del control variable &var el valor 0, indicando que no
deberá verse en el form.
A su vez, a la variable de tipo bitmap, &Update, se le carga la imagen que contendrá, y al control que
suponemos imagen, newControl, se le define la propiedad Link, de manera tal que cuando el usuario haga
clic sobre el control, se invocará a la transacción “Cliente”.
258
Evento Refresh
• El evento Refresh es un evento del sistema
• Se ejecuta cada vez que se realiza un Get o Post.
• Provoca que se ejecute la consulta a la base de
datos.
• Es decir, al ocurrir el evento Refresh, se ejecuta lo
codificado en dicho evento, y a continuación se ejecuta
la consulta a la base de datos. Viene seguido siempre
del evento Load.
259
Evento Load
• Cada vez que se ejecute el evento Refresh en un web panel,
seguidamente se ejecutará el evento Load.
• La cantidad de veces que el evento Load será ejecutado,
dependerá de si el web panel tiene tabla base o no la tiene:
• Tiene tabla base:
• Cuando aparecen atributos que le permiten automáticamente
determinar que se desea navegar una tabla determinada de la
base de datos
• El evento Load se ejecutará N veces
• No tiene tabla base:
• Cuando no ocurre lo anterior (en el form solo hay variables)
• El evento Load se ejecutará solamente una vez.
Cuando el web panel es con tabla base, al producirse el evento Refresh se accede a la base de datos, a
esa tabla base (la asociada al web panel), y se la recorre cargando los registros que cumplan las
condiciones (conditions del grid y generales). Ocurrirá en ese proceso un evento Load por cada
registro en el que se esté posicionado, inmediatamente antes de cargarlo. Esto nos permite realizar
alguna operación que requiera de ese registro (y de su extendida), antes de efectivamente cargarlo en el
grid. Inmediatamente luego de ejecutado el código asociado al evento Load, se cargará la línea del grid y
se pasará el puntero al siguiente registro de la tabla base, para realizar lo mismo (evento Load, carga de
la línea). Este proceso se repetirá hasta cargar todas las líneas del grid.
Si un web panel es sin tabla base, GeneXus no puede determinar automáticamente una tabla de la base
de datos a recorrer para mostrar la información que se presenta en el form. En este caso en el form
solamente aparecen variables (y no atributos) y también ocurrirán los eventos Refresh y Load, sólo que el
evento Load se ejecutará una única vez, dado que no se estará posicionado en ningún registro de
ninguna tabla.
260
Evento Load
en web panel con tabla base
Luego del
evento Refresh
se ejecuta el
evento Load N
veces:
una vez por cada
registro de la
tabla base leído
para ser cargado
en la línea del
grid
Por cada registro leído en la consulta efectuada a la base de datos, se disparará 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 asociados al registro).
261
Evento Load
en web panel con tabla base: ejemplo
Si en el grid que muestra los clientes que cumplen con las condiciones de filtro, quisiéramos agregar una
columna al final, que marque que el cliente es moroso (deudor) si su saldo es mayor a $10.000, es decir,
que en ejecución sobresalga su condición de moroso apareciendo un literal DEUDOR en ese caso, alcanza
con agregar una variable &tipo al grid, de tipo Character(10) y cargarla en el evento Load del web panel
como se muestra arriba.
Para cada registro de la tabla base CLIENTE que se vaya a cargar como línea en el grid, se ejecutará el
código del evento Load, cargándose en la columna &tipo el valor DEUDOR únicamente si el saldo de ese
cliente que va a listarse supera los $10.000.
Luego, si para cada cliente del grid además de mostrar su nombre, país, sexo, saldo y tipo, queremos
mostrar la cantidad de facturas que se le han emitido, alcanza con agregar una variable &cantidad al grid,
e incluir en el código del evento Load, el for each para contar esas facturas.
Observar que el for each definido en el evento Load estará anidado al for each implícito (el de la tabla
base), por lo que se efectuará un join, recorriéndose solamente las facturas de ese cliente, el que se está
cargando.
262
Evento Load
en web panel sin tabla base
•
En un web panel sin tabla base, el evento Load se ejecutará solamente una vez.
Evento Refresh
Evento Load
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 única vez.
Aquí es donde tendremos que cargar el grid, consultando la base de datos con un for each explícito. A
continuación vemos el código de este evento.
263
Evento Load
en web panel sin tabla base: ejemplo
Comando (que solo puede ir dentro de
evento Load) para efectivamente
cargar una línea con el valor que
tengan las variables en ese momento.
El objetivo del comando LOAD dentro del evento Load es cargar efectivamente una línea en el grid.
Una vez que se hayan asignado valores a todas las variables que sean necesarias, y se desee agregar la
línea al grid, deberá ejecutarse el comando LOAD.
Solamente se puede especificar el comando LOAD dentro del evento Load del grid de un web panel y en
ningún otro lado.
Event Load
for each
&ClienteId = ClienteId
&ClienteNombre = ClienteNombre
&ClienteSexo = ClienteSexo
&ClienteSaldo = ClienteSaldo
if ClienteSaldo > 10000
&tipo = ‘DEUDOR’
else
&tipo = ‘’
endif
&cantidad = 0
for each
defined by FacturaFecha
&cantidad += 1
endfor
Load /* LUEGO DE HABER CARGADO TODAS LAS VARIABLES CON LOS VALORES
CORRESPONDIENTES A LA LÍNEA A SER CARGADA EN EL GRID, DEBEMOS INCLUIR
EL
LOAD, EL CUAL AGREGARÁ EFECTIVAMENTE LA LÍNEA AL
GRID. */
endfor
Endevent
COMANDO
Si en la codificación del evento Load definimos comandos For each y asignamos valores a las variables en
las iteraciones pero no incluimos el comando LOAD, en tiempo de ejecución estaremos asignando una y otra
vez valores a las variables, pero no se estarán agregado líneas en el grid (solamente quedará una línea en el
grid con los últimos valores cargados en las variables). Por esta razón es muy importante no olvidar escribir
este comando en el lugar apropiado.
264
Evento Enter
• 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.
265
Eventos de usuario
• Además
de
los
eventos
ofrecidos por GeneXus, el
analista puede definir eventos
creados
por
él,
llamados
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.
Casi todos los controles que aparecen en el form brindan la posibilidad de disparar un evento cuando el
usuario hace clic con el mouse sobre ellos (aparecen como hipervínculos en ejecución); se consigue de
dos maneras distintas:
1. Editando las propiedades del control, y definiendo un evento de usuario en la propiedad
OnClickEvent
2. Dándole un nombre al control y en la sección de Eventos programando:
Event nombreControl.click
…
Endevent
Con esta última alternativa no tendremos que definir un evento de usuario, sino que
estaremos programando el evento click del control.
266
Web panel "Trabajar Con Cliente”
Acciones sobre
el cliente
seleccionado
Para que el web panel con el que venimos trabajando sea un verdadero “trabajar con” se le deben agregar
acciones a ser efectuadas sobre los clientes: la posibilidad de insertar un nuevo registro (nuevo cliente), el
modificar uno existente, o el eliminarlo (así como también poder simplemente “visualizarlo”).
Una forma de implementar esto es agregar los cuatro botones que aparecen arriba, en el form:
.
.
.
.
un
un
un
un
botón
botón
botón
botón
que
que
que
que
ofrezca
ofrezca
ofrezca
ofrezca
insertar un cliente (Insert)
modificar un cliente (Update)
eliminar un cliente (Delete)
visualizar los datos de un cliente (View)
Además debemos permitir la selección de una línea de la grilla para aplicarle alguna de las acciones
definidas en los botones del form. Para ello, accedemos a las propiedades de la grilla con botón derecho
sobre el control grid y configuramos la propiedad AllowSelection con el valor ‘True’ como muestra la
figura. Al hacerlo se nos 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. Estas
funcionalidades se implementan con código javaScript que se envía al Browser al ejecutar el Web Panel.
En la sección de eventos del web panel, definiremos el código asociado a estos botones. Lo veremos en la
página siguiente.
267
Eventos de usuario en el web panel
“Trabajar Con Cliente”
Event ‘Insert’
TCliente.call(‘INS’, 0)
Endevent
Event ‘Update’
TCliente.call(‘UPD’, ClienteId)
Endevent
Event ‘Delete’
TCliente.call(‘DLT’, ClienteId)
Endevent
En las reglas de la
transacción “Cliente”:
Parm(&Mode, &ClienteId );
Variable del
sistema
Variable de
usuario
ClienteId = &ClienteId if not
&ClienteId.IsEmpty();
Event ‘View’
TCliente.call(‘DSP’, ClienteId)
Endevent
La variable &Mode es del sistema y su tipo es Character(3). Tiene la particularidad de “entender” 4 valores:
•
•
•
•
‘INS’: este valor indica ‘ejecutar la transacción en modo Insert’
‘UPD’: este valor indica ‘ejecutar la transacción en modo Update’
‘DLT’: este valor indica ‘ejecutar la transacción en modo Delete’
‘DSP’: este valor indica ‘ejecutar la transacción en modo Display’
¿Cuál es el resultado de recibir por parámetros en una transacción el modo de ejecución y la clave
primaria? El permitir insertar, modificar o eliminar puntualmente una instancia y luego retornar al objeto
llamador.
Es por ello que en todos los eventos definidos en el Web Panel “Trabajar Con Cliente” estamos invocando a
la transacción “Cliente”, pasándole dos valores por parámetro: un literal de 3 letras, que es el modo y el
código de cliente correspondiente a la línea del grid que fue seleccionada (por ello necesitamos habilitar la
selección de líneas del grid, mediante la propiedad AllowSelection que vimos antes).
En definitiva la regla parm a definirse en la transacción "Cliente", es:
parm(&Mode, &ClienteId);
Como se puede observar, no recibimos el código de cliente directamente en el atributo ClienteId, sino en
una variable. ¿Por qué?
Si declaráramos el atributo ClienteId en vez de una variable, el valor que se recibiera en él actuaría
automáticamente como filtro por igualdad. Sin embargo cuando invocamos a la transacción "Cliente" con los
parámetros ‘INS’ y 0, el modo ‘INS’ indica que queremos que la transacción se ejecute en modo insert; y
como en dicho caso no tenemos que enviar el código de cliente para instanciarlo, completamos el segundo
parámetro con valor 0 (porque la cantidad –y el tipo de datos- de los parámetros enviados, debe coincidir
con la cantidad –y el tipo de datos- de los parámetros recibidos). De modo que el valor 0 es para completar
el parámetro simplemente, no para que se filtre por él tratando de instanciar un cliente de código 0.
En los otros 3 casos en que se invoca a la transacción "Cliente" (con los parámetros ‘UPD’ y ClienteId ; ‘DLT’
y ClienteId ó ‘DSP’ y ClienteId respectivamente) sí se quiere filtrar por el valor del código de cliente recibido;
pero basta que haya un caso en el cual se invoque a la transacción y que no sirva filtrar por el valor
recibido, para que no sirva recibir el parámetro en el atributo y esa es la razón por la cuál se está recibiendo
en una variable. Si la clave primaria, ClienteId es autonumerada, entonces en ese caso sí podrá recibirse en
atributo.
Recuerde que a partir de la inclusión de la regla parm en un objeto, éste desaparece del Developer Menú,
debido a que desde el mismo no es posible el envío de parámetros.
268
Web panels - Funcionamiento
• Esquema de trabajo en Internet: el servidor no sabe
lo que se está haciendo en el Browser, hasta que se
someta la página. Es decir, hasta que se dispare un
evento (enter, de usuario, click).
• Orden de disparo de eventos: es diferente si se
trata de la primera carga del web panel (Get) o si
ya estaba cargado cuando se dispara un evento de
usuario, enter, click (Post)
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 o click. En ese momento se envía (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 que es 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, enter o click (POST).
269
GET: Orden de disparo de eventos
• Al ejecutar un web panel por primera vez se
disparan los siguientes eventos:
• Start
• Refresh
• Load
La primera vez que se ejecuta el web panel (se conoce también como el momento en que se hace el
“GET” de la página) los eventos que se disparan son los siguientes y en el siguiente orden:
1. Start
2. Refresh
3. Load
Luego de esto, cuando el usuario haga clic sobre un control que tenga asociado el evento Enter o uno de
usuario o click se ejecutará nuevamente el web panel y el orden de disparo de los eventos será diferente,
como se indica en la siguiente página.
270
POST: Orden de disparo de eventos
• Resto de las ejecuciones del web panel:
• Start
• Lectura de variables
en pantalla
• Evento Enter o de
usuario (submit)
• Refresh
• Load
En el resto de las ejecuciones del web panel, que ocurren cuando se presiona un botón, o se fuerza la
ejecución del evento asociado a una imagen, text block, etc. (haciendo clic sobre el control que tiene asociado
el evento de usuario o Enter o click) momento que se conoce también como el “POST” de la página, los
eventos se dispararán en el siguiente orden:
1. Start (nuevamente se dispara el evento Start)
2. Lectura de las variables de la pantalla. Esto se realiza porque el usuario puede haberlas modificado (por
ejemplo las variables de la parte fija del web panel que están involucradas en las conditions, como en el
ejemplo que se presenta arriba, donde se quieren cargar en el grid los clientes cuyo nombre contenga el
string cargado por el usuario en la variable &ClienteNombre)
3. Evento Enter o click o evento de usuario (código correspondiente al evento asociado al control que se
presionó y produjo el POST).
4. Refresh
5. Load
En el ejemplo no necesitamos codificar nada en el evento asociado al botón Buscar. Solo lo pusimos para
poder enviar al servidor la variable con el valor que ingresó el usuario y que la página se refresque cargando
en el grid los clientes que cumplan con el filtro que el usuario estableció mediante esa variable.
271
Web panels - Variables
• Variables: adquieren valor ingresado por el usuario luego de
sometido evento (POST)
• Si en un evento se usa una variable que se carga en otro evento Æ
la variable debe estar en el form, y además debe estar después del
control en el que se carga su valor.
• Ejemplo:
Event Load
&cont+=1
endevent
Event Enter
Event Refresh
&cont= 0
endevent
if &cont<5
…
endevent
Relacionado con el orden de disparo de los eventos, es importante destacar el momento en que las
variables adquieren los valores ingresados por el usuario: solamente lo harán después de presionar un
botón1 (que es cuando el servidor Web tiene el control del procesamiento).
Por ejemplo, cualquier Link especificado en el evento Start a otro web panel con una variable que se ingresa
en el form no va a tener ningún valor cuando se haga clic sobre el Link.
(Ej: control.Link = HWebPanelX.Link(&var). No se debe escribir esto en el start si la &var esta en el form,
porque al momento de armarse el link no se tiene el valor de la variable)
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 disparen los eventos que la consultan
(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. 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.
Ejemplo: web panel con grid que lista las facturas existentes, y queremos contar la cantidad de facturas que
se listan en el grid. Para ello definimos una variable &cont que debemos incrementar cada vez que se carga
una nueva línea, es decir, en el evento Load del grid.
Para que la variable se cargue correctamente, deberá incluirse luego del grid, puesto que de lo contrario ya se
habrá dibujado en la página, antes de que pueda ser cargada por el evento Load.
Gracias a tenerla en el form, cuando el usuario presione el botón Confirm que consulta por el valor de la
variable, la misma podrá tener el valor cargado antes por el Load.
Recordemos que al presionar el botón Confirm se realizará un POST al servidor, y en él se dispararán Start,
lectura de variables de pantalla (aquí se leerá el valor de &cont que había sido cargado antes por el evento
Load), luego se disparará el evento Enter asociado al Confirm y dentro del mismo se consulta por el valor de
la variable, que gracias a que fue enviada al servidor por estar en el form, tiene el valor que se había cargado
antes. Luego se dispararán Refresh y Load.
Observemos que aquí, cuando se dispare el Load, se incrementará la variable, por lo que deberemos
resetearla antes de que se empiecen a cargar las líneas, porque de lo contrario mostrará el doble de las líneas
que tenía antes. ¿Dónde resetearla?
Event Refresh
&cont = 0
endevent
----------------------------------------------------------------------------------------------------------------------1 O hacer clic sobre algún control del form que tenga un evento de usuario o click o Enter asociado (ya sea con
la propiedad Link, o la propiedad OnClickEvent, o el evento click).
272
Ejemplo: Supongamos que tenemos un web panel donde en un sector del form se puede ingresar usuario
y contraseña para loguearse al sistema.
En el evento donde validamos el usuario y la contraseña (asociado a algún botón o text block),
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 (por ejemplo un web panel de
nombre “DatosCliente”, que recibirá por parámetro el identificador de cliente).
En consecuencia, primero que nada, deberíamos programar lo siguiente en el evento donde validamos el
usuario:
Event ‘Login’
For each
Where ClienteUser = &ClienteUser
If ClientePassword = &ClientePassword
&ClienteId = ClienteId
Mensaje.Caption = ‘Bienvenido/a ’+trim(ClienteNombre)
Else
Mensaje.Caption = ‘La contraseña ingresada no es correcta’
Endif
When none
Mensaje.Caption = ‘El usuario ingresado no existe’
Endfor
Endevent
donde Mensaje es el nombre de un text block que dinámicamente (con la propiedad Caption) cambia de
texto.
Obsérvese que tenemos una tabla CLIENTE que contiene la info de usuario y password.
Para realizar la llamada al web panel Datos del Cliente (DatosCliente), existen varias alternativas, una de
las cuáles sería agregar un botón o una imagen con un evento click asociado (o definir un evento de
usuario y asociárselo al control mediante la propiedad OnClickEvent), entonces el código seria el
siguiente:
Event Ver.clic // “ver” es el nombre de la imagen o botón.
HDatosCliente.Call(&ClienteId)
Endevent
Repasemos entonces lo que ocurre:
1. En la primera ejecución se disparan los eventos: Start, Refresh y Load y podemos ingresar el usuario y
password en las variables respectivas.
2. Cuando presionamos el botón o text block para validar el login, se dispara el evento Start, se leen las
variables anteriores que están en pantalla, se ejecuta el código del evento Login, donde se asigna a la
variable &ClienteId el código de cliente del usuario correspondiente. Luego ocurren Refresh y Load y la
página se despliega en el Browser.
3. Ahora, ya estando logueados, cuando presionamos la imagen o botón con el evento click asociado, se
dispara el evento Start, se leen las variables que están en pantalla, se ejecuta el evento click y ahí cuando
redireccionamos al Web Panel DatosCliente, la variable &ClienteId no tiene valor alguno, ya que la misma
se perdió luego de haber finalizado la ejecución del Web Panel en el punto 2.
Es por esta razón que si queremos disponer del valor de la misma, deberíamos agregar la variable
&ClienteId en el form y la ocultaríamos usando la propiedad Visible (por ejemplo en el evento Start).
Event Start
&ClienteId.Visible = 0
Endevent
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 &ClienteId)
3. Se ejecuta el evento click, y por consiguiente se llama al Web Panel con el código de cliente correcto.
Esto es porque no existe un concepto de “memoria local” para los web objects, por lo cual, si en un
evento se usa una variable que se carga en otro evento, entonces esa variable debe estar presente en el
form, de manera que, aprovechando el orden de disparo de los eventos en el POST, se obtenga el valor
de la variable.
273
Definición de columnas ocultas
en el grid de un web panel
• Al hacer botón derecho sobre el grid y seleccionar Columns:
•Editar las propiedades de la columna
que se quiere ocultar:
Hay veces que por motivos de presentación, no se desea incluir ciertos atributos o variables como columnas
visibles de un grid, pero se necesita tener sus valores cargados en columnas ocultas.
¿Por qué motivo se puede necesitar definir una columna oculta en el grid de un web panel?
Un grid siempre tiene un archivo temporal asociado.
Cuando en un Web Panel se ejecuta el evento Refresh, se comienza a ejecutar la consulta a la base de datos;
a continuación por cada registro leído que cumpla con las condiciones de filtro definidas, se ejecuta el evento
Load y se cargan los datos de dicho registro, en el archivo temporal asociado al grid.
¿Qué datos de los registros se cargan en el archivo temporal? Es decir, ¿qué columnas contendrá el archivo
temporal? Una columna por cada atributo o variable mostrado en el grid, más una columna por cada atributo
o variable declarado en el grid como columna oculta.
A modo de ejemplo, si en un grid hay 2 columnas visibles con los atributos ClienteNombre y ClienteSaldo y
ninguna columna oculta, el archivo temporal asociado al grid contendrá 2 columnas correspondientes a los
atributos ClienteNombre y ClienteSaldo, respectivamente. Si además de esas 2 columnas visibles, se declara
el atributo ClienteId como columna no visible en el grid, el archivo temporal asociado contendrá 3 columnas
correspondientes a los atributos ClienteNombre, ClienteSaldo y ClienteId, respectivamente.
Si en el grid sólo incluimos 2 columnas visibles con los atributos ClienteNombre y ClienteSaldo, en el caso en
que necesitemos en un evento de usuario conocer el valor del atributo ClienteId correspondiente al cliente de
cierta línea seleccionada (para escribir alguna sentencia utilizándolo), no lo tendremos. Para conocer en un
evento de usuario el valor del atributo ClienteId correspondiente a cierta línea seleccionada, tendremos que
incluirlo en el grid ya sea visible o no visible, pero debe estar presente.
Como ejemplo, pensemos en nuestro Web Panel “Trabajar Con Clientes”: necesitábamos una vez que el
usuario seleccionaba una línea, y presionaba el botón “Update” llamar a la transacción “Cliente” enviándole
como parámetro el ClienteId seleccionado. En este caso necesitamos tener el ClienteId en el archivo
temporal, ya sea que esté visible en el grid o no lo esté.
¿Cómo ocultar una columna en un grid?
Para ocultar una columna en un grid, debemos configurar la propiedad Visible del atributo o variable que se
desea ocultar con valor ‘False’. Para ello, debemos hacer clic con el botón derecho del mouse sobre el grid y
seleccionar las columnas (Columns) de la grilla; se abrirá el diálogo mostrado. Luego, habrá que posicionarse
en el atributo o variable que se desee definir como columna oculta, y editar sus propiedades (Properties). Por
último, se debe configurar la propiedad Visible de la columna con valor False.
274
De modo que el motivo por el cual podemos necesitar incluir un atributo o variable como
columna oculta de un grid, es porque necesitemos conocer el valor de ese atributo o variable en
un evento de usuario, pero no deseemos mostrarlo.
Así como los eventos de usuario trabajan con los datos cargados en el archivo temporal asociado
al grid, las condiciones de filtro en cambio, trabajan sobre la tabla física consultada y su tabla
extendida; por lo tanto, al definir condiciones de filtro, se podrán referenciar atributos que
pertenezcan a la tabla física que se consulta y su tabla extendida, sin la necesidad de que dichos
atributos deban estar incluidos en el grid (ni visibles ni ocultos) ni en ninguna otra sección del
web panel.
Por ejemplo, piénsese en el ejemplo que ya presentamos antes:
Event Load
if ClienteSaldo > 10000
&tipo = 'DEUDOR'
else
&tipo = ''
endif
endevent
Aquí surge la pregunta: como en este evento utilizamos el atributo ClienteSaldo para poder
cargar adecuadamente la variable, ¿es necesario colocarlo oculto en el grid? La respuesta es no.
En el evento Load estamos posicionados en un registro de la tabla base. Tenemos a disposición
todos los atributos de esta tabla base y de la extendida, sin necesidad de cargarlos luego en el
grid.
275
Comando FOR EACH LINE
GeneXus nos provee el comando For each line para recorrer las
líneas de un grid en un web panel:
for each line [in NombreGrid]
Sentencia 1
……
Sentencia N
endfor
ƒ
ƒ
in NombreGrid: solamente es necesario explicitarlo cuando hay más
de un grid en el form del web panel.
Sentencia 1, …, Sentencia N: sentencias a ejecutarse para cada
línea recorrida del grid.
276
Comando FOR EACH LINE
Ejemplo
Event ‘Borrar’
for each line
if &dlt = ‘S’
PBorrClientes.call(ClienteId)
endif
endfor
Endevent
A continuación, implementaremos un caso de selección múltiple, una operativa diferente a la presentada en
el caso del web panel Trabajar Con Clientes, que permitía seleccionar una única línea por vez (selección
simple).
La operativa que pretendemos ofrecer en el web panel BorrClientes presentado arriba es la siguiente: luego
de que el usuario haya ingresado un substring para filtrar los clientes y se haya cargado el grid con los
clientes que cumplan dicho filtro, el usuario podrá marcar (con un clic del mouse) qué líneas (clientes) desea
eliminar.
En el ejemplo, hemos incluido en el grid del web panel “BorrClientes", una variable de nombre &dlt (definida
como check box), además de los atributos ClienteId, ClienteNombre, PaisId, PaisNombre y ClienteDireccion.
De esta forma, el usuario seleccionará el check box en los clientes que desea eliminar. A su vez, tendríamos
que tener un botón “Borrar" y en el código del evento asociado a dicho botón deberíamos recorrer el grid y
para cada línea seleccionada invocar a un procedimiento que haga la eliminación física de dicho cliente.
A continuación incluimos el código del procedimiento BorrClientes que recibe en la regla parm el código del
cliente a eliminar (ClienteId).
Reglas:
Parm(ClienteId);
Source:
for each
defined by ClienteNombre
Delete
//se elimina el cliente recibido como parámetro
Endfor
277
Variables en un grid
• Por defecto todas las variables de un grid son
Read-Only
• For each line [in grid], evento click, OnClickEvent:
modifica valor por defecto y todas las variables
del grid pasan a ser de entrada.
• Propiedad: Read Only para que alguna sea de
salida.
Cómo desplegar datos en un grid
Por defecto todo atributo y variable que está dentro de un grid se despliega en ejecución como texto, es decir
que es únicamente de lectura y por consiguiente no puede ser modificado.
Cómo aceptar datos en un grid
Es posible aceptar datos en las variables de un grid dependiendo de la programación de los eventos existentes
en el objeto:
1. Si dentro de un evento del web panel se está utilizando el comando For each line, todas las variables que
están dentro del grid pasan a ser de entrada. Es posible indicar en este caso cuáles son las variables que
no van a poder ser modificadas (Ver más abajo).
2. Si dentro de la fila hay algún control con un evento click asociado (ó evento de usuario especificado en la
propiedad OnClickEvent).
Cómo indicar que una variable no puede ser modificada
1. Para indicar que el valor de una variable en un grid no puede ser modificado, debemos configurar la
propiedad Read Only de la variable con valor ‘True’. Para ello, debemos hacer clic con el botón derecho
del mouse sobre el grid y seleccionar las columnas (Columns) de la grilla. Luego, habrá que posicionarse
en la variable que se desee definir como de sólo lectura, y editar sus propiedades (Properties). Por último,
se debe configurar la propiedad Read Only de la columna con valor True.
2. Utilizando la regla Noaccept()
278
Diferentes tipos de grilla/grid
• Grid estándar: datos repetitivos en formato fijo (línea, columna)
• Grid Freestyle: datos repetitivos en formato libre
Se dispone de dos tipos de grilla:
• Grilla estándar: la que vimos hasta ahora, en Transacciones y Web Panels
• Grilla Freestyle
Estas grillas, agregan potencia al diseño de aplicaciones web, permitiendo al desarrollador mayor libertad a la
hora del diseño.
279
Grid estándar
Propiedades:
Establece si el grid se
cargará o no por
páginas (paginado).
Indica cantidad de
filas por página.
0 Æ todas (no habrá
paginado)
Permite
selección de
línea del grid
Los grids permiten trabajar con datos repetitivos en web panels y transacciones con form HTML. Las columnas
de los grids pueden ser atributos, variables (incluyendo las de tipo bitmap), y siempre tendrán una primera fila
que corresponderá a los títulos de las columnas.
En ejecución, el grid será una tabla HTML.
Para interiorizarse de cada una de las propiedades configurables de un grid, sugerimos acceder al Help de
GeneXus. Aquí solo mencionaremos algunas como ejemplo:
ControlName: Permite indicar el nombre del control. Siempre se le asigna un nombre por defecto.
Class: Clase (del tema asociado al objeto) asociada al control. La propiedad Class solo se encuentra disponible
si el control está en el form de un objeto que tiene un Tema asociado.
BackColorStyle: Permite asignar un estilo al grid. Los estilos disponibles son:
1. None: el grid no tendrá un estilo particular, sino que tendrá el diseño del form o del control que lo contenga.
2. Header: permite especificar un color para el fondo de los títulos del grid y otro para las líneas del mismo.
Las propiedades son LinesBackColor y TitleBackColor.
3. Report: permite especificar un color para el fondo de los títulos y alternar colores para las líneas pares e
impares del grid. Las propiedades son LinesBackColor, LinesBackColorEven y TitleBackColor.
4. Uniform : permite especificar un único color para el fondo del grid(tanto el título como las líneas).
Dependiendo del valor de la propiedad “BackColorStyle”, estarán disponibles otras propiedades adicionales
relacionadas con la configuración de las líneas del grid.
Rows: Esta propiedad permite al usuario indicar la cantidad de registros que va a cargar en el grid. Aplica
únicamente a los grids que tienen tabla base. Si el valor de esta propiedad es 0, se despliegan tantas líneas
como registros resulten de la consulta asociada. El valor por defecto de esta propiedad es 0.
Collapsing:
• AllowCollapsing :True: Permite colapsar el grid en ejecución
• Collapsed :True: Arranca el grid colapsado.
Selection:
• AllowSelection: True: Especifica que es posible seleccionar una línea en la grilla.
• SelectionColor: Seleccionar el color deseado al marcar la fila
• AllowHovering: True: Marca la fila cuando el mouse se posiciona sobre la misma.
• HoveringColor: Seleccionar el color deseado
280
Grid Freestyle
• Permite “formato libre” de los
registros
• Tabla con registros repetitivos
• No posee títulos para las
columnas
• Permite tener más de un tipo de
control en una misma celda
grid
• Propiedades de diseño de tablas
• Propiedades del Grid
El grid Freestyle permite al usuario definir el formato de los datos a desplegar de una forma menos
estructurada que el grid estándar.
El grid Freestyle 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 freestyle 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. Cabe destacar que el grid Freestyle posee las mismas propiedades mencionadas
anteriormente para el grid estándar.
En este caso para poder visualizar las propiedades hay que seleccionar la tabla donde se encuentran los
atributos/variables.
En el ejemplo presentado arriba queremos mostrar alguna información de los clientes. El atributo ClientePhoto
se ha incluido en la transacción “Cliente” para almacenar la foto de cada cliente (es un atributo de tipo Blob).
Pero no queremos mostrar la información como lo haríamos en un grid estándar, con cada elemento de
información en una columna distinta del grid. Aquí queremos mostrar la foto y debajo el nombre del cliente.
El comportamiento de las variables dentro de un grid Freestyle es análogo al que presentan dentro de un grid
estándar, por lo tanto también quedan de ingreso si existe un For each line o For each line in <grid> dentro
de algún evento, o si se asocia un evento a cualquier control de la fila. Nuevamente este comportamiento
puede modificarse, agregando la regla noaccept o cambiando la propiedad Read Only.
281
Grid Freestyle
Propiedades
Para visualizar las propiedades de un grid Freestyle, hay que seleccionar la tabla del grid, presionar el botón
derecho del mouse y seleccionar la opción ‘Properties’.
Nuevamente, para interiorizarse de cada una de las propiedades configurables de un grid freestyle, sugerimos
acceder al Help de GeneXus. Aquí solo mencionaremos algunas como ejemplo:
Class: Permite modificar la clase de un control, ya sea en tiempo de diseño como en ejecución.
La clase debe pertenecer al tema asociado al objeto que contiene el control. La propiedad Class solo se
encuentra disponible si el control está en el form de un objeto que tiene un Tema asociado.
BackColorStyle: Permite asignar un estilo al grid. Los estilos disponibles son los mismos que para un grid
estándar (ver grid estándar)
Rows: Esta propiedad permite al usuario indicar la cantidad de registros que va a cargar en el grid. Ídem a
grid estándar.
Columns: Esta propiedad permite al usuario indicar cuántas columnas va a tener el Freestyle grid en
ejecución. Si se ingresa un valor distinto de 1, el Freestyle grid va a mostrar los registros en tantas columnas
como se haya especificado en la propiedad. Si el valor de esta propiedad es 0, se despliegan tantas columnas
como registros resulten de la consulta asociada. El valor por defecto de esta propiedad es 1. Esta es propia de
este tipo de grids.
Propiedades modificables en ejecución: En tiempo de ejecución se pueden modificar algunas
propiedades, como: visible, backcolor, backColorEven, BackColorOdd, Columns, Rows y
RecordCount: La propiedad RecordCount aplica únicamente a grids que tienen tabla base y retorna un
número mayor o igual a cero representando la cantidad de registros de la tabla base del grid que cumplen las
condiciones de selección. Puede retornar -1 si no existe navegación para la tabla base del grid.
PageCount: La propiedad PageCount devuelve la cantidad de páginas del grid en base a las propiedades
Rows y Columns del mismo. Al igual que la propiedad RecordCount, devuelve –1 si el grid no tiene tabla base.
Para el caso de un grid estándar, también existe esta propiedad dinámica, pero toma en cuenta solo la
propiedad Rows.
282
Paginado de grids en Web panels
• Asignarle valor a propiedad
Rows para indicar cantidad
de registros a cargar por
página.
• Métodos:
•
•
•
•
•
Firstpage
Nextpage
Previouspage
Lastpage (tabla base)
Gotopage (tabla base)
• Propiedades:
• RecordCount (tabla base)
• PageCount (tabla base)
Descripción
El paginado del grid aplica a grids comunes y freestyle cuya propiedad ‘Rows’ tenga un valor diferente de
cero. Existen algunas diferencias relacionadas con la paginación cuando un grid tiene tabla base o no.
Podemos agregar al web panel “Trabajar Con Cliente” botones de navegación para el grid (se muestran
arriba) y eventos para realizar el paginado.
Métodos
A continuación se describen los métodos disponibles:
FirstPage:
El método FirstPage lleva al usuario al primer conjunto de registros devueltos.
Los valores devueltos por este método son los siguientes:
0: Operación exitosa
1: No está habilitado el paginado en el grid
NextPage
El método NextPage lleva al usuario al siguiente conjunto de registros.
Los valores devueltos por este método son los siguientes:
0: Operación exitosa
1: No está habilitado el paginado en el grid
2: Ya se encuentra en la última página
PreviousPage
El método PreviousPage lleva al usuario al conjunto anterior de registros.
Los valores devueltos por este método son los siguientes:
0: Operación exitosa
1: No está habilitado el paginado en el grid
2: Ya se encuentra en la primera página
Lastpage
El método LastPage lleva al usuario al último conjunto de registros. Puede ser utilizado únicamente si el grid
tiene tabla base.
Los valores devueltos por este método son los siguientes:
0: Operación exitosa
1: No está habilitado el paginado en el grid
3: El grid no tiene tabla base
283
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.
Los valores devueltos por este método son los siguientes:
0: Operación exitosa
1: No está habilitado el paginado en el grid
Propiedades
Cada grid dispone de las siguientes propiedades que son utilizadas en la paginación:
RecordCount
La propiedad RecordCount aplica únicamente a grids que tienen tabla base y retorna un número mayor o
igual a cero representando la cantidad de registros de la tabla base del grid que cumplen las condiciones de
selección. Puede retornar -1 si no existe navegación para la tabla base del grid.
PageCount
La propiedad PageCount devuelve la cantidad de páginas del grid en base a las propiedades Rows y
Columns del mismo. Al igual que la propiedad RecordCount, devuelve –1 si el grid no tiene tabla base.
Recomendamos estudiar las consideraciones de eficiencia relacionadas con el uso de estos métodos. Se
aconseja realizar un buen filtrado de datos del grid.
284
Reglas más utilizadas en Web Panels
A diferencia del objeto transacción, en el cual se programa su comportamiento mediante la definición de
reglas, en el objeto web panel la programación es dirigida por eventos.
Son pocas las reglas para web panels, y las mismas permiten definir comportamientos puntuales (hay algunas
reglas más además de las mencionadas, que se pueden consultar en el Help de GeneXus).
Noaccept(&variable);
En los web panels las variables que están en el form fuera de un control grid, ó que están dentro de un grid
pero hay algún evento donde se utiliza el comando For each line, o se le ha asociado evento de usuario o click
a algún atributo o variable del grid, son de entrada por defecto; es decir, el comportamiento por omisión es
que en las mismas pueden ingresarse valores.
Para definir que una variable se presente deshabilitada en un web panel, es decir, no permitiendo ingresos en
la misma, una opción es definir la regla:
noaccept(&variable);
siendo &variable una variable definida en el objeto.
La otra opción que tenemos en GeneXus para que una variable se presente deshabilitada en un web panel es
configurando la propiedad Read Only de la variable con valor ‘True’.
Ver sección Propiedades de la grilla.
Default(&variable, valor);
Asigna un valor por defecto a una variable.
&variable: es una variable definida en el objeto.
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.
El valor por defecto se asignará a la variable al principio de la ejecución del programa.
285
Conceptos fundamentales
• Web panel con a lo sumo un grid:
• Con tabla base
• Sin tabla base
• Web panel con N grids:
• Grids paralelos
• Grids anidados
286
Web Panel “con tabla base”
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:
1. form: en la parte fija
2. form: en el grid (visibles o no visibles)
3. el order del grid
4. las condiciones del grid (no en las condiciones globales)
5. los eventos fuera de comandos for each
GeneXus busca la mínima tabla extendida que contenga a todos estos atributos, y la tabla base de dicha
mínima tabla extendida, será la tabla base del for each implícito (es decir, la tabla que navegará el for each),
se llamará tabla base del web panel.
Observar que GeneXus no toma en cuenta para determinar la tabla base de un web panel:
1) los atributos recibidos por parámetro
2) los atributos mencionados en las condiciones globales del web panel
Éstos actúan como filtros una vez determinada la tabla base.
287
Web panel “sin tabla base”
• Un web panel “sin tabla base” es aquel que no
tiene atributos en ninguno de los 5 lugares
puntuados antes.
• Por lo tanto GeneXus no determina un for each
implícito asociado a él.
Los web panels de entrada generalmente son web panels “sin tabla base” por el hecho de que suelen
contener solamente variables; entonces, por no contener atributos en ninguno de los 5 lugares tenidos en
cuenta por GeneXus para determinar la tabla base, son web panels “sin tabla base”.
Además del caso de los web panels de entrada, existen otros casos que ameritan la definición de web panels
“sin tabla base”.
En la próxima página vemos la resolución de una consulta con un web panel sin tabla base.
288
Web panel “sin tabla base”
Ejemplo
• Mostrar para cada cliente el total facturado, pero sólo de los
clientes que tienen facturas.
Event Load
For Each ClienteId
defined by FacturaFecha
&Cliente = ClienteNombre
&Total =0
for Each
&Total +=FacturaTotal
endfor
Load
endfor
EndEvent
Dado que no mencionamos atributos en ninguno de los 5 lugares tenidos en cuenta por GeneXus para
determinar la tabla base, se trata de un web panel “sin tabla base”.
Por tratarse de un web panel “sin tabla base”, el evento Load se ejecuta una sóla vez; y en el mismo
codificamos explícitamente los accesos con comando for each: cargamos valores en variables y para cargar
líneas en el grid utilizamos el comando LOAD.
Nota: Observar en este caso que todas las columnas definidas en el grid (variables: &Cliente y &Total) son
exclusivamente de salida, manteniendo el comportamiento por defecto definido para las variables en un grid.
Esto se debe a que no se está utilizando el comando For each line en ninguno de los eventos del web panel, ni
tampoco hay definido un evento click asociado a un control del grid (ni OnClickEvent).
289
Comando LOAD
• El objetivo del comando LOAD es incluir efectivamente una línea
en un grid.
• Una vez que se haya asignado valores a todas las variables que
sean necesarias, y se desee agregar la línea al grid, deberá
ejecutarse el comando LOAD.
• Solamente se puede especificar el comando LOAD dentro del
evento Load del grid de un web panel.
Si en la codificación del evento Load definimos comandos For each y asignamos valores a las variables en las
iteraciones pero no incluimos el comando LOAD, en tiempo de ejecución estaremos asignando una y otra vez
valores a las variables, pero no se estarán agregado líneas en el grid (solamente quedará una línea en el grid
con los últimos valores cargados en las variables).
290
Web panel “con tabla base”
Ejemplo
• Mostrar para cada cliente el total facturado, pero sólo de los
clientes que tengan facturas.
Event Load
&Total =0
For Each
&Total +=FacturaTotal
endfor
EndEvent
Atributo Oculto: FacturaFecha
Atributo Order: ClienteId
¡Corte de control!
Atributo en el form del web panel: ClienteNombre
Atributo oculto (no visible) en el grid: FacturaFecha
tabla base del web panel: FACTURA
Atributo order en el grid: ClienteId
Al especificarse este web panel, GeneXus determinará que la tabla base del mismo es FACTURA, significando
esto que el web panel tiene un for each implícito asociado, con tabla base FACTURA.
Recordemos que en los web panels con tabla base, el evento Load se ejecuta N veces y es muy importante
el siguiente concepto:
Si en un web panel con tabla base, se incluye un comando for each en el evento Load, dicho for
each se anidará al for each implícito asociado al web panel. Es decir, el for each definido en el
evento Load no será un for each independiente.
En el web panel del ejemplo, codificamos lo siguiente en su evento Load:
- Inicialización de la variable &Total con valor cero
- For each cuya tabla base será FACTURA (porque el único atributo que contiene es FacturaTotal) y dentro del
mismo incrementamos la variable &Total con el total de cada factura (FacturaTotal) recorrida.
De modo que como el web panel tiene tabla base FACTURA, en su evento Load definimos un for each con
tabla base FACTURA también, y definimos un order indicando un criterio de agrupación, hemos
implementado en el web panel con tabla base, un corte de control.
En cambio, si no hubiésemos puesto el atributo FacturaFecha en el grid, el web panel seguiría teniendo tabla
base, pero esta vez sería CLIENTE. En el evento Load se definió un for each con tabla base FACTURA (ya que
dentro del comando for each solamente se encuentra el atributo FacturaTotal). El for each del evento Load
no será un for each independiente, sino que se anidará al for each implícito asociado al web panel
y estaremos implementando un join.
GeneXus analizará: ¿existe algún atributo relación entre las tablas CLIENTE y FACTURA? Sí, ClienteId. Por lo
tanto, GeneXus definirá el siguiente filtro automático en el for each con tabla base FACTURA:
FACTURA.ClienteId = CLIENTE.ClienteId.
291
En resumen, cuando se ejecute el evento Refresh del web panel, comenzará a ejecutarse el for each
implícito asociado al web panel. Y por cada cliente recorrido, justo antes de cargarse una línea en el grid
con el mismo, se ejecutará el evento Load. Entonces, para ese cliente que se venía recorriendo, se
ejecutará el código definido en el evento Load (es decir, se recorrerán sus facturas, sumando el total
facturado del cliente). Al finalizar la ejecución del evento Load, se cargará la línea en el grid. Obsérvese que
aquí no es necesario especificar comando Load para realizar la carga: se hace automáticamente por el
hecho de tener una tabla asociada a este grid.
En los eventos de usuario sucede algo parecido: cuando se incluye un for each en un evento de usuario, el
mismo no es un for each independiente tampoco, sino que también se anidará al for each implícito asociado
al web panel. GeneXus considerará qué línea del grid está seleccionada al momento de ejecutar el evento
de usuario (recordar Allowselection = True), y para los datos de la misma ejecutará el evento. De modo
que si estando seleccionada determinada línea con un cliente, se ejecuta un evento de usuario, y el mismo
tiene un for each con tabla base FACTURA, se recorrerán las facturas del cliente de la línea
seleccionada.
Teniendo los conceptos relacionados al objeto web panel bien claros, el analista GeneXus podrá optar si
definir un web panel “con tabla base” o “sin tabla base”.
292
Web panels “con N grids”
Grids paralelos
• 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.
• Atributos que participan en la determinación
de la tabla base de 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
A diferencia de lo que sucedía para un web panel con un solo grid, en el caso de múltiples grids los atributos
de la parte fija del web panel no participan en la determinación de la tabla base de ninguno de ellos, pero
deberán pertenecer a la tabla extendida de alguno (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).
293
Web panels “con N grids”
Grids paralelos - Ejemplos
Una tabla base por grid
No busca ni establece relaciones entre ellas
Ejemplo:
Dado que el web panel “Ver Proveedores y Clientes” 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.
En este ejemplo, no hay definidos ni Order ni Conditions para ninguno de los grids, por lo tanto GeneXus sólo
tendrá en cuenta los atributos incluidos en cada grid para determinar sus tablas bases. La tabla base del grid
que se encuentra arriba en el form será: PROVEEDOR y la tabla base del grid que se encuentra abajo en el
form será: CLIENTE.
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 “Ver Proveedores y Clientes”, en el web panel “Ver Clientes y Facturas”, GeneXus
determinará la tabla base del primer grid (que será CLIENTE) y la tabla base del segundo grid (que será
FACTURA), 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á definirlas
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.
294
Web panels “con N grids”
Grids paralelos – Eventos y carga
•
•
•
•
•
Un Refresh global
No se relacionan las cargas
Refresh independiente de grids.
Evento Load de cada grid
Secuencia de Carga:
Refresh
<Grid Control Name1>.Refresh
<Grid Control Name1>.Load
<Grid Control Name1>.Load
<Grid Control Name1>.Load
N veces si GridControlName1 tiene
tabla base. Sino 1.
<Grid Control Name2>.Refresh
<Grid Control Name2>.Load
<Grid Control Name2>.Load
<Grid Control Name2>.Load
N veces si GridControlName2 tiene
tabla base. Sino 1.
En web panels con más de un grid, existe un evento Refresh global y un evento Refresh particular para
cada grid. El evento Load, no existe global sino sólo a nivel de cada grid.
Los eventos Refresh y Load a nivel de grids, deben referenciar al grid usando la siguiente nomenclatura:
Event <Grid Control Name>.<Refresh | Load>
....
EndEvent
Por ejemplo, si en el web panel “Ver Proveedores y Clientes”, los nombres de los grids son SuppliersGrd y
ClientesGrd respectivamente, para codificar los eventos Refresh y Load a nivel de los grids, la sintaxis deberá
ser:
Event SuppliersGrd.Refresh
....
EndEvent
Event SuppliersGrd.Load
....
EndEvent
Event ClientesGrd.Refresh
....
EndEvent
Event ClientesGrd.Load
....
EndEvent
Además de estos eventos a nivel de los grids, estará el evento Refresh global:
Event Refresh
....
EndEvent
La carga de los grids en un web panel se realiza para cada grid de forma independiente. Es decir, aún si los
datos que se muestran en ambos grids están relacionados, el especificador no relaciona las cargas.
La carga asociada a los grids de un web panel incluye el evento Refresh, o sea que la secuencia de carga de
un objeto con 2 grids es como se muestra arriba. La ejecución del método Refresh de cualquier grid solo se
dispara par refrescar dicho grid.
El orden en que se cargan los grids es como aparecen en el form: de arriba hacia abajo y de izquierda a
derecha. De esa manera, cada uno de los grids se cargará con los datos correspondientes.
295
Web panels “con N grids”
Grids paralelos - Comandos
• Load: La sintaxis sigue siendo Load, pero debe estar incluido
dentro del evento load asociado al grid que se está queriendo
cargar. Su uso es análogo al caso de un grid (sin tabla base).
– Event Grid1.Load
....
Load
Endevent
• For each line: Debe incluir una referencia al grid de la siguiente
forma:
– For each line IN <Grid Control Name>
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.
296
Web panels “con N grids”
Grids paralelos - Cargas Relacionadas
• Se requiere la implementación de un Web
Panel que muestre en un grid todos los países
(GrdPaises), y cada vez que el usuario
seleccione un país, que se carguen sus clientes
en un segundo grid (GrdClientes).
SOLUCIÓN
297
Web panels “con N grids”
Múltiples grids - Cargas Relacionadas
AllowSelection = True
Event Enter
&PaisId = PaisId
EndEvent // Enter
AMBOS GRIDS CON TABLA BASE
En la solución que se presenta, ambos grids han sido definidos “con tabla base”, así que cada uno de ellos
tiene un for each ímplicito asociado:
• GrdPaises tiene un for each implícito asociado que navega la tabla PAIS.
• GrdClientes tiene un for each implícito asociado que navega la tabla CLIENTE.
Debemos habilitar la selección de línea por parte del usuario para el grid de países (propiedad AllowSelection
del grid GrdPaises). Cuando el usuario la seleccione, presionará el botón “Ver Clientes” para que se
desplieguen en el grid inferior todos los clientes del país seleccionado.
Para ello necesitamos guardar en una variable el país seleccionado, para que luego, cuando se haga la carga
del grid de los clientes, puedan éstos filtrarse mostrando solo los que correspondan al valor almacenado en
esa variable.
Es decir, en el evento asociado al botón, asignaremos a la variable &PaisId el valor del país actual, es decir,
del de la línea seleccionada por el usuario.
Recordemos que cuando se presione este botón, se disparará el evento Start, luego se leerán las variables del
form (en este caso no hay), luego se disparará el evento asociado al botón (allí se le dará valor a la variable) y
luego se dispararán el evento refresh general y a continuación los eventos refresh y load para cargar
nuevamente el grid de países, e inmediatamente el refresh y load para cargar los clientes (y aquí se aplicará el
filtro asociado).
Observar que no necesitamos colocar la variable &ClienteId en el form, puesto que es cargada y utilizada en la
misma ejecución en el servidor, por lo que no pierde su valor.
Existen otras soluciones posibles para implementar la carga relacionada en web panels con múltiples grids que
veremos a continuación.
298
Solución Nro. 2: Grid Grdcountries “con tabla base” y GrdClientes “sin tabla base”
En esta segunda solución, el grid GrdPaises ha sido definido “con tabla base”, así que tiene un for each
ímplicito asociado al mismo, que navega la tabla PAIS.
Debemos habilitar la selección de línea por parte del usuario sobre este grid, a través de la propiedad
AllowSelection.
Una vez que el usuario se posiciona en una línea y presiona el botón “Ver Clientes” se debe refrescar el
grid GrdClientes con los clientes que pertenezcan a ese país.
Al igual que antes, en el evento asociado al botón (en nuestro caso es el enter), debemos darle valor a la
variable para que luego pueda ser utilizada para filtrar.
Event Enter
&PaisId = PaisId
endevent
El grid GrdClientes fue definido “sin tabla base” asociada, por lo cual debemos programar a mano la carga
del grid en el Evento Load.
Event GrdClientes.Load
For each
where PaisId=&PaisId
&ClienteId=ClienteId
&ClienteNombre = ClienteNombre
Load
endfor
Endevent
Como el grid de clientes (GrdClientes) es “sin tabla base”; cada vez que se ejecute Refresh para el grid
GrdClientes, a continuación se ejecutará su evento Load una sola vez. Por lo tanto, programamos en el
evento GrdClientes.Load un for each con tabla base CLIENTE, filtrando los clientes del país que
habíamos cargado en una variable, y agregamos explícitamente los clientes en el grid (asignando a las
variables &ClienteId y &ClienteNombre los valores de los atributos ClienteId y &ClienteNombre
respectivamente y ejecutando el comando Load a continuación para efectuar la carga de cada línea).
Recordemos que cuando el usuario habiendo seleccionado un país en el grid correspondiente, presione el
botón “Ver Clientes” se realizará un post al servidor, donde se ejecutará el evento Start, luego se leerán
las variables de pantalla, se ejecutará el código asociado al botón (evento Enter), donde la variable para
filtrar es cargada, y a continuación se dispara el evento Refresh general, y luego el Refresh seguido de N
ocurrencias del evento Load del grid de países (1 por cada país a ser cargado) y finalmente el evento
Refresh del grid de clientes, seguido de un evento Load para ese grid (dentro del cuál se cargan las líneas
con el comando Load).
299
Solución Nro. 3: Ambos grids “sin tabla base”
En esta tercera solución ambos grids han sido definidos “sin tabla base”, por lo cual el evento Load de
cada grid se ejecutará una sóla vez.
Event GrdPaises.Load
For each
&PaisId=PaisId
&PaisNombre=PaisNombre
Load
Endfor
Endevent
Event GrdClientes.Load
For each
where PaisId=&PaisIdActual
&ClienteId=ClienteId
&ClienteNombre = ClienteNombre
Load
endfor
Endevent
En el evento Load correspondiente al grid GrdPaises, programamos explícitamente con comando for each
y comando Load, que se carguen todos los países de la tabla PAIS.
Luego codificamos el evento Enter asociado al botón “Ver Clientes”:
Event Enter
&PaisIdActual = &PaisId
Endevent
En tiempo de ejecución, estas 3 soluciones vistas se comportarán igual. Como se ha mencionado
anteriormente, si se incorporan bien los conceptos teóricos vistos, el analista GeneXus podrá optar al
definir un web panel, si trabajar “con tabla base”, “sin tabla base” o combinando ambas cosas.
300
Web panels “con N grids”
Grids paralelos - Consideraciones
• Acerca de condiciones de filtro
• 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).
• Las globales nunca participan de la determinación de la tabla base
• No es posible nombrar a un atributo o variable de un grid
• Ejemplo: GrdPaises.PaisId / GrdClientes.PaisId
• Sí es posible referirse a PaisId, codificar sus propiedades, eventos y
métodos
• Igualmente no se recomienda tener el mismo atributo / variable en
más de un grid, ya que las codificaciones afectarían a todos
Si por ejemplo el atributo PaisId se agregara en más de un grid y se codificara: PaisId.Visible=0, el atributo
PaisId quedaría invisible en todos los grids.
301
Web panels “con N grids”
Grids Anidados
• Varios niveles de anidación
• Anidaciones paralelas
• Ej: Paises y Clientes
ejecución
• Para profundizar en este
tema dirigirse al curso de
Desarrollo de aplicaciones
para Internet con GeneXus
Es posible definir grids “anidados” en un web panel.
Los grids anidados consisten en un grid Freestyle al que se puede insertar dentro de una celda otro grid
estándar u otro Freestyle.
Por ejemplo, se quiere tener un web panel que muestre los clientes, pero indentados por país, como se
muestra en la imagen en ejecución arriba a la derecha.
Para ello se define un grid freestyle con el país y dentro de éste se inserta otro grid, en este caso estándar,
con los clientes.
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.
Cada grid puede ser un freestyle o un grid estándar, aunque si es estándar no puede tener ninguno anidado.
Los grids estándar sólo pueden ser hojas del árbol de anidación.
No se ahondará en el tema en el presente curso. Podrá hacerlo en el curso de Desarrollo de aplicaciones para
Internet con GeneXus.
302
Web panels
• Tipos de Web panels
• Component
• Master Page
• Web Page
• Propiedad Type
Los objetos web pueden ser definidos con tres tipos diferentes, configurable en la propiedad Type del
objeto. Para un web panel podrá tomar uno de los valores:
•Component: (transacción ó web panel, que a partir de aquí podrá ser incluido en otro web object)
•Master Page
•Web Page (es decir, el objeto será una transacción ó web panel tal como hemos trabajado hasta el
momento)
El tipo de web panel ‘Component’ se analiza en detalle en el curso Desarrollo de Aplicaciones para Internet
con GeneXus.
A continuación introduciremos el Web Panel tipo “Master Page” y su utilización.
303
Master Pages
HEADER
CONTENT
M ENU
Tener un look&feel consistente es hoy en día un deber de toda aplicación Web.
Crear y mantener cada página de una aplicación Web asegurando la consistencia con el resto del sitio toma
gran tiempo de programación.
En el ejemplo presentado arriba, hemos capturado una pantalla del sitio de Sony. Navegando entre las
distintas pantallas, nos hemos encontrado que todas ellas tienen un header común, así como un menú a la
izquierda de cada página. Ambas cosas pueden ser visualizadas en la pantalla capturada arriba. Lo que va
variando a medida que uno va navegando por las distintas páginas es lo que aparece a la derecha, y que es
el contenido específico de cada página.
¿Cómo implementar un sitio de estas características? Con el conocimiento que tenemos hasta el momento,
tendríamos que repetir la parte del Layout común a todas las páginas del sitio, así como el comportamiento
común, en cada web panel que implementa cada una de esas páginas. Eso introduce dos problemas
fundamentales: si hubiera que realizar alguna modificación a esas partes comunes a todas las páginas,
habrá que ir página por página a realizarlo. Y relacionado con esto, la posibilidad de olvidarnos de hacerlo en
alguna página, o introducir alguna variación en la misma, degradará la consistencia del sitio.
Las Master Pages proveen una forma de centralizar el layout y el comportamiento común en un solo
objeto y reutilizarlo en todo otro objeto sin tener que programar. Esto significa que la modificación de alguna
parte del layout o del comportamiento común es tan fácil como modificarla en un único objeto y ¡listo!.
Se creará un web panel categorizado como “Master Page” con todo lo que sea el Layout y comportamiento
común a todas las páginas del sitio, y en el mismo se dejará un espacio para cargar en cada oportunidad la
página que corresponda (el contenido variable del sitio). Las páginas web que implementan el contenido
variable, se implementan como Web Panels o Web Transactions comunes y corrientes (es decir de tipo “Web
Page”, ver página anterior), y se asocian a la Master Page, de manera que cada vez que se ejecuten, se
carguen con ese “contexto”.
304
Master Pages
• Propiedad Type = ‘Master Page’
• Permiten definir en un único lugar el layout y
comportamiento común a todas las páginas del sitio
(especifican el marco o contexto de toda página)
Header
Menú
Marco, contexto de
todas las páginas
del sitio
Lugar donde las
páginas individuales
serán cargadas.
Master Pages
Se crea entonces un objeto Web Panel y se le configura la propiedad Type con el valor ‘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 web transaction, en la propiedad MasterPage de estos objetos (que por defecto tiene
el valor “(none)”). El efecto de hacer esto será que al ejecutar estos objetos, se ejecutarán con la master page
asociada, es decir, se cargará la master page, y en el “hueco” es donde se cargará la página individual.
Se profundiza en Master Pages, Web Components, Embedded Pages, en el curso Desarrollo de Aplicaciones
para Internet con GeneXus.
305
Descargar