330
Os elementos das web panels são:
Web Form: Cada web panel contem um form Web, o qual deve ser desenhado pelo analista agre...
No exemplo, a web panel contem duas variáveis &StartDate e &EndDate como se mostra acima. Em tempo de
execução, o usuário ...
A web panel mostrada acima foi criada para exibir os dados de um cliente. Precisa ser chamada a partir de outro objeto,
pa...
O que diferencia está web panel da anterior é que ela não é plana.
Quando se incluiu um grid num form, se está indicando q...
335
Quando GeneXus pode determinar automaticamente uma tabela para carregar as linhas do grid, o faz, e nesse
caso não pre...
336
Observe como na janela de propriedade do control Grid, aparece un de nome ‘Conditions’. Clicando no combo
abre um edit...
337
A propriedade Automatic Refresh que se encontra a nível da Web Panel pode ter os seguintes valores:
• When variables i...
338
Ampliaremos a funcionalidade de nossa web panel, permitindo ver o estado de cada cliente, e para aqueles
que estiverem...
339
Na seção Events da web panel, programamos o evento Load do grid que vemos acima. No exemplo,
customerGrid é o nome que...
340
No exemplo, quando o usuário pressiona o botão ‘Confirm’, necessitamos percorrer todas as linhas do grid, e
para cada ...
341
Outra possibilidade, ao invés de utilizar o evento do sistema Enter, é definir um evento de usuário. Isso é
realizado ...
342
A parte fixa da web panel por default é de entrada, como já vimos anteriormente para as variáveis utilizadas
para filt...
343
Continuamos ampliando nosso exemplo; agora queremos que o usuário possa selecionar uma linha do grid
(um cliente) e pr...
344
Como GeneXus determina uma tabela base para percorrer automaticamente para carregar o grid da web
panel?
Se existir al...
345
Estamos apresentando aqui outro exemplo, para que possamos observar um caso que surge a necessidade
natural de impleme...
346
O objetivo do comando LOAD é agregar um linha num grid. É necessário quando o grid não tem tabela base,
visto que ness...
347
No caso de um grid sem tabela base, os filtros dos dados são programados dentro do código implementado
para carga (o d...
348
Em toda Web panel existem eventos do sistema que podem ser programados. Alguns ocorrem sempre, em
cada execução da web...
350
Quando a web panel é com tabela base, ao produzir-se o evento Refresh se acessa a base de dados, a essa
tabela base (a...
351
A propriedade Automatic Refresh que se encontra a nível da Web Panel pode tomar os seguintes valores:
• When variáveis...
352
Os eventos disparados e sua ordem depende se a web panel está sendo aberta (Get) ou se já estava aberta e
está efetuan...
353
Internamente GeneXus determina as entradas e saídas de cada evento. Se em suas entradas, se requerem
que ações sejam e...
354
Aqui apresentaremos um exemplo que reúne os dois casos que viemos estudando: a web panel mostrada em
execução tem dois...
355
Esta web panel poderia ter sido implementada de diferentes formas e obtendo o mesmo resultado na
execução.
Acima podem...
356
Vamos analisar o que acontece quando a web panel é executada pela primeira vez.
Primeiro o evento Start é executado, e...
357
O usuário seleciona o cliente do grid o cliente correspondente da linha e pressiona o botão ‘Select customer’.
Uma açã...
358
Agora o usuário já selecionou o segundo cliente, e o que deseja fazer é filtrar suas faturas por data (não quer
visual...
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, agre...
362
Este caso de grids aninhados é igual o de for each aninhados em um procedimento: ou seja, aqui as cargas
estão relacio...
363
364
Os objetos web podem ser definidos com três tipos diferentes, configurável na propriedade Type do objeto.
Para uma web...
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...
15 web panels-curso gxxbr
Próximos SlideShares
Carregando em…5
×

15 web panels-curso gxxbr

1.957 visualizações

Publicada em

0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
1.957
No SlideShare
0
A partir de incorporações
0
Número de incorporações
2
Ações
Compartilhamentos
0
Downloads
18
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

15 web panels-curso gxxbr

  1. 1. 330
  2. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 20. 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.
  21. 21. 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.
  22. 22. 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...
  23. 23. 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.
  24. 24. 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).
  25. 25. 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.
  26. 26. 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.
  27. 27. 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....
  28. 28. 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’.
  29. 29. 359 Os botões inseridos dependem da quantidade de registros e da quantidade de linhas do grid.
  30. 30. 360
  31. 31. 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.
  32. 32. 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 .....
  33. 33. 363
  34. 34. 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.
  35. 35. 365
  36. 36. 366
  37. 37. 367
  38. 38. 368
  39. 39. 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.

×