SlideShare uma empresa Scribd logo
1 de 40
Baixar para ler offline
330
Os elementos das web panels são:
Web Form: Cada web panel contem um form Web, o qual deve ser desenhado pelo analista agregando
variáveis, atributos, assim como outros controles, para que o usuário possa interagir com o mesmo.
Regras: As regras de uma web panel permitem definir certos comportamentos pontuais de dito objeto. Por
exemplo, declarar quais parâmetros recebe, definir quais va is não queremos que sejam aceitas no form
mas utilizadas para mostrar informação, etc.
Condições: É para definir as condições que devem cumprir os dados a ser recuperados (filtros).
Subrotinas: São rotinas locais na web panel.
Eventos: As web panels empregam a programação orientada a eventos. Este tipo de programação permite
definir c digo ocioso, que se ativa em resposta a certas ações provocadas pelo usuário ou pelo sistema. Nesta
seção de uma web panel é onde se define o c digo ocioso associado aos eventos que podem ocorrer durante
a execução da web panel.
Propriedades: São caracter sticas a serem configuradas para definir certos detalhes referentes ao
comportamento geral da web panel.
Ajuda: Permite a inclusão de texto de ajuda, que os usuários podem consultar em tempo de execução da web
panel.
Documentação: Permite a inclusão de texto t cnico como documentação para os desenvolvedores.
No exemplo, a web panel contem duas variáveis &StartDate e &EndDate como se mostra acima. Em tempo de
execução, o usuário pode ingressar valores nas variáveis &StartDate e &EndDate visto que nas web panels as
variáveis por default são de entrada.
No evento Enter da web panel (associado ao botão Billing Generation), se obtêm e gravam as faturas cujas
datas se encontrem na faixa especificada.
De modo que a definição desta web panel é para que o usuário ingresse a faixa de datas, e ao selecionar o
botão Billing Generation, se execute o processamento das faturas.
A web panel mostrada acima foi criada para exibir os dados de um cliente. Precisa ser chamada a partir de outro objeto,
passando por parâmetro o código do cliente do qual se quer mostrar a informação.
Uma web panel é um objeto tipicamente utilizado para mostrar informação. Então, quando GeneXus encontra atributos no
form, qual intenção do programador ao ter colocado isso? Pois, o que está pedindo implicitamente é que se busque os
dados correspondentes a base de dados para mostrá-los.
Com a web panel anterior, GeneXus vai a tabela CUSTOMER e filtra pelo atributo recebido por parâmetro, CustomerId,
mostrará a informação do registro encontrado. Que informação? A que reside nos atributos que figuram no form. Mas o
atributo CountryName não se encontra na tabela CUSTOMER. Pois acontece o mesmo que com um for each, um grupo de
grupo de Data Providers, etc., isto é, desde o registro da tabela base, se acessa o registro relacionado da tabela estendida
necessária, para obter o valor do atributo requerido (em nosso caso acessa a tabela COUNTRY para recuperar o valor de
CountryName).
As inferências que GeneXus realiza são as seguintes:
Ao se tratar de uma web panel, os atributos que figurem serão de consulta1. Então GeneXus deve acessar a base de dados
para recuperar seus valores. De quais tabelas? Vai depender se a Web panel possui grids ou não:
• Web panel plana (sem grid): os atributos estão “soltos” no form, como no caso que estamos mostrando. Se isso acontece,
é porque o analista necessita acessar a informação de um registro de uma tabela (e eventualmente dos registros
relacionados pela tabela estendida), como é o caso do exemplo. Neste caso, a web panel estará bem programada se além
disso se agregar um filtro que determine “esse” registro a ser mostrado. Em nosso caso, temos a regra parm que ao receber
no atributo PK da tabela somente vai recuperar um registro. GeneXus determina uma tabela base da web panel, assim
como faz para um for each. Como? Buscando a mínima tabela estendida que contenha os atributos..
• Web panel com um ou mais grids: veremos em seguida, mas já podemos pensar... Qual o sentido de colocar um grid?
Mostrar informação repetitiva. No caso geral: cada grid mostra muitos registros de uma tabela (e sua informação associada).
____________________________________________________________________________________________1 Ao contrário do que acontece com os atributos nas transações (exceto os inferidos ou os que tem regra noaccept ou propriedade Enabled
desabilitada).
O que diferencia está web panel da anterior é que ela não é plana.
Quando se incluiu um grid num form, se está indicando que vai mostrar uma quantidade indefinida de dados
(neste caso, clientes).
Visto que nesta web panel tem envolvidos atributos, GeneXus infere que deseja acessar a base de dados.
Simplesmente dizendo quais atributos deseja mostrar, sem necessidade de mais informação. Existe um grid,
tem atributos, então, necessariamente terá tabela base, isto é, a tabela da base de dados navegada em busca
da informação requerida.
Se ao invés de mostra esta informação em tela, quisermos uma listagem, vamos criar um procedimento com
um print block ‘customer’ com os atributos CustomerName e CountryName e no source programaríamos:
for each
print customer
endfor
Isto é a análogo, somente que o for each está implícito, não tem que especificá-lo. Cada linha do grid que se
carrega, é como o print que se executa em cada iteração do for each da listagem.
Das tabelas CUSTOMER e COUNTRY e da relação entre ambas é Na1, GeneXus determina a tabela base
desta web panel (sendo que a tabela base seja a mínima que contenha todos os atributos referidos). Observe
que este exemplo difere do anterior, que os atributos aparecem num grid, e portanto, não precisa ser realizado
o filtro, fica somente registros de CUSTOMER. Nesta web panel não tem a regra parm que estabeleça filtro
algum.
Também vamos ver que conseguimos que esta web panel além de mostrar os clientes da base de dados no
grid, podem realizar filtros para os clientes que se quer ver em cada oportunidade, seja por nome do cliente,
endereço ou por ambos. Por isso as variáveis aparecem no form.
335
Quando GeneXus pode determinar automaticamente uma tabela para carregar as linhas do grid, o faz, e nesse
caso não precisa dessa informação. É por isso que falamos que nesse caso tem um for each ‘implícito’. Depois
veremos casos em que isso não acontece (grids sem tabela base).
Observe o exemplo, existindo 4 registros na tabela, são carregados um de cada vez, um a um dos quatro.
Se agora queremos que o usuário possa filtrar os clientes que deseja ver...entra em questão as variáveis que
definimos na parte fixa do form, como veremos na página seguinte.
336
Observe como na janela de propriedade do control Grid, aparece un de nome ‘Conditions’. Clicando no combo
abre um editor para especificar as condições booleanas que devem cumprir os registros para ser carregados
como linhas do grid.
É por essa razão que foi agregado as variáveis &CustomerName e &CountryName no form da web panel, para
que o usuário possa ingressar ali valores que operem como filtros sobre os dados a mostrar. Em nosso caso,
estabelecemos filtros com o operador like. As variáveis na parte plana do form de web panels são por default
de entrada. Depois veremos que se estiverem em grids são por default de saída.
Observe que as condições (separadas com “;”) equivalem as que apareciam nas cláusulas where de um for
each (ou grupo repetitivo de data provider).
Da mesma maneira, por questões de otimização, pode determinar, igual se fazia com um for each, critério de
ordenação da tabela percorrida, como se mostra acima no exemplo.
Nota: Assim mesmo, da mesma forma que num procedimento, as condições locais podem ser realizadas no
grid (for each), mas também podem ser gerais, mediante o selector Conditions. Isto tem sentido quando tiver
mais de um grid (for each), para não ter que repetir cada vez a mesma condição.
337
A propriedade Automatic Refresh que se encontra a nível da Web Panel pode ter os seguintes valores:
• When variables in conditions change (valor por default): depois de chamar automaticamente o refresh, se dispara o
evento Load carregando o grid segundo os novos valores das variáveis.
• No
Dependendo do tipo de dados do filtro, e do control web utilizado para filtrar, a condição será aplicada quando se está
digitando ou ao abandonar o campo.
No caso de filtros em controles edit, para tipo de dados Character, são aplicados quando o usuário vai digitando. Para tipo
de dados Date, DateTime e Numeric, as condições são avaliadas ao sair do campo.
No caso de filtros combo boxes ou dynamic combos, as condições são avaliadas quando se abandona o campo. Para
Check boxes e Radio buttons, as condições são avaliadas quando o valor é alterado.
Execução: o que acontece no cliente e no servidor ao ter a propriedade por default e um grid com tabela base?
1ª execução (variáveis vazias):
For each CUSTOMER
guardar em memória CustomerName
acessar o registro de COUNTRY relacionado
guardar em memória CountryName
carregar (load) linha no grid com ambos valores
N-ésima execução (altera o valor da variável das conditions):
Automaticamente no browser do cliente se detecta a mudança refresh no servidor para voltar a carregar o grid com os
registros que cumpram as condições (com os novos valores das variáveis) load para cada linha.
Conclusão: Existem dois eventos do sistema que ocorrem no momento da carga do form (Refresh) e da carga de cada
linha do grid (Load). Como veremos, estes eventos podem ter códigos associados para serem executados nos momentos
específicos...
338
Ampliaremos a funcionalidade de nossa web panel, permitindo ver o estado de cada cliente, e para aqueles
que estiverem ‘On Hold’, brindando a possibilidade de os passar para o estado ‘Active’.
Para fazer isto, agregaremos ao grid o atributo CustomerStatus que mostra o estado, e uma variável booleana
&Select, que permitirá ao usuário selecionar aqueles clientes que deseja ‘ativar’. Além disso um botão para
efetivamente ativar todos os clientes marcados. Mas isto o faremos num segundo momento.
Observe que se o tipo de dados da variável &select booleano, por default aparece no grid como um check box.
Para assegurar que o usuário somente tente ‘ativar’ clientes ‘On Hold’, desejamos que somente apareça
habilitado este check box quando corresponde... para ele necessitaremos programar a carga de cada linha, isto
é, o evento Load...
339
Na seção Events da web panel, programamos o evento Load do grid que vemos acima. No exemplo,
customerGrid é o nome que demos ao control grid no form.
Ao se tratar de uma web panel com um único grid, também poderíamos ter programado o evento Load:
Event Load
if CustomerStatus = Status.OnHold
&select.Enabled = 1
else
&select.Enabled = 0
endif
endevent
Isto é, no caso de uma web panel com um único grid, não é necessário qualificar o evento com o nome do grid.
Igualmente recomendamos fazer, antecipando a possibilidade futura de agregar outro grid no form da web
panel.
O evento Load é disparado para cada linha que vai carregar no grid, encontrando este comando ou não. O que
fazemos no exemplo é aproveitar este momento imediatamente anterior a carga, para efetuar uma ação. E
esse é o código que incluímos no evento.
Agora sim, estamos em condições de implementar a ‘activate’, para isso precisamos associar ao botão um
evento, que poderá ser o evento Enter ou um de usuário...
340
No exemplo, quando o usuário pressiona o botão ‘Confirm’, necessitamos percorrer todas as linhas do grid, e
para cada uma delas, se o usuário marcou a variável boleana &Select f (check box), devemos alterar o estado
do cliente correspondetne, de ‘On Hold’ a ‘Active’.
Ao inserir o botão no form da web panel, e editar suas propriedades, por default se pode observar que o botao
esta associado ao evento Enter (ver propiedad OnClickEvent).
O Entrr será um evento do sistema, executado quando o usuário faz clique no controle associado, assim como
quando ele pressiona a tecla Enter.
Neste exemplo veremos na 1a vez:
• Possibilidade de definir eventos de usuário e associar os controles ou utilizar o evento Enter do sistema.
• Comando For each line, para percorrer as linhas já carregadas no grid.
• Variáveis num grid passam a ser Read only (de saída) por default, a serem de entrada, quando é utilizado um
comando for each line nesse grid (também quando é programado os eventos OnClickEvent, Click, etc., em
alguma coluna do grid).
Observe que a única coisa em comum no comando For each line e comando For each estudado antes, o fato
de representar um estrutura repetitiva. A diferença mais importante: enquanto o for each percorre registros de
uma tabela (base) da base de dados, o for each line percorre as linhas de um grid.
Em nosso exemplo definimos uma variável &customer, Business Component Customer, trocaremos o estado
para ‘Active’ de todas as linhas do grid que o usuário marcou. Para isso utilizamos o comando for each line
para percorremos o grid.
341
Outra possibilidade, ao invés de utilizar o evento do sistema Enter, é definir um evento de usuário. Isso é
realizado seguindo os passos que estão acima.
Como podemos ver, a maioria dos controles presentes em um form tem a propriedade OnClickEvent
associada. Essa propriedade permite especificar um evento a ser disparado quando o usuário faz clique sobre
o controle. Poderá ser um evento do sistema (Refresh, Enter) ou um evento definido pelo usuário.
342
A parte fixa da web panel por default é de entrada, como já vimos anteriormente para as variáveis utilizadas
para filtrar os clientes (customers) mostrados no grid.
Como mostrar dados no grid
Por default todo atributo e variável que está dentro de um grid se mostra em execução como texto, porque é
unicamente de leitura e por consequencia não pode ser alterado.
Como aceitar dados em um grid
É possível aceitar dados nas variáveis de um grid dependendo da programação dos eventos existentes no
objeto:
1. Se dentro de um evento da web panel ter o comando For each line, todas as variáveis que estão dentro do
grid passam a ser de entrada. É possível indicar neste caso quais são as variáveis que não podem ser
modificadas através da propriedade ReadOnly.
2. Se dentro da fila tem algum controle com um evento click, dblClick, etc.. associado (ou evento de usuário
especificado na propriedade OnClickEvent), acontecerá o mesmo.
343
Continuamos ampliando nosso exemplo; agora queremos que o usuário possa selecionar uma linha do grid
(um cliente) e pressionando botão ‘Select customer’ para chamar a web panel que havíamos implementado
anteriormente.
Neste exemplo vemos duas funcionalidades:
• A necessidade de colocar uma coluna no grid oculta (não visível).
• Permitir que o usuário selecione uma linha do grid para fazer algo com ela.
Por que colocar a coluna correspondente a CustomerId e ocultá-la, ao invés de não agregar o atributo? Faça a
seguinte reflexão: o atributo CustomerId enviado por parâmetro ao executar o evento ‘Select customer’, de
onde é extraído? Da base de dados? Não, é o que está carregado no grid. Mais especificamente, para cada
grid existirá um arquivo temporário que contem a quantidade de colunas que o grid possuir, visíveis e ocultas.
Quando o usuário seleciona no grid a segunda linha, e pressiona o botão ‘Select customer’, está posicionado
nesse arquivo temporário, correspondente a essa linha (e nunca na base de dados!). É por esta razão que se
não colocarmos nenhuma coluna correspondente a CustomerId no grid, não estaríamos passando valor algum
a CustomerView.
Para que o usuário possa selecionar uma linha do grid, é suficiente ‘prender’ a propriedade ‘AllowSelection’ do
grid.
344
Como GeneXus determina uma tabela base para percorrer automaticamente para carregar o grid da web
panel?
Se existir algum atributo em pelo menos um dos 3 lugares mencionados, GeneXus poderá encontrar a tabela
base. Para determinar a tabela base, ele extrai os atributos encontrados ali (parte fixa do Form, no Grid, tanto
nas colunas como nas propriedades Order, Conditions ou using Data Selector, e nos eventos programa
programados no selector de Eventos, somente os atributos que estejam ‘soltos’ dentro do evento, isto é, fora
de um comando for each de acesso a base de dados), e determina a mínima tabela estendida que os
contenha. A tabela base dessa estendida, será a percorrida automaticamente e carregada com o Load.
Observe que somente programamos o evento Load para tomar a decisão para cada línea que vai ser
carregada no grid, que habilitará ou não para a mesma variável &select que permitirá ao usuário marcar o
check box.
Importante: A forma de determinação da tabela base de um grid dependerá se existir outro grid na web panel
ou se é o único. O resumo apresentado aqui corresponde a um único grid. Neste caso se diz que a própria
Web panel tem tabela base. É a do grid. Quando existir mais de um grid na web panel, isto não vai ter
sentido, e cada grid passará a ter cada grid passará a ter ou não tabela base. Veremos a forma de
determinação das tabelas bases nesse caso, quando tratemos o caso de múltiplos grids em uma web panel.
345
Estamos apresentando aqui outro exemplo, para que possamos observar um caso que surge a necessidade
natural de implementar um grid sem tabela base.
O caso de implementação natural de um grid com tabela base, é quando deseja que seja carregado para cada
registro de uma tabela, uma linha do grid (1 registro – 1 linha). No caso que se quer carregar uma linha do grid
como produto a ser lido de vários registros da base de dados (N registros – 1 linha), como produtos de
cálculos, etc., é mais natural implementar o grid sem tabela base.
O caso do exemplo: não queremos carregar para cada fatura uma linha, mas sim queremos agrupar as faturas
por data, e para cada grupo, carregar uma linha que some seus valores. Estamos falando de um controle de
corte. Se tivéssemos que implementar uma listagem PDF ao invés de uma web panel, saberíamos como
programar (como o fazemos acima) . Vejamos como implementar com uma web panel...
346
O objetivo do comando LOAD é agregar um linha num grid. É necessário quando o grid não tem tabela base,
visto que nesse caso não será agregado nenhuma linha de forma automática. O evento Load vai ocorrer uma
vez, e o grid retornará vazio caso não seja programado. Portanto neste caso é imprescindível que seja
programado, de acordo com a lógica correspondente. Uma vez que for atribuído a cada variável seu valor, e se
deseja agredar uma linha ao grid, o comando LOAD deverá ser programado.
O comando LOAD somente pode ser especificado dentro do evento Load do grid de uma web panel.
Observe que neste caso a implementação fica por conta do analista. Frente ao caso do grid com tabela base,
neste GeneXus realiza menos inferências.
347
No caso de um grid sem tabela base, os filtros dos dados são programados dentro do código implementado
para carga (o do Load). Aqui não tem o refresh automático. Isto é, quando o usuário modifica os valores das
variáveis que intervém nos filtros, GeneXus não sabe que tem que voltar a carregar o grid.
Para isso deverá, por exemplo, agregar um botão associado ao evento Enter, ou a um evento de usuário, sem
código, devido ao fato que somente precisamos dele para que um Refresh seja realizado, ou seja, para que o
servidor volte a carregar a web panel.
Sobre os eventos disponíveis e a ordem em que são disparados, estudaremos em seguida.
348
Em toda Web panel existem eventos do sistema que podem ser programados. Alguns ocorrem sempre, em
cada execução da web panel (como o Start, Refresh, Load), outros se forem declarados e o usuários
realiza as ações necessárias para provocá-los (Enter, definidos pelo usuário, TrackContext).
Assim mesmo, quase todos os controles que aparecem no form brindam a possibilidade de disparar um evento
quanto o usuário faz clic com o mouse (os hiper-links aparecem em execução); de duas maneiras
diferentes:
1. Editando as propriedades do controle (F4), e definindo um evento de usuário na propriedade
OnClickEvent, ou associando o evento Enter ou o Refresh.
2. Dando um nome ao controle e na seção de Eventos programando:
Event nomeControl.click
…
Endevent
Com esta última alternativa não teremos que definir um evento de usuário, mas sim teremos que
programar o evento click do controle. O mesmo ocorre com os eventos DblClick, RightClick, IsValid...
(quando fizer duplo clique, botão direito, etc.).
Sobre os eventos associados as ações sobre os controles (click, dblclick, drag, drop, etc.) não veremos no
curso presente. Em nosso wiki tem informação detalhada, assim como no Help de GeneXus.
Sobre o evento TrackContext somente mencionaremos que é possível detectar mudanças no valor de um dado
controle (grid, variável, etc.) e nesse caso disparar este evento baseado ao valor modificado, tomar uma
ação.
350
Quando a web panel é com tabela base, ao produzir-se o evento Refresh se acessa a base de dados, a essa
tabela base (associada a web panel), e se percorre carregando os registros que cumpram as condições
(conditions do grid e gerais). Vai ocorrer nesse processo um evento Load para cada registro em que estiver
posicionado, imediatamente antes de carregá-lo. Isto nos permite realizar alguma operação que requeira
desse registro ( e de sua estendida), antes de efetivamente carregá-lo no grid. Imediatamente depois de
executado o código associado ao evento Load, será carregado a linha do grid e o ponteiro é passado ao
seguinte registro da tabela base, para realizar o mesmo (evento Load, carga da linha). Este processo se
repetirá até carregar todas as linhas do grid.
Se uma web panel é sem tabela base, GeneXus não pode determinar automaticamente uma tabela da base de
dados a percorrer para mostrar a informação que se apresenta no form. Neste caso no form somente
aparecem variáveis (e não atributos) e também vão ocorrer os eventos Refresh e Load, somente que o evento
Load é executado uma única vez, visto que não estará posicionado em nenhum registro de nenhuma tabela.
Dentro desse evento a carga terá que ser codificada, que pode ser que precise acessar a base de dados (ex:
comando for each) o não (vamos supor que seq queira carregar o grid com informação obtida ao percorrer um
SDT collection, efetuar alguma transformação sobre seus itens ... ou carregar linhas no grid produto de
cálculos). O controle da carga do grid, neste caso fica nas mãos do analista, utilizando o comando Load. Este
comando somente é válido dentro do evento com o mesmo nome. Note como no caso do grid com tabela base,
este comando não é necessário.
351
A propriedade Automatic Refresh que se encontra a nível da Web Panel pode tomar os seguintes valores:
• When variáveis in conditions change (valor por default): automaticamente provocam o refresh, se dispara
o evento Load carregando-se o grid segundo os novos valores das variáveis.
• No: para que o conteúdo do grid se renove depois de alterar os filtros, o usuário deve realizar uma ação:
Se o grid é com tabela base:
• As alterações nas variáveis dos filtros se detectam automaticamente.
• Ao pressionar a tecla Enter, se dispara o Refresh da página (não o código do evento Enter, ainda
que esteja programado).
• Ao fazer click num botão ou numa imagem associados a um evento de usuário, imediatamente
depois de alterar o valor de uma variável das conditions do grid, se executa este evento e atualiza
imediatamente depois a página. Se o evento for o Enter, este evento NÃO se executa.
Se o grid é sem tabela base:
• As alterações nas variáveis dos filtros NÃO se detectam automaticamente
• O usuário deve fazer click no botão ou na imagem associados a um evento Refresh ou a um
evento de usuário que chame um Refresh.
352
Os eventos disparados e sua ordem depende se a web panel está sendo aberta (Get) ou se já estava aberta e
está efetuando uma ação posterior a um botão (Post).
Acima mostramos com exemplos o caso geral.
1a. vez: Start + Refresh + Load
N-ésima vez: Start + Leitura de variáveis da tela + Evento que produziu o Post + Refresh + Load.
Este é o caso geral... existe uma exceção...
353
Internamente GeneXus determina as entradas e saídas de cada evento. Se em suas entradas, se requerem
que ações sejam executadas no Server, então o evento é executado no Server. Por exemplo, se entre as
entradas de um evento de usuário X, se encontra alguma das saídas do evento Start (do server), então o
evento de usuário é executado no Server.
Se o código do evento não requer que seja executado no servidor, então por performance, será executado no
cliente, como código javascript.
De todas as maneiras o analista GeneXus não deve se preocupar com estes assuntos, visto que em todo caso
será o GeneXus que terá a inteligência de resolver onde vai executar o evento.
354
Aqui apresentaremos um exemplo que reúne os dois casos que viemos estudando: a web panel mostrada em
execução tem dois grids paralelos: um que mostra informação dos clientes do sistema, e outro que mostra
faturas, totalizadas por dia.
No nosso caso, queremos além disso relacionar os dados, de tal maneira que quando o usuário seleciona um
cliente, sejam mostradas somente as faturas desse cliente. Incluso ao estabelecer filtros de datas, também
queremos que vá para o cliente selecionado (e não para todos os clientes).
Quando uma web panel contem mais de um grid em seu form, GeneXus não determina uma única tabela
base associada para web panel, mas sim uma tabela base associada a cada grid.
Atributos que participam na determinação da tabela base de cada grid:
• Os incluídos no grid (são levados em consideração os atributos visíveis como os não visíveis,
ocultos/hidden)
• Os referenciados na Order e Conditions locais do grid
A diferença do que acontecia para uma web panel com somente um grid, no caso de múltiplos grids os
atributos da parte fixa da web panel não participam na determinação da tabela base de nenhum deles, mas
deverão pertencer a tabela estendida de algum (para que seja possível inferir seus valores).Caso isso não seja
respeitado, ao especificar a web panel, se mostra na listagem de navegação resultante, um warning advertindo
desta situação.
Os atributos utilizados nos eventos da web panel tampouco participam na determinação da tabela base de
nenhum dos grids. Os atributos que se inclui nos eventos fora de comandos for each, deverão pertencer a
tabela estendida de algum dos grids (da mesma forma como da parte fixa).
355
Esta web panel poderia ter sido implementada de diferentes formas e obtendo o mesmo resultado na
execução.
Acima podemos ver a implementação mais natural: o primeiro grid tem tabela base e o segundo não tem. Mas
poderia ter sido implementada de forma contrária, com variáveis no primeiro grid e tendo que realizar a carga
dos clientes a mão no Load, e atributos no segundo grid, e algumas coisas a mais para obter o controle de
corte, sendo um grid com tabela base. Ou qualquer combinação (ambos grids com tabela base, ou nenhum
com tabela base).
O importante é, uma vez escolhida a implementação mais natural ao caso, realizá-la corretamente.
Em qualquer dos casos, ainda que a informação a ser carregada em mais de um grid se encontre relacionada
na base de dados, GeneXus não assume nenhuma relação entre os dados na hora de carregar um grid e o
outro. É análogo o caso de um par de for eachs paralelos no Source de um procedimento.
Acima podemos ver a web panel que temos o grid com os grids, agregamos a parte de visualização de faturas
por data que implementamos na web panel. Mas não basta simplesmente unir as duas web panels... para
poder relacionar as cargas dos grids, a lógica deve ser agregada. Em nosso caso desejamos que uma vez que
selecionarmos um cliente do primeiro grid, certa lógica precisa ser agregada. Em nosso caso desejamos que
uma vez um cliente for selecionado no primeiro grid, as faturas carregadas no segundo grid não sejam de
todos os clientes, mas somente do selecionado.
Para isso devemos ter duas coisas: agregar uma variável &CustomerId para armazenar o id do cliente
selecionado ao pressionar ‘Select customer’, e depois agregar um filtro pelo valor dessa variável quando se
carrega o grid de Invoices. Assim mesmo precisa obrigatoriamente colocar essa variável no form para que tudo
funcione corretamente ... como esperamos... e na análise abaixo encontraremos a razão.
356
Vamos analisar o que acontece quando a web panel é executada pela primeira vez.
Primeiro o evento Start é executado, em nosso caso a variável &CustomerId é ocultada.
Podemos ver na imagem, que um evento Refresh genérico é produzido, depois serão produzidos as cargas de
todos e cada um dos grids encontrados na web panel, da esquerda para a direita de cima para baixo.
Um evento Refresh próprio ocorre e o evento Load (se possuir tabela base são N vezes e se não tiver tabela
base somente 1 vez).
Observe que nosso caso, o grid de cliente tem condições para serem carregadas, pelas variáveis de filtro
&customerName e &countryName, não são aplicadas se estiverem vazias (visto que ambas cláusulas
condicionais tem when not &var.IsEmpty())
O segundo grid é sem tabela base, mas como já vimos, o evento Load era executado um for each com
cláusulas where, serão carregadas somente aquelas linhas que as condições são cumpridas. São três:
where InvoiceDate >= &startDate when not &startDate.IsEmpty()
where InvoiceDate <= &endDate when not &endDate.IsEmpty()
where CustomerId = &customerId when not &customerId.IsEmpty()
Observe que nesta primeira execução &customerId está vazio, o filtro não é aplicado e todas as faturas do dia
é carregada, de todos os clientes.
357
O usuário seleciona o cliente do grid o cliente correspondente da linha e pressiona o botão ‘Select customer’.
Uma ação é detectada e ocorre um post ao servidor, quem executa o Start (ocultando a variável), depois as
variáveis da tela são lidas (&customerId no momento está vazia, são consideradas não somente as variáveis
da tela, as que são definidas, mas também a informação completa da linha selecionada pelo usuário com o
mouse, entre ela, o valor de CustomerId, coluna do grid), depois o código do evento que produziu o post é
executado, no nosso caso, ‘Select customer’. Aqui a variável &customerId toma o valor do CustomerId da linha
escolhida. Depois ocorre o evento Refresh geral que dispara o Refresh e Load de cada grid.
Portanto, cada grid é executado executando as conditions. O primeiro se carregado como antes, porque
nenhuma de suas conditions variou. O segundo, agora se tiver um valor para &customerId, somente será
mostrado as faturas do cliente.
Você poderia se perguntar porque precise colocar a variável oculta no form. Simplesmente porque não se pode
usar como variável dentro do programa, se não estiver no form e torná-la invisível. Todavia com esta segunda
execução não podemos responder a pergunta. De fato, se analisarmos, pode ser visto facilmente que teríamos
o mesmo comportamento se somente fosse atribuído valor a variável no ‘Select Customer’ sem colocá-la no
form.
Vamos ver o motivo com a execução seguinte....
358
Agora o usuário já selecionou o segundo cliente, e o que deseja fazer é filtrar suas faturas por data (não quer
visualizar todas).
Para isso especifica os filtros de data, e pressiona o botão ‘Search’, que produzirá um post no servidor.
Então o código do Start é executado, depois são lidas as variáveis da tela: aqui está o motivo de ter colocado
&customerId no form. O valor de &customerId é lido, permanecendo até que o usuário não selecione outro
cliente do grid e pressionar o botão ‘Select customer’... esta variável presente no form, é a forma de manter a
memória em execuções.
Lembre que cada vez que se faz um post ao servidor, é uma nova execução da web panel, já que as variáveis
começam novamente vazias. Por isso que o segundo passo: “Leitura de variáveis da tela” é fundamental.
Agora sim, seguindo o exemplo, as variáveis da tela são lidas &customerId invisível (visible=0), junto com as
variáveis &startDate e &endDate.
E depois, como sempre, a carga é executada (Refresh genérico + Refresh e Load de cada grid).
Alterando as condições do for each que carrega o segundo grid, agora aparece somente as faturas do segundo
cliente, entre as datas estipuladas pelo usuário.
Se agora o usuário quiser alterar o cliente, para ver suas faturas, será feito a seleção no grid de clientes e ao
pressionar ‘Select Customer’, o processo começa novamente como vimos na 2da. execução.
E como fazemos para voltar a trabalhar com as faturas de todos os clientes e não de um?
O que acontece se o usuário não selecionar nenhum cliente do grid com o mouse e pressionar ‘Select
Customer’. O valor da variável &CustomerId fica vazio, pois CustomerId não vai ter valor.
Por este motivo, o botão ‘Select Customer’ poderíamos chamar ‘Select/Unselect’.
359
Os botões inseridos dependem da quantidade de registros e da quantidade de linhas do grid.
360
361
Dois tipos de grid:
• Grid padrão: que vimos até agora, em Transações e Web Panels
• Grid Free Style
Estes grids, agregam potência ao desenho de aplicações web, permitindo ao desenvolvedor maior liberdade na
hora do desenho.
O grid Free Style permite ao usuário definir o formato dos dados a serem mostrados de uma forma menos
estruturada que o grid padrão.
O grid Freestyle é basicamente uma tabela que podem inserir os atributos/variáveis, text blocks, imagens,
botões, web components, embedded pages, grids freestyle e/ou grids que serão mostrados posteriormente na
tela. Neste caso para poder visualizar as propriedades tem que selecionar a tabela onde se encontram os
atributos/variáveis.
No exemplo apresentado acima queremos mostrar alguma informação dos países. O atributo CountryFlag foi
incluído na transação “Country” para armazenar a foto da bandeira de cada país (é um atributo de tipo Blob).
Mas não queremos mostrar a informação como o faríamos em um grid padrão, cada elemento de informação
em uma coluna diferente do grid. Aqui queremos mostrar a foto e abaixo o identificador e nome do país.
O comportamento das variáveis dentro de um grid Free Style é análogo ao apresentado dentro de um grid
padrão, portanto também são de ingresso se existe um For each line ou For each line in <grid> dentro de
algum evento, ou se associa um evento a qualquer controle da fila. Novamente este comportamento pode ser
modificado, agregando a regra noaccept ou alterando a propriedade Read Only.
362
Este caso de grids aninhados é igual o de for each aninhados em um procedimento: ou seja, aqui as cargas
estão relacionadas, e no Grid2 é carregado todos os clientes pertencentes ao país carregado no Grid1.
A ordem de execução dos eventos estará aninhada:
Refresh (genérico)
Grid1.Refresh
Grid1.Load carga de um país
Grid2.Refresh
Grid2.Load carga de cliente do país
Grid2.Load carga de cliente do país
Grid2.Load carga de cliente do país
Grid1.Load carga do país seguinte
Grid2.Refresh
Grid2.Load carga de cliente do país
Grid2.Load carga de cliente do país
Grid2.Load carga de cliente do país
.....
363
364
Os objetos web podem ser definidos com três tipos diferentes, configurável na propriedade Type do objeto.
Para uma web panel poderá ter um dos valores:
• Component: (transação ou web panel, que a partir daqui poderá ser incluído em outro web object)
• Web Page (isto é, o objeto será uma transação ou web panel tal como temos trabalhado até o momento)
• Master Page
Em seguida introduziremos a Web Panel tipo: Component”, “Master Page” e sua utilização.
365
366
367
368
369
Ter um look&feel consistente é hoje em dia um dever de toda aplicação Web.
Criar e manter cada página de uma aplicação Web assegurando a consistência com o resto do site leva grande tempo
de programação.
Ao criar uma base de conhecimento GeneXus X criará também dois objetos de tipo Mastet Page:
• ApplMasterPage: Para a aplicação
• PromptMasterPage: Para os prompts
Uma web panel, AppMasterPager categorizado como “Master Page” será criada com tudo, ou seja, o Layout e
comportamento comum a todas as páginas do site, e no mesmo se deixa um espaço para carregar a página
correspondente (o conteúdo variável do site). Corresponde ao controle especial ContentPlaceholder. As páginas web
que implementam o conteúdo variável, se implementam como Web Panels ou Web Transactions comuns e correntes
(é do tipo “Web Page”, ver página anterior), e se associam a Master Page, de maneira que cada vez que se executem,
são carregadas com esse “contexto”. Agora faça o seguinte, abra qualquer objeto GeneXus com form (transação ou
web panel) criada na KB, e veja o valor da propriedade Master Page.
As Master Pages fornecem uma forma de centralizar o layout e o comportamento comum em somente um objeto e
reutilizá-lo em todo outro objeto sem ter que programar. Isto significa que a modificação de alguma parte do layout ou
do comportamento comum é tão fácil como modificá-la num único objeto e pronto!.
Numa mesma base de conhecimento podem ser definidas tantas Master Pages quanto desejar.

Mais conteúdo relacionado

Mais procurados

Fundamentos de SQL - Parte 5 de 8
Fundamentos de SQL - Parte 5 de 8Fundamentos de SQL - Parte 5 de 8
Fundamentos de SQL - Parte 5 de 8Emiliano Barbosa
 
Utilizando views, stored procedures e triggers
Utilizando views, stored procedures e triggersUtilizando views, stored procedures e triggers
Utilizando views, stored procedures e triggersDaniel Maia
 
Normalização básica
Normalização básicaNormalização básica
Normalização básicaNadia Habu
 
Fundamentos de SQL - Parte 6 de 8
Fundamentos de SQL - Parte 6 de 8Fundamentos de SQL - Parte 6 de 8
Fundamentos de SQL - Parte 6 de 8Emiliano Barbosa
 
TOTVS LINHA RM TREINAMENTO SQL
TOTVS LINHA RM TREINAMENTO SQLTOTVS LINHA RM TREINAMENTO SQL
TOTVS LINHA RM TREINAMENTO SQLFábio Delboni
 
Comandos DDL para o MySQL
Comandos DDL para o MySQLComandos DDL para o MySQL
Comandos DDL para o MySQLArley Rodrigues
 
Aula5 normalização
Aula5   normalizaçãoAula5   normalização
Aula5 normalizaçãoMatias Silva
 
Sql básico - Teoria e prática: Um grande resumo
Sql básico - Teoria e prática: Um grande resumoSql básico - Teoria e prática: Um grande resumo
Sql básico - Teoria e prática: Um grande resumoHelder Lopes
 
Fundamentos de SQL - Parte 4 de 8
Fundamentos de SQL - Parte 4 de 8Fundamentos de SQL - Parte 4 de 8
Fundamentos de SQL - Parte 4 de 8Emiliano Barbosa
 
Treinamento de SQL Básico
Treinamento de SQL BásicoTreinamento de SQL Básico
Treinamento de SQL BásicoIgor Alves
 
Aula 05 banco de dados em asp.net (site do administrador - alterar e excluir)
Aula 05   banco de dados em asp.net (site do administrador - alterar e excluir)Aula 05   banco de dados em asp.net (site do administrador - alterar e excluir)
Aula 05 banco de dados em asp.net (site do administrador - alterar e excluir)Gabriel Bugano
 
Aula de SQL - Básico
Aula de SQL - BásicoAula de SQL - Básico
Aula de SQL - BásicoAirton Zanon
 
Fundamentos de SQL - Parte 1 de 8
Fundamentos de SQL - Parte 1 de 8Fundamentos de SQL - Parte 1 de 8
Fundamentos de SQL - Parte 1 de 8Emiliano Barbosa
 
Fundamentos de SQL - Parte 3 de 8
Fundamentos de SQL - Parte 3 de 8Fundamentos de SQL - Parte 3 de 8
Fundamentos de SQL - Parte 3 de 8Emiliano Barbosa
 
Usando o i report como gerador de relatórios para php
Usando o i report como gerador de relatórios para phpUsando o i report como gerador de relatórios para php
Usando o i report como gerador de relatórios para phpbrunocf007
 

Mais procurados (20)

Aula 11 banco de dados
Aula 11   banco de dadosAula 11   banco de dados
Aula 11 banco de dados
 
Projeto locadora
Projeto locadoraProjeto locadora
Projeto locadora
 
Fundamentos de SQL - Parte 5 de 8
Fundamentos de SQL - Parte 5 de 8Fundamentos de SQL - Parte 5 de 8
Fundamentos de SQL - Parte 5 de 8
 
Consultas SQL
Consultas SQLConsultas SQL
Consultas SQL
 
Aula10 sql-ddl
Aula10 sql-ddlAula10 sql-ddl
Aula10 sql-ddl
 
Utilizando views, stored procedures e triggers
Utilizando views, stored procedures e triggersUtilizando views, stored procedures e triggers
Utilizando views, stored procedures e triggers
 
Normalização básica
Normalização básicaNormalização básica
Normalização básica
 
Fundamentos de SQL - Parte 6 de 8
Fundamentos de SQL - Parte 6 de 8Fundamentos de SQL - Parte 6 de 8
Fundamentos de SQL - Parte 6 de 8
 
TOTVS LINHA RM TREINAMENTO SQL
TOTVS LINHA RM TREINAMENTO SQLTOTVS LINHA RM TREINAMENTO SQL
TOTVS LINHA RM TREINAMENTO SQL
 
Comandos DDL para o MySQL
Comandos DDL para o MySQLComandos DDL para o MySQL
Comandos DDL para o MySQL
 
Aula5 normalização
Aula5   normalizaçãoAula5   normalização
Aula5 normalização
 
Sql básico - Teoria e prática: Um grande resumo
Sql básico - Teoria e prática: Um grande resumoSql básico - Teoria e prática: Um grande resumo
Sql básico - Teoria e prática: Um grande resumo
 
Fundamentos de SQL - Parte 4 de 8
Fundamentos de SQL - Parte 4 de 8Fundamentos de SQL - Parte 4 de 8
Fundamentos de SQL - Parte 4 de 8
 
Treinamento de SQL Básico
Treinamento de SQL BásicoTreinamento de SQL Básico
Treinamento de SQL Básico
 
Aula 05 banco de dados em asp.net (site do administrador - alterar e excluir)
Aula 05   banco de dados em asp.net (site do administrador - alterar e excluir)Aula 05   banco de dados em asp.net (site do administrador - alterar e excluir)
Aula 05 banco de dados em asp.net (site do administrador - alterar e excluir)
 
MySQL Query Optimization
MySQL Query OptimizationMySQL Query Optimization
MySQL Query Optimization
 
Aula de SQL - Básico
Aula de SQL - BásicoAula de SQL - Básico
Aula de SQL - Básico
 
Fundamentos de SQL - Parte 1 de 8
Fundamentos de SQL - Parte 1 de 8Fundamentos de SQL - Parte 1 de 8
Fundamentos de SQL - Parte 1 de 8
 
Fundamentos de SQL - Parte 3 de 8
Fundamentos de SQL - Parte 3 de 8Fundamentos de SQL - Parte 3 de 8
Fundamentos de SQL - Parte 3 de 8
 
Usando o i report como gerador de relatórios para php
Usando o i report como gerador de relatórios para phpUsando o i report como gerador de relatórios para php
Usando o i report como gerador de relatórios para php
 

Semelhante a Web panels: filtros e atualização automática

Semelhante a Web panels: filtros e atualização automática (20)

14 patterns-curso gxxbr
14 patterns-curso gxxbr14 patterns-curso gxxbr
14 patterns-curso gxxbr
 
11 data providers-cursogxxbr
11 data providers-cursogxxbr11 data providers-cursogxxbr
11 data providers-cursogxxbr
 
12 db atualizacao-curso-gxxbr
12 db atualizacao-curso-gxxbr12 db atualizacao-curso-gxxbr
12 db atualizacao-curso-gxxbr
 
Desenvolvimento Delphi
Desenvolvimento DelphiDesenvolvimento Delphi
Desenvolvimento Delphi
 
10 sd ts-curso-gxxbr
10 sd ts-curso-gxxbr10 sd ts-curso-gxxbr
10 sd ts-curso-gxxbr
 
000047 como fazer totvs - v 4.0.0 - entenda o rm conversor de classis para ...
000047   como fazer totvs - v 4.0.0 - entenda o rm conversor de classis para ...000047   como fazer totvs - v 4.0.0 - entenda o rm conversor de classis para ...
000047 como fazer totvs - v 4.0.0 - entenda o rm conversor de classis para ...
 
Aula 01 web server controls
Aula 01   web server controlsAula 01   web server controls
Aula 01 web server controls
 
Cadastro de clientes em java no netbeans
Cadastro de clientes em java no netbeansCadastro de clientes em java no netbeans
Cadastro de clientes em java no netbeans
 
CURSO JAVA 01
CURSO JAVA 01CURSO JAVA 01
CURSO JAVA 01
 
Java13
Java13Java13
Java13
 
Testes de carga com j meter
Testes de carga com j meterTestes de carga com j meter
Testes de carga com j meter
 
03 formulas globais-cursogxxbr
03 formulas globais-cursogxxbr03 formulas globais-cursogxxbr
03 formulas globais-cursogxxbr
 
Manual vsflexgrid
Manual vsflexgridManual vsflexgrid
Manual vsflexgrid
 
IReport.pdf
IReport.pdfIReport.pdf
IReport.pdf
 
Cadastro de clientes em c#
Cadastro de clientes em c#Cadastro de clientes em c#
Cadastro de clientes em c#
 
Apostila: Curso de java III
Apostila: Curso de java IIIApostila: Curso de java III
Apostila: Curso de java III
 
JavaServer Faces Produtividade em Desenvolvimento
JavaServer Faces Produtividade em DesenvolvimentoJavaServer Faces Produtividade em Desenvolvimento
JavaServer Faces Produtividade em Desenvolvimento
 
Treinamento pricing
Treinamento pricingTreinamento pricing
Treinamento pricing
 
Produtividade com JavaServer Faces
Produtividade com JavaServer FacesProdutividade com JavaServer Faces
Produtividade com JavaServer Faces
 
Jdbc
JdbcJdbc
Jdbc
 

Mais de Cristiano Rafael Steffens

CONVOLUTIONAL NEURAL NETWORKS: The workhorse of image and video
CONVOLUTIONAL NEURAL NETWORKS: The workhorse of image and videoCONVOLUTIONAL NEURAL NETWORKS: The workhorse of image and video
CONVOLUTIONAL NEURAL NETWORKS: The workhorse of image and videoCristiano Rafael Steffens
 
A pipelined approach to deal with image distortion in computer vision - BRACI...
A pipelined approach to deal with image distortion in computer vision - BRACI...A pipelined approach to deal with image distortion in computer vision - BRACI...
A pipelined approach to deal with image distortion in computer vision - BRACI...Cristiano Rafael Steffens
 
A CNN BASED MODEL TO RESTORE ILL EXPOSED IMAGES
A CNN BASED MODEL TO RESTORE ILL EXPOSED IMAGESA CNN BASED MODEL TO RESTORE ILL EXPOSED IMAGES
A CNN BASED MODEL TO RESTORE ILL EXPOSED IMAGESCristiano Rafael Steffens
 
Can Exposure, Noise and Compression affect Image Recognition? An Assessment o...
Can Exposure, Noise and Compression affect Image Recognition? An Assessment o...Can Exposure, Noise and Compression affect Image Recognition? An Assessment o...
Can Exposure, Noise and Compression affect Image Recognition? An Assessment o...Cristiano Rafael Steffens
 
MODELAGEM DAS DINÂMICAS DA FORMAÇÃO DA GOTA E TRANSFERÊNCIA DE MASSA EM PROCE...
MODELAGEM DAS DINÂMICAS DA FORMAÇÃO DA GOTA E TRANSFERÊNCIA DE MASSA EM PROCE...MODELAGEM DAS DINÂMICAS DA FORMAÇÃO DA GOTA E TRANSFERÊNCIA DE MASSA EM PROCE...
MODELAGEM DAS DINÂMICAS DA FORMAÇÃO DA GOTA E TRANSFERÊNCIA DE MASSA EM PROCE...Cristiano Rafael Steffens
 
UMA ABORDAGEM COMPARATIVA ENTRE MICROCONTROLADORES: ARDUINO MEGA X ARDUINO DU...
UMA ABORDAGEM COMPARATIVA ENTRE MICROCONTROLADORES: ARDUINO MEGA X ARDUINO DU...UMA ABORDAGEM COMPARATIVA ENTRE MICROCONTROLADORES: ARDUINO MEGA X ARDUINO DU...
UMA ABORDAGEM COMPARATIVA ENTRE MICROCONTROLADORES: ARDUINO MEGA X ARDUINO DU...Cristiano Rafael Steffens
 
FPGA-based sensor integration and communication protocols for automated
FPGA-based sensor integration and communication protocols for automatedFPGA-based sensor integration and communication protocols for automated
FPGA-based sensor integration and communication protocols for automatedCristiano Rafael Steffens
 
Lars 2016 A Texture Driven Approach for Visible Spectrum Fire Detection
Lars 2016 A Texture Driven Approach for Visible Spectrum Fire DetectionLars 2016 A Texture Driven Approach for Visible Spectrum Fire Detection
Lars 2016 A Texture Driven Approach for Visible Spectrum Fire DetectionCristiano Rafael Steffens
 
ICRA 2016 - Interactive section Presentation
ICRA 2016 - Interactive section PresentationICRA 2016 - Interactive section Presentation
ICRA 2016 - Interactive section PresentationCristiano Rafael Steffens
 
Vision-Based System for Welding Groove Measurements for Robotic Welding Appli...
Vision-Based System for Welding Groove Measurements for Robotic Welding Appli...Vision-Based System for Welding Groove Measurements for Robotic Welding Appli...
Vision-Based System for Welding Groove Measurements for Robotic Welding Appli...Cristiano Rafael Steffens
 
Simpósio Unicruz: OpenCV + Python (parte 1)
Simpósio Unicruz: OpenCV + Python (parte 1)Simpósio Unicruz: OpenCV + Python (parte 1)
Simpósio Unicruz: OpenCV + Python (parte 1)Cristiano Rafael Steffens
 
Welding Groove Mapping: Image Acquisition and Processing on Shiny Surfaces - ...
Welding Groove Mapping: Image Acquisition and Processing on Shiny Surfaces - ...Welding Groove Mapping: Image Acquisition and Processing on Shiny Surfaces - ...
Welding Groove Mapping: Image Acquisition and Processing on Shiny Surfaces - ...Cristiano Rafael Steffens
 
Automated control module based on VBM for shipyard welding applications: Stud...
Automated control module based on VBM for shipyard welding applications: Stud...Automated control module based on VBM for shipyard welding applications: Stud...
Automated control module based on VBM for shipyard welding applications: Stud...Cristiano Rafael Steffens
 
An Unconstrained Dataset for Non-stationary Video Based Fire Detection
An Unconstrained Dataset for Non-stationary Video Based Fire DetectionAn Unconstrained Dataset for Non-stationary Video Based Fire Detection
An Unconstrained Dataset for Non-stationary Video Based Fire DetectionCristiano Rafael Steffens
 
Introdução ao processamento de imagens com OpenCV (cont)
Introdução ao processamento de imagens com OpenCV (cont)Introdução ao processamento de imagens com OpenCV (cont)
Introdução ao processamento de imagens com OpenCV (cont)Cristiano Rafael Steffens
 
Um Sistema De Detecção De Fogo Baseado Em Vídeo
Um Sistema De Detecção De Fogo Baseado Em VídeoUm Sistema De Detecção De Fogo Baseado Em Vídeo
Um Sistema De Detecção De Fogo Baseado Em VídeoCristiano Rafael Steffens
 
Um sistema de detecção de chamas utilizando RF e SVM (Short Version)
Um sistema de detecção de chamas utilizando RF e SVM (Short Version)Um sistema de detecção de chamas utilizando RF e SVM (Short Version)
Um sistema de detecção de chamas utilizando RF e SVM (Short Version)Cristiano Rafael Steffens
 

Mais de Cristiano Rafael Steffens (20)

CONVOLUTIONAL NEURAL NETWORKS: The workhorse of image and video
CONVOLUTIONAL NEURAL NETWORKS: The workhorse of image and videoCONVOLUTIONAL NEURAL NETWORKS: The workhorse of image and video
CONVOLUTIONAL NEURAL NETWORKS: The workhorse of image and video
 
A pipelined approach to deal with image distortion in computer vision - BRACI...
A pipelined approach to deal with image distortion in computer vision - BRACI...A pipelined approach to deal with image distortion in computer vision - BRACI...
A pipelined approach to deal with image distortion in computer vision - BRACI...
 
A CNN BASED MODEL TO RESTORE ILL EXPOSED IMAGES
A CNN BASED MODEL TO RESTORE ILL EXPOSED IMAGESA CNN BASED MODEL TO RESTORE ILL EXPOSED IMAGES
A CNN BASED MODEL TO RESTORE ILL EXPOSED IMAGES
 
Can Exposure, Noise and Compression affect Image Recognition? An Assessment o...
Can Exposure, Noise and Compression affect Image Recognition? An Assessment o...Can Exposure, Noise and Compression affect Image Recognition? An Assessment o...
Can Exposure, Noise and Compression affect Image Recognition? An Assessment o...
 
MODELAGEM DAS DINÂMICAS DA FORMAÇÃO DA GOTA E TRANSFERÊNCIA DE MASSA EM PROCE...
MODELAGEM DAS DINÂMICAS DA FORMAÇÃO DA GOTA E TRANSFERÊNCIA DE MASSA EM PROCE...MODELAGEM DAS DINÂMICAS DA FORMAÇÃO DA GOTA E TRANSFERÊNCIA DE MASSA EM PROCE...
MODELAGEM DAS DINÂMICAS DA FORMAÇÃO DA GOTA E TRANSFERÊNCIA DE MASSA EM PROCE...
 
UMA ABORDAGEM COMPARATIVA ENTRE MICROCONTROLADORES: ARDUINO MEGA X ARDUINO DU...
UMA ABORDAGEM COMPARATIVA ENTRE MICROCONTROLADORES: ARDUINO MEGA X ARDUINO DU...UMA ABORDAGEM COMPARATIVA ENTRE MICROCONTROLADORES: ARDUINO MEGA X ARDUINO DU...
UMA ABORDAGEM COMPARATIVA ENTRE MICROCONTROLADORES: ARDUINO MEGA X ARDUINO DU...
 
FPGA-based sensor integration and communication protocols for automated
FPGA-based sensor integration and communication protocols for automatedFPGA-based sensor integration and communication protocols for automated
FPGA-based sensor integration and communication protocols for automated
 
Lars 2016 A Texture Driven Approach for Visible Spectrum Fire Detection
Lars 2016 A Texture Driven Approach for Visible Spectrum Fire DetectionLars 2016 A Texture Driven Approach for Visible Spectrum Fire Detection
Lars 2016 A Texture Driven Approach for Visible Spectrum Fire Detection
 
Php Math and arrays
Php Math and arraysPhp Math and arrays
Php Math and arrays
 
ICRA 2016 - Interactive section Presentation
ICRA 2016 - Interactive section PresentationICRA 2016 - Interactive section Presentation
ICRA 2016 - Interactive section Presentation
 
Vision-Based System for Welding Groove Measurements for Robotic Welding Appli...
Vision-Based System for Welding Groove Measurements for Robotic Welding Appli...Vision-Based System for Welding Groove Measurements for Robotic Welding Appli...
Vision-Based System for Welding Groove Measurements for Robotic Welding Appli...
 
Simpósio Unicruz: OpenCV + Python (parte 1)
Simpósio Unicruz: OpenCV + Python (parte 1)Simpósio Unicruz: OpenCV + Python (parte 1)
Simpósio Unicruz: OpenCV + Python (parte 1)
 
Welding Groove Mapping: Image Acquisition and Processing on Shiny Surfaces - ...
Welding Groove Mapping: Image Acquisition and Processing on Shiny Surfaces - ...Welding Groove Mapping: Image Acquisition and Processing on Shiny Surfaces - ...
Welding Groove Mapping: Image Acquisition and Processing on Shiny Surfaces - ...
 
Automated control module based on VBM for shipyard welding applications: Stud...
Automated control module based on VBM for shipyard welding applications: Stud...Automated control module based on VBM for shipyard welding applications: Stud...
Automated control module based on VBM for shipyard welding applications: Stud...
 
An Unconstrained Dataset for Non-stationary Video Based Fire Detection
An Unconstrained Dataset for Non-stationary Video Based Fire DetectionAn Unconstrained Dataset for Non-stationary Video Based Fire Detection
An Unconstrained Dataset for Non-stationary Video Based Fire Detection
 
Introdução ao processamento de imagens com OpenCV (cont)
Introdução ao processamento de imagens com OpenCV (cont)Introdução ao processamento de imagens com OpenCV (cont)
Introdução ao processamento de imagens com OpenCV (cont)
 
Introdução OpenCV (Pt-Br) com exemplos
Introdução OpenCV (Pt-Br) com exemplosIntrodução OpenCV (Pt-Br) com exemplos
Introdução OpenCV (Pt-Br) com exemplos
 
Um Sistema De Detecção De Fogo Baseado Em Vídeo
Um Sistema De Detecção De Fogo Baseado Em VídeoUm Sistema De Detecção De Fogo Baseado Em Vídeo
Um Sistema De Detecção De Fogo Baseado Em Vídeo
 
Um sistema de detecção de chamas utilizando RF e SVM (Short Version)
Um sistema de detecção de chamas utilizando RF e SVM (Short Version)Um sistema de detecção de chamas utilizando RF e SVM (Short Version)
Um sistema de detecção de chamas utilizando RF e SVM (Short Version)
 
G xserver curso-actualizgxxev1
G xserver curso-actualizgxxev1G xserver curso-actualizgxxev1
G xserver curso-actualizgxxev1
 

Web panels: filtros e atualização automática

  • 1. 330
  • 2. Os elementos das web panels são: Web Form: Cada web panel contem um form Web, o qual deve ser desenhado pelo analista agregando variáveis, atributos, assim como outros controles, para que o usuário possa interagir com o mesmo. Regras: As regras de uma web panel permitem definir certos comportamentos pontuais de dito objeto. Por exemplo, declarar quais parâmetros recebe, definir quais va is não queremos que sejam aceitas no form mas utilizadas para mostrar informação, etc. Condições: É para definir as condições que devem cumprir os dados a ser recuperados (filtros). Subrotinas: São rotinas locais na web panel. Eventos: As web panels empregam a programação orientada a eventos. Este tipo de programação permite definir c digo ocioso, que se ativa em resposta a certas ações provocadas pelo usuário ou pelo sistema. Nesta seção de uma web panel é onde se define o c digo ocioso associado aos eventos que podem ocorrer durante a execução da web panel. Propriedades: São caracter sticas a serem configuradas para definir certos detalhes referentes ao comportamento geral da web panel. Ajuda: Permite a inclusão de texto de ajuda, que os usuários podem consultar em tempo de execução da web panel. Documentação: Permite a inclusão de texto t cnico como documentação para os desenvolvedores.
  • 3. No exemplo, a web panel contem duas variáveis &StartDate e &EndDate como se mostra acima. Em tempo de execução, o usuário pode ingressar valores nas variáveis &StartDate e &EndDate visto que nas web panels as variáveis por default são de entrada. No evento Enter da web panel (associado ao botão Billing Generation), se obtêm e gravam as faturas cujas datas se encontrem na faixa especificada. De modo que a definição desta web panel é para que o usuário ingresse a faixa de datas, e ao selecionar o botão Billing Generation, se execute o processamento das faturas.
  • 4. A web panel mostrada acima foi criada para exibir os dados de um cliente. Precisa ser chamada a partir de outro objeto, passando por parâmetro o código do cliente do qual se quer mostrar a informação. Uma web panel é um objeto tipicamente utilizado para mostrar informação. Então, quando GeneXus encontra atributos no form, qual intenção do programador ao ter colocado isso? Pois, o que está pedindo implicitamente é que se busque os dados correspondentes a base de dados para mostrá-los. Com a web panel anterior, GeneXus vai a tabela CUSTOMER e filtra pelo atributo recebido por parâmetro, CustomerId, mostrará a informação do registro encontrado. Que informação? A que reside nos atributos que figuram no form. Mas o atributo CountryName não se encontra na tabela CUSTOMER. Pois acontece o mesmo que com um for each, um grupo de grupo de Data Providers, etc., isto é, desde o registro da tabela base, se acessa o registro relacionado da tabela estendida necessária, para obter o valor do atributo requerido (em nosso caso acessa a tabela COUNTRY para recuperar o valor de CountryName). As inferências que GeneXus realiza são as seguintes: Ao se tratar de uma web panel, os atributos que figurem serão de consulta1. Então GeneXus deve acessar a base de dados para recuperar seus valores. De quais tabelas? Vai depender se a Web panel possui grids ou não: • Web panel plana (sem grid): os atributos estão “soltos” no form, como no caso que estamos mostrando. Se isso acontece, é porque o analista necessita acessar a informação de um registro de uma tabela (e eventualmente dos registros relacionados pela tabela estendida), como é o caso do exemplo. Neste caso, a web panel estará bem programada se além disso se agregar um filtro que determine “esse” registro a ser mostrado. Em nosso caso, temos a regra parm que ao receber no atributo PK da tabela somente vai recuperar um registro. GeneXus determina uma tabela base da web panel, assim como faz para um for each. Como? Buscando a mínima tabela estendida que contenha os atributos.. • Web panel com um ou mais grids: veremos em seguida, mas já podemos pensar... Qual o sentido de colocar um grid? Mostrar informação repetitiva. No caso geral: cada grid mostra muitos registros de uma tabela (e sua informação associada). ____________________________________________________________________________________________1 Ao contrário do que acontece com os atributos nas transações (exceto os inferidos ou os que tem regra noaccept ou propriedade Enabled desabilitada).
  • 5. O que diferencia está web panel da anterior é que ela não é plana. Quando se incluiu um grid num form, se está indicando que vai mostrar uma quantidade indefinida de dados (neste caso, clientes). Visto que nesta web panel tem envolvidos atributos, GeneXus infere que deseja acessar a base de dados. Simplesmente dizendo quais atributos deseja mostrar, sem necessidade de mais informação. Existe um grid, tem atributos, então, necessariamente terá tabela base, isto é, a tabela da base de dados navegada em busca da informação requerida. Se ao invés de mostra esta informação em tela, quisermos uma listagem, vamos criar um procedimento com um print block ‘customer’ com os atributos CustomerName e CountryName e no source programaríamos: for each print customer endfor Isto é a análogo, somente que o for each está implícito, não tem que especificá-lo. Cada linha do grid que se carrega, é como o print que se executa em cada iteração do for each da listagem. Das tabelas CUSTOMER e COUNTRY e da relação entre ambas é Na1, GeneXus determina a tabela base desta web panel (sendo que a tabela base seja a mínima que contenha todos os atributos referidos). Observe que este exemplo difere do anterior, que os atributos aparecem num grid, e portanto, não precisa ser realizado o filtro, fica somente registros de CUSTOMER. Nesta web panel não tem a regra parm que estabeleça filtro algum. Também vamos ver que conseguimos que esta web panel além de mostrar os clientes da base de dados no grid, podem realizar filtros para os clientes que se quer ver em cada oportunidade, seja por nome do cliente, endereço ou por ambos. Por isso as variáveis aparecem no form.
  • 6. 335 Quando GeneXus pode determinar automaticamente uma tabela para carregar as linhas do grid, o faz, e nesse caso não precisa dessa informação. É por isso que falamos que nesse caso tem um for each ‘implícito’. Depois veremos casos em que isso não acontece (grids sem tabela base). Observe o exemplo, existindo 4 registros na tabela, são carregados um de cada vez, um a um dos quatro. Se agora queremos que o usuário possa filtrar os clientes que deseja ver...entra em questão as variáveis que definimos na parte fixa do form, como veremos na página seguinte.
  • 7. 336 Observe como na janela de propriedade do control Grid, aparece un de nome ‘Conditions’. Clicando no combo abre um editor para especificar as condições booleanas que devem cumprir os registros para ser carregados como linhas do grid. É por essa razão que foi agregado as variáveis &CustomerName e &CountryName no form da web panel, para que o usuário possa ingressar ali valores que operem como filtros sobre os dados a mostrar. Em nosso caso, estabelecemos filtros com o operador like. As variáveis na parte plana do form de web panels são por default de entrada. Depois veremos que se estiverem em grids são por default de saída. Observe que as condições (separadas com “;”) equivalem as que apareciam nas cláusulas where de um for each (ou grupo repetitivo de data provider). Da mesma maneira, por questões de otimização, pode determinar, igual se fazia com um for each, critério de ordenação da tabela percorrida, como se mostra acima no exemplo. Nota: Assim mesmo, da mesma forma que num procedimento, as condições locais podem ser realizadas no grid (for each), mas também podem ser gerais, mediante o selector Conditions. Isto tem sentido quando tiver mais de um grid (for each), para não ter que repetir cada vez a mesma condição.
  • 8. 337 A propriedade Automatic Refresh que se encontra a nível da Web Panel pode ter os seguintes valores: • When variables in conditions change (valor por default): depois de chamar automaticamente o refresh, se dispara o evento Load carregando o grid segundo os novos valores das variáveis. • No Dependendo do tipo de dados do filtro, e do control web utilizado para filtrar, a condição será aplicada quando se está digitando ou ao abandonar o campo. No caso de filtros em controles edit, para tipo de dados Character, são aplicados quando o usuário vai digitando. Para tipo de dados Date, DateTime e Numeric, as condições são avaliadas ao sair do campo. No caso de filtros combo boxes ou dynamic combos, as condições são avaliadas quando se abandona o campo. Para Check boxes e Radio buttons, as condições são avaliadas quando o valor é alterado. Execução: o que acontece no cliente e no servidor ao ter a propriedade por default e um grid com tabela base? 1ª execução (variáveis vazias): For each CUSTOMER guardar em memória CustomerName acessar o registro de COUNTRY relacionado guardar em memória CountryName carregar (load) linha no grid com ambos valores N-ésima execução (altera o valor da variável das conditions): Automaticamente no browser do cliente se detecta a mudança refresh no servidor para voltar a carregar o grid com os registros que cumpram as condições (com os novos valores das variáveis) load para cada linha. Conclusão: Existem dois eventos do sistema que ocorrem no momento da carga do form (Refresh) e da carga de cada linha do grid (Load). Como veremos, estes eventos podem ter códigos associados para serem executados nos momentos específicos...
  • 9. 338 Ampliaremos a funcionalidade de nossa web panel, permitindo ver o estado de cada cliente, e para aqueles que estiverem ‘On Hold’, brindando a possibilidade de os passar para o estado ‘Active’. Para fazer isto, agregaremos ao grid o atributo CustomerStatus que mostra o estado, e uma variável booleana &Select, que permitirá ao usuário selecionar aqueles clientes que deseja ‘ativar’. Além disso um botão para efetivamente ativar todos os clientes marcados. Mas isto o faremos num segundo momento. Observe que se o tipo de dados da variável &select booleano, por default aparece no grid como um check box. Para assegurar que o usuário somente tente ‘ativar’ clientes ‘On Hold’, desejamos que somente apareça habilitado este check box quando corresponde... para ele necessitaremos programar a carga de cada linha, isto é, o evento Load...
  • 10. 339 Na seção Events da web panel, programamos o evento Load do grid que vemos acima. No exemplo, customerGrid é o nome que demos ao control grid no form. Ao se tratar de uma web panel com um único grid, também poderíamos ter programado o evento Load: Event Load if CustomerStatus = Status.OnHold &select.Enabled = 1 else &select.Enabled = 0 endif endevent Isto é, no caso de uma web panel com um único grid, não é necessário qualificar o evento com o nome do grid. Igualmente recomendamos fazer, antecipando a possibilidade futura de agregar outro grid no form da web panel. O evento Load é disparado para cada linha que vai carregar no grid, encontrando este comando ou não. O que fazemos no exemplo é aproveitar este momento imediatamente anterior a carga, para efetuar uma ação. E esse é o código que incluímos no evento. Agora sim, estamos em condições de implementar a ‘activate’, para isso precisamos associar ao botão um evento, que poderá ser o evento Enter ou um de usuário...
  • 11. 340 No exemplo, quando o usuário pressiona o botão ‘Confirm’, necessitamos percorrer todas as linhas do grid, e para cada uma delas, se o usuário marcou a variável boleana &Select f (check box), devemos alterar o estado do cliente correspondetne, de ‘On Hold’ a ‘Active’. Ao inserir o botão no form da web panel, e editar suas propriedades, por default se pode observar que o botao esta associado ao evento Enter (ver propiedad OnClickEvent). O Entrr será um evento do sistema, executado quando o usuário faz clique no controle associado, assim como quando ele pressiona a tecla Enter. Neste exemplo veremos na 1a vez: • Possibilidade de definir eventos de usuário e associar os controles ou utilizar o evento Enter do sistema. • Comando For each line, para percorrer as linhas já carregadas no grid. • Variáveis num grid passam a ser Read only (de saída) por default, a serem de entrada, quando é utilizado um comando for each line nesse grid (também quando é programado os eventos OnClickEvent, Click, etc., em alguma coluna do grid). Observe que a única coisa em comum no comando For each line e comando For each estudado antes, o fato de representar um estrutura repetitiva. A diferença mais importante: enquanto o for each percorre registros de uma tabela (base) da base de dados, o for each line percorre as linhas de um grid. Em nosso exemplo definimos uma variável &customer, Business Component Customer, trocaremos o estado para ‘Active’ de todas as linhas do grid que o usuário marcou. Para isso utilizamos o comando for each line para percorremos o grid.
  • 12. 341 Outra possibilidade, ao invés de utilizar o evento do sistema Enter, é definir um evento de usuário. Isso é realizado seguindo os passos que estão acima. Como podemos ver, a maioria dos controles presentes em um form tem a propriedade OnClickEvent associada. Essa propriedade permite especificar um evento a ser disparado quando o usuário faz clique sobre o controle. Poderá ser um evento do sistema (Refresh, Enter) ou um evento definido pelo usuário.
  • 13. 342 A parte fixa da web panel por default é de entrada, como já vimos anteriormente para as variáveis utilizadas para filtrar os clientes (customers) mostrados no grid. Como mostrar dados no grid Por default todo atributo e variável que está dentro de um grid se mostra em execução como texto, porque é unicamente de leitura e por consequencia não pode ser alterado. Como aceitar dados em um grid É possível aceitar dados nas variáveis de um grid dependendo da programação dos eventos existentes no objeto: 1. Se dentro de um evento da web panel ter o comando For each line, todas as variáveis que estão dentro do grid passam a ser de entrada. É possível indicar neste caso quais são as variáveis que não podem ser modificadas através da propriedade ReadOnly. 2. Se dentro da fila tem algum controle com um evento click, dblClick, etc.. associado (ou evento de usuário especificado na propriedade OnClickEvent), acontecerá o mesmo.
  • 14. 343 Continuamos ampliando nosso exemplo; agora queremos que o usuário possa selecionar uma linha do grid (um cliente) e pressionando botão ‘Select customer’ para chamar a web panel que havíamos implementado anteriormente. Neste exemplo vemos duas funcionalidades: • A necessidade de colocar uma coluna no grid oculta (não visível). • Permitir que o usuário selecione uma linha do grid para fazer algo com ela. Por que colocar a coluna correspondente a CustomerId e ocultá-la, ao invés de não agregar o atributo? Faça a seguinte reflexão: o atributo CustomerId enviado por parâmetro ao executar o evento ‘Select customer’, de onde é extraído? Da base de dados? Não, é o que está carregado no grid. Mais especificamente, para cada grid existirá um arquivo temporário que contem a quantidade de colunas que o grid possuir, visíveis e ocultas. Quando o usuário seleciona no grid a segunda linha, e pressiona o botão ‘Select customer’, está posicionado nesse arquivo temporário, correspondente a essa linha (e nunca na base de dados!). É por esta razão que se não colocarmos nenhuma coluna correspondente a CustomerId no grid, não estaríamos passando valor algum a CustomerView. Para que o usuário possa selecionar uma linha do grid, é suficiente ‘prender’ a propriedade ‘AllowSelection’ do grid.
  • 15. 344 Como GeneXus determina uma tabela base para percorrer automaticamente para carregar o grid da web panel? Se existir algum atributo em pelo menos um dos 3 lugares mencionados, GeneXus poderá encontrar a tabela base. Para determinar a tabela base, ele extrai os atributos encontrados ali (parte fixa do Form, no Grid, tanto nas colunas como nas propriedades Order, Conditions ou using Data Selector, e nos eventos programa programados no selector de Eventos, somente os atributos que estejam ‘soltos’ dentro do evento, isto é, fora de um comando for each de acesso a base de dados), e determina a mínima tabela estendida que os contenha. A tabela base dessa estendida, será a percorrida automaticamente e carregada com o Load. Observe que somente programamos o evento Load para tomar a decisão para cada línea que vai ser carregada no grid, que habilitará ou não para a mesma variável &select que permitirá ao usuário marcar o check box. Importante: A forma de determinação da tabela base de um grid dependerá se existir outro grid na web panel ou se é o único. O resumo apresentado aqui corresponde a um único grid. Neste caso se diz que a própria Web panel tem tabela base. É a do grid. Quando existir mais de um grid na web panel, isto não vai ter sentido, e cada grid passará a ter cada grid passará a ter ou não tabela base. Veremos a forma de determinação das tabelas bases nesse caso, quando tratemos o caso de múltiplos grids em uma web panel.
  • 16. 345 Estamos apresentando aqui outro exemplo, para que possamos observar um caso que surge a necessidade natural de implementar um grid sem tabela base. O caso de implementação natural de um grid com tabela base, é quando deseja que seja carregado para cada registro de uma tabela, uma linha do grid (1 registro – 1 linha). No caso que se quer carregar uma linha do grid como produto a ser lido de vários registros da base de dados (N registros – 1 linha), como produtos de cálculos, etc., é mais natural implementar o grid sem tabela base. O caso do exemplo: não queremos carregar para cada fatura uma linha, mas sim queremos agrupar as faturas por data, e para cada grupo, carregar uma linha que some seus valores. Estamos falando de um controle de corte. Se tivéssemos que implementar uma listagem PDF ao invés de uma web panel, saberíamos como programar (como o fazemos acima) . Vejamos como implementar com uma web panel...
  • 17. 346 O objetivo do comando LOAD é agregar um linha num grid. É necessário quando o grid não tem tabela base, visto que nesse caso não será agregado nenhuma linha de forma automática. O evento Load vai ocorrer uma vez, e o grid retornará vazio caso não seja programado. Portanto neste caso é imprescindível que seja programado, de acordo com a lógica correspondente. Uma vez que for atribuído a cada variável seu valor, e se deseja agredar uma linha ao grid, o comando LOAD deverá ser programado. O comando LOAD somente pode ser especificado dentro do evento Load do grid de uma web panel. Observe que neste caso a implementação fica por conta do analista. Frente ao caso do grid com tabela base, neste GeneXus realiza menos inferências.
  • 18. 347 No caso de um grid sem tabela base, os filtros dos dados são programados dentro do código implementado para carga (o do Load). Aqui não tem o refresh automático. Isto é, quando o usuário modifica os valores das variáveis que intervém nos filtros, GeneXus não sabe que tem que voltar a carregar o grid. Para isso deverá, por exemplo, agregar um botão associado ao evento Enter, ou a um evento de usuário, sem código, devido ao fato que somente precisamos dele para que um Refresh seja realizado, ou seja, para que o servidor volte a carregar a web panel. Sobre os eventos disponíveis e a ordem em que são disparados, estudaremos em seguida.
  • 19. 348 Em toda Web panel existem eventos do sistema que podem ser programados. Alguns ocorrem sempre, em cada execução da web panel (como o Start, Refresh, Load), outros se forem declarados e o usuários realiza as ações necessárias para provocá-los (Enter, definidos pelo usuário, TrackContext). Assim mesmo, quase todos os controles que aparecem no form brindam a possibilidade de disparar um evento quanto o usuário faz clic com o mouse (os hiper-links aparecem em execução); de duas maneiras diferentes: 1. Editando as propriedades do controle (F4), e definindo um evento de usuário na propriedade OnClickEvent, ou associando o evento Enter ou o Refresh. 2. Dando um nome ao controle e na seção de Eventos programando: Event nomeControl.click … Endevent Com esta última alternativa não teremos que definir um evento de usuário, mas sim teremos que programar o evento click do controle. O mesmo ocorre com os eventos DblClick, RightClick, IsValid... (quando fizer duplo clique, botão direito, etc.). Sobre os eventos associados as ações sobre os controles (click, dblclick, drag, drop, etc.) não veremos no curso presente. Em nosso wiki tem informação detalhada, assim como no Help de GeneXus. Sobre o evento TrackContext somente mencionaremos que é possível detectar mudanças no valor de um dado controle (grid, variável, etc.) e nesse caso disparar este evento baseado ao valor modificado, tomar uma ação.
  • 20.
  • 21. 350 Quando a web panel é com tabela base, ao produzir-se o evento Refresh se acessa a base de dados, a essa tabela base (associada a web panel), e se percorre carregando os registros que cumpram as condições (conditions do grid e gerais). Vai ocorrer nesse processo um evento Load para cada registro em que estiver posicionado, imediatamente antes de carregá-lo. Isto nos permite realizar alguma operação que requeira desse registro ( e de sua estendida), antes de efetivamente carregá-lo no grid. Imediatamente depois de executado o código associado ao evento Load, será carregado a linha do grid e o ponteiro é passado ao seguinte registro da tabela base, para realizar o mesmo (evento Load, carga da linha). Este processo se repetirá até carregar todas as linhas do grid. Se uma web panel é sem tabela base, GeneXus não pode determinar automaticamente uma tabela da base de dados a percorrer para mostrar a informação que se apresenta no form. Neste caso no form somente aparecem variáveis (e não atributos) e também vão ocorrer os eventos Refresh e Load, somente que o evento Load é executado uma única vez, visto que não estará posicionado em nenhum registro de nenhuma tabela. Dentro desse evento a carga terá que ser codificada, que pode ser que precise acessar a base de dados (ex: comando for each) o não (vamos supor que seq queira carregar o grid com informação obtida ao percorrer um SDT collection, efetuar alguma transformação sobre seus itens ... ou carregar linhas no grid produto de cálculos). O controle da carga do grid, neste caso fica nas mãos do analista, utilizando o comando Load. Este comando somente é válido dentro do evento com o mesmo nome. Note como no caso do grid com tabela base, este comando não é necessário.
  • 22. 351 A propriedade Automatic Refresh que se encontra a nível da Web Panel pode tomar os seguintes valores: • When variáveis in conditions change (valor por default): automaticamente provocam o refresh, se dispara o evento Load carregando-se o grid segundo os novos valores das variáveis. • No: para que o conteúdo do grid se renove depois de alterar os filtros, o usuário deve realizar uma ação: Se o grid é com tabela base: • As alterações nas variáveis dos filtros se detectam automaticamente. • Ao pressionar a tecla Enter, se dispara o Refresh da página (não o código do evento Enter, ainda que esteja programado). • Ao fazer click num botão ou numa imagem associados a um evento de usuário, imediatamente depois de alterar o valor de uma variável das conditions do grid, se executa este evento e atualiza imediatamente depois a página. Se o evento for o Enter, este evento NÃO se executa. Se o grid é sem tabela base: • As alterações nas variáveis dos filtros NÃO se detectam automaticamente • O usuário deve fazer click no botão ou na imagem associados a um evento Refresh ou a um evento de usuário que chame um Refresh.
  • 23. 352 Os eventos disparados e sua ordem depende se a web panel está sendo aberta (Get) ou se já estava aberta e está efetuando uma ação posterior a um botão (Post). Acima mostramos com exemplos o caso geral. 1a. vez: Start + Refresh + Load N-ésima vez: Start + Leitura de variáveis da tela + Evento que produziu o Post + Refresh + Load. Este é o caso geral... existe uma exceção...
  • 24. 353 Internamente GeneXus determina as entradas e saídas de cada evento. Se em suas entradas, se requerem que ações sejam executadas no Server, então o evento é executado no Server. Por exemplo, se entre as entradas de um evento de usuário X, se encontra alguma das saídas do evento Start (do server), então o evento de usuário é executado no Server. Se o código do evento não requer que seja executado no servidor, então por performance, será executado no cliente, como código javascript. De todas as maneiras o analista GeneXus não deve se preocupar com estes assuntos, visto que em todo caso será o GeneXus que terá a inteligência de resolver onde vai executar o evento.
  • 25. 354 Aqui apresentaremos um exemplo que reúne os dois casos que viemos estudando: a web panel mostrada em execução tem dois grids paralelos: um que mostra informação dos clientes do sistema, e outro que mostra faturas, totalizadas por dia. No nosso caso, queremos além disso relacionar os dados, de tal maneira que quando o usuário seleciona um cliente, sejam mostradas somente as faturas desse cliente. Incluso ao estabelecer filtros de datas, também queremos que vá para o cliente selecionado (e não para todos os clientes). Quando uma web panel contem mais de um grid em seu form, GeneXus não determina uma única tabela base associada para web panel, mas sim uma tabela base associada a cada grid. Atributos que participam na determinação da tabela base de cada grid: • Os incluídos no grid (são levados em consideração os atributos visíveis como os não visíveis, ocultos/hidden) • Os referenciados na Order e Conditions locais do grid A diferença do que acontecia para uma web panel com somente um grid, no caso de múltiplos grids os atributos da parte fixa da web panel não participam na determinação da tabela base de nenhum deles, mas deverão pertencer a tabela estendida de algum (para que seja possível inferir seus valores).Caso isso não seja respeitado, ao especificar a web panel, se mostra na listagem de navegação resultante, um warning advertindo desta situação. Os atributos utilizados nos eventos da web panel tampouco participam na determinação da tabela base de nenhum dos grids. Os atributos que se inclui nos eventos fora de comandos for each, deverão pertencer a tabela estendida de algum dos grids (da mesma forma como da parte fixa).
  • 26. 355 Esta web panel poderia ter sido implementada de diferentes formas e obtendo o mesmo resultado na execução. Acima podemos ver a implementação mais natural: o primeiro grid tem tabela base e o segundo não tem. Mas poderia ter sido implementada de forma contrária, com variáveis no primeiro grid e tendo que realizar a carga dos clientes a mão no Load, e atributos no segundo grid, e algumas coisas a mais para obter o controle de corte, sendo um grid com tabela base. Ou qualquer combinação (ambos grids com tabela base, ou nenhum com tabela base). O importante é, uma vez escolhida a implementação mais natural ao caso, realizá-la corretamente. Em qualquer dos casos, ainda que a informação a ser carregada em mais de um grid se encontre relacionada na base de dados, GeneXus não assume nenhuma relação entre os dados na hora de carregar um grid e o outro. É análogo o caso de um par de for eachs paralelos no Source de um procedimento. Acima podemos ver a web panel que temos o grid com os grids, agregamos a parte de visualização de faturas por data que implementamos na web panel. Mas não basta simplesmente unir as duas web panels... para poder relacionar as cargas dos grids, a lógica deve ser agregada. Em nosso caso desejamos que uma vez que selecionarmos um cliente do primeiro grid, certa lógica precisa ser agregada. Em nosso caso desejamos que uma vez um cliente for selecionado no primeiro grid, as faturas carregadas no segundo grid não sejam de todos os clientes, mas somente do selecionado. Para isso devemos ter duas coisas: agregar uma variável &CustomerId para armazenar o id do cliente selecionado ao pressionar ‘Select customer’, e depois agregar um filtro pelo valor dessa variável quando se carrega o grid de Invoices. Assim mesmo precisa obrigatoriamente colocar essa variável no form para que tudo funcione corretamente ... como esperamos... e na análise abaixo encontraremos a razão.
  • 27. 356 Vamos analisar o que acontece quando a web panel é executada pela primeira vez. Primeiro o evento Start é executado, em nosso caso a variável &CustomerId é ocultada. Podemos ver na imagem, que um evento Refresh genérico é produzido, depois serão produzidos as cargas de todos e cada um dos grids encontrados na web panel, da esquerda para a direita de cima para baixo. Um evento Refresh próprio ocorre e o evento Load (se possuir tabela base são N vezes e se não tiver tabela base somente 1 vez). Observe que nosso caso, o grid de cliente tem condições para serem carregadas, pelas variáveis de filtro &customerName e &countryName, não são aplicadas se estiverem vazias (visto que ambas cláusulas condicionais tem when not &var.IsEmpty()) O segundo grid é sem tabela base, mas como já vimos, o evento Load era executado um for each com cláusulas where, serão carregadas somente aquelas linhas que as condições são cumpridas. São três: where InvoiceDate >= &startDate when not &startDate.IsEmpty() where InvoiceDate <= &endDate when not &endDate.IsEmpty() where CustomerId = &customerId when not &customerId.IsEmpty() Observe que nesta primeira execução &customerId está vazio, o filtro não é aplicado e todas as faturas do dia é carregada, de todos os clientes.
  • 28. 357 O usuário seleciona o cliente do grid o cliente correspondente da linha e pressiona o botão ‘Select customer’. Uma ação é detectada e ocorre um post ao servidor, quem executa o Start (ocultando a variável), depois as variáveis da tela são lidas (&customerId no momento está vazia, são consideradas não somente as variáveis da tela, as que são definidas, mas também a informação completa da linha selecionada pelo usuário com o mouse, entre ela, o valor de CustomerId, coluna do grid), depois o código do evento que produziu o post é executado, no nosso caso, ‘Select customer’. Aqui a variável &customerId toma o valor do CustomerId da linha escolhida. Depois ocorre o evento Refresh geral que dispara o Refresh e Load de cada grid. Portanto, cada grid é executado executando as conditions. O primeiro se carregado como antes, porque nenhuma de suas conditions variou. O segundo, agora se tiver um valor para &customerId, somente será mostrado as faturas do cliente. Você poderia se perguntar porque precise colocar a variável oculta no form. Simplesmente porque não se pode usar como variável dentro do programa, se não estiver no form e torná-la invisível. Todavia com esta segunda execução não podemos responder a pergunta. De fato, se analisarmos, pode ser visto facilmente que teríamos o mesmo comportamento se somente fosse atribuído valor a variável no ‘Select Customer’ sem colocá-la no form. Vamos ver o motivo com a execução seguinte....
  • 29. 358 Agora o usuário já selecionou o segundo cliente, e o que deseja fazer é filtrar suas faturas por data (não quer visualizar todas). Para isso especifica os filtros de data, e pressiona o botão ‘Search’, que produzirá um post no servidor. Então o código do Start é executado, depois são lidas as variáveis da tela: aqui está o motivo de ter colocado &customerId no form. O valor de &customerId é lido, permanecendo até que o usuário não selecione outro cliente do grid e pressionar o botão ‘Select customer’... esta variável presente no form, é a forma de manter a memória em execuções. Lembre que cada vez que se faz um post ao servidor, é uma nova execução da web panel, já que as variáveis começam novamente vazias. Por isso que o segundo passo: “Leitura de variáveis da tela” é fundamental. Agora sim, seguindo o exemplo, as variáveis da tela são lidas &customerId invisível (visible=0), junto com as variáveis &startDate e &endDate. E depois, como sempre, a carga é executada (Refresh genérico + Refresh e Load de cada grid). Alterando as condições do for each que carrega o segundo grid, agora aparece somente as faturas do segundo cliente, entre as datas estipuladas pelo usuário. Se agora o usuário quiser alterar o cliente, para ver suas faturas, será feito a seleção no grid de clientes e ao pressionar ‘Select Customer’, o processo começa novamente como vimos na 2da. execução. E como fazemos para voltar a trabalhar com as faturas de todos os clientes e não de um? O que acontece se o usuário não selecionar nenhum cliente do grid com o mouse e pressionar ‘Select Customer’. O valor da variável &CustomerId fica vazio, pois CustomerId não vai ter valor. Por este motivo, o botão ‘Select Customer’ poderíamos chamar ‘Select/Unselect’.
  • 30. 359 Os botões inseridos dependem da quantidade de registros e da quantidade de linhas do grid.
  • 31. 360
  • 32. 361 Dois tipos de grid: • Grid padrão: que vimos até agora, em Transações e Web Panels • Grid Free Style Estes grids, agregam potência ao desenho de aplicações web, permitindo ao desenvolvedor maior liberdade na hora do desenho. O grid Free Style permite ao usuário definir o formato dos dados a serem mostrados de uma forma menos estruturada que o grid padrão. O grid Freestyle é basicamente uma tabela que podem inserir os atributos/variáveis, text blocks, imagens, botões, web components, embedded pages, grids freestyle e/ou grids que serão mostrados posteriormente na tela. Neste caso para poder visualizar as propriedades tem que selecionar a tabela onde se encontram os atributos/variáveis. No exemplo apresentado acima queremos mostrar alguma informação dos países. O atributo CountryFlag foi incluído na transação “Country” para armazenar a foto da bandeira de cada país (é um atributo de tipo Blob). Mas não queremos mostrar a informação como o faríamos em um grid padrão, cada elemento de informação em uma coluna diferente do grid. Aqui queremos mostrar a foto e abaixo o identificador e nome do país. O comportamento das variáveis dentro de um grid Free Style é análogo ao apresentado dentro de um grid padrão, portanto também são de ingresso se existe um For each line ou For each line in <grid> dentro de algum evento, ou se associa um evento a qualquer controle da fila. Novamente este comportamento pode ser modificado, agregando a regra noaccept ou alterando a propriedade Read Only.
  • 33. 362 Este caso de grids aninhados é igual o de for each aninhados em um procedimento: ou seja, aqui as cargas estão relacionadas, e no Grid2 é carregado todos os clientes pertencentes ao país carregado no Grid1. A ordem de execução dos eventos estará aninhada: Refresh (genérico) Grid1.Refresh Grid1.Load carga de um país Grid2.Refresh Grid2.Load carga de cliente do país Grid2.Load carga de cliente do país Grid2.Load carga de cliente do país Grid1.Load carga do país seguinte Grid2.Refresh Grid2.Load carga de cliente do país Grid2.Load carga de cliente do país Grid2.Load carga de cliente do país .....
  • 34. 363
  • 35. 364 Os objetos web podem ser definidos com três tipos diferentes, configurável na propriedade Type do objeto. Para uma web panel poderá ter um dos valores: • Component: (transação ou web panel, que a partir daqui poderá ser incluído em outro web object) • Web Page (isto é, o objeto será uma transação ou web panel tal como temos trabalhado até o momento) • Master Page Em seguida introduziremos a Web Panel tipo: Component”, “Master Page” e sua utilização.
  • 36. 365
  • 37. 366
  • 38. 367
  • 39. 368
  • 40. 369 Ter um look&feel consistente é hoje em dia um dever de toda aplicação Web. Criar e manter cada página de uma aplicação Web assegurando a consistência com o resto do site leva grande tempo de programação. Ao criar uma base de conhecimento GeneXus X criará também dois objetos de tipo Mastet Page: • ApplMasterPage: Para a aplicação • PromptMasterPage: Para os prompts Uma web panel, AppMasterPager categorizado como “Master Page” será criada com tudo, ou seja, o Layout e comportamento comum a todas as páginas do site, e no mesmo se deixa um espaço para carregar a página correspondente (o conteúdo variável do site). Corresponde ao controle especial ContentPlaceholder. As páginas web que implementam o conteúdo variável, se implementam como Web Panels ou Web Transactions comuns e correntes (é do tipo “Web Page”, ver página anterior), e se associam a Master Page, de maneira que cada vez que se executem, são carregadas com esse “contexto”. Agora faça o seguinte, abra qualquer objeto GeneXus com form (transação ou web panel) criada na KB, e veja o valor da propriedade Master Page. As Master Pages fornecem uma forma de centralizar o layout e o comportamento comum em somente um objeto e reutilizá-lo em todo outro objeto sem ter que programar. Isto significa que a modificação de alguma parte do layout ou do comportamento comum é tão fácil como modificá-la num único objeto e pronto!. Numa mesma base de conhecimento podem ser definidas tantas Master Pages quanto desejar.