ISB007 - ZEN.pdf

291
Zen Guia do Aluno

Transcript of ISB007 - ZEN.pdf

Page 1: ISB007 - ZEN.pdf

Zen

Guia do Aluno

Page 2: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 1

Page 3: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 2

COPYRIGHT NOTICE Copyright © InterSystems Corporation

1997-2006

All rights reserved

NOTICE

PROPRIETARY — CONFIDENTIAL

This document contains trade secret and confidential information which is the property of InterSystems Corporation, One Memorial Drive, Cambridge, MA 02142, or its affiliates, and is furnished for the sole purpose of the operation and maintenance of the products of InterSystems Corporation. No part of this publication is to be used for any other purpose, and this publication is not to be reproduced, copied, disclosed, transmitted, stored in a retrieval system or translated into any human or computer language, in any form, by any means, in whole or in part, without the express prior written consent of InterSystems Corporation.

The copying, use and disposition of this document and the software programs described herein is prohibited except to the limited extent set forth in the standard software license agreement(s) of InterSystems Corporation covering such programs and related documentation. InterSystems Corporation makes no representations and warranties concerning such software programs other than those set forth in such standard software license agreement(s). In addition, the liability of InterSystems Corporation for any losses or damages relating to or arising out of the use of such software programs is limited in the manner set forth in such standard software license agreement(s).

THE FOREGOING IS A GENERAL SUMMARY OF THE RESTRICTIONS AND LIMITATIONS IMPOSED BY INTERSYSTEMS CORPORATION ON THE USE OF, AND LIABILITY ARISING FROM, ITS COMPUTER SOFTWARE. FOR COMPLETE INFORMATION REFERENCE SHOULD BE MADE TO THE STANDARD SOFTWARE LICENSE AGREEMENT(S) OF INTERSYSTEMS CORPORATION, COPIES OF WHICH WILL BE MADE AVAILABLE UPON REQUEST.

InterSystems Corporation disclaims responsibility for errors which may appear in this document, and it reserves the right, in its sole discretion and without notice, to make substitutions and modifications in the products and practices described in this document.

Caché, InterSystems Caché, Caché SQL, Caché ObjectScript, Caché Objects, ISM, MSM, DSM, and DTM are trademarks of InterSystems Corporation.

All other brand or product names used herein are trademarks or registered trademarks of their respective companies or organizations.

For Support questions about any InterSystems products, contact the InterSystems Worldwide Support Center:

Phone: US: +1 617 621-0700 Europe: +44 (0) 1753 830-077 Fax: US: +1 617 374-9391 Europe: +44 (0) 1753 861-311

Caché 2009 - Revisão 3.0 – 13/04/2010

Page 4: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 3

Page 5: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 4

Conteúdo Módulo – Introdução ..................................................................................................... 6 Visão Geral .................................................................................................................. 12 Benefícios .................................................................................................................... 16 Demo ............................................................................................................................ 22 Módulo – Cliente e Servidor ....................................................................................... 26 Módulo – Conceito de Aplicações Zen ..................................................................... 32 Módulo – Conceitos de Componentes Zen .............................................................. 40 Convenções de Nomenclaturas ................................................................................. 46 Módulo – Tabelas Zen ................................................................................................. 54 Módulo – Controles Zen ............................................................................................. 66 Módulo – Formulários Zen ......................................................................................... 90 Módulo – MVC ............................................................................................................ 102 Módulo – MVC – Exercícios Adicionais ................................................................... 118 Módulo – Zen e SVG .................................................................................................. 152 Módulo – Gráficos Zen .............................................................................................. 160 Módulo – Componentes de Navegação ................................................................... 170 Módulo – Janelas de Expansão e Popup ................................................................ 184 Módulo – Miscelânea ................................................................................................ 202 Módulo – Componentes Customizados .................................................................. 208 Módulo – Localização ............................................................................................... 218 Módulo – Programação da Aplicação ...................................................................... 226 Respostas dos Exercícios ........................................................................................ 242

Page 6: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 5

Page 7: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 6

Módulo: Introdução

Módulo: Introdução

Page 8: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 7

Page 9: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 8

Lembre-se por favor…

• Desligue ou silencie seu celular ou pagger durante as aulas.

• Responda a chamadas importantes fora da sala de aula ou em local apropriado.

• Responda chamadas menos importantes durante os exercícios ou breaks

Page 10: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 9

Page 11: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 10

Page 12: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 11

Page 13: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 12

Visão Geral

Visão Geral

Page 14: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 13

Page 15: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 14

Zen – Visão Geral

áç

ç ç

ç áç

Zen é um framework extensível para criação rápida de aplicações baseadas na Web.

• Framework extensível, de alto nível, otimizado para oferecer a máxima velocidade de

desenvolvimento, escalabilidade e disponibilidade para aplicações Web.

• Utiliza tecnologia AJAX, permitindo a criação de aplicações web muito mais interativas

• Oferece biblioteca de componentes visuais pré-construídos para montagem de páginas,

aplicações e portais web com comportamento semelhante ao de aplicações desktop.

• Estão disponíveis diversos tipos de componentes como grids, formulários, calendários, botões

diversos, menus, etc.

• Oferece ainda, recursos avançados para construção de relatórios em PDF, criados

dinamicamente e distribuídos através da Web.

• É possível a utilização de recursos que envolvem a utilização de padrões de projeto como o

MVC para a construção das aplicações, além da possibilidade de utilização de gráficos vetoriais

SVG.

Page 16: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 15

Page 17: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 16

Benefícios

Benefícios

Page 18: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 17

Page 19: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 18

Zen – Benefícios

• Desenvolvimento Rápido.

• Simplicidade.

• Biblioteca Extensível de Componentes.

• Integração de objetos com o Banco de Dados.

• Geração de Códigos.

• Extensibilidade (CSS)

• Uso integrado de SVG.

• Fonte de Cliente Independente

• Segurança.

• Manipulação de Form.

• Layout de página.

• Manipulação de Eventos.

• Suporte a Multilinguagem.

• Documentos de reports.

Desenvolvimento Zen

çá á

• Definições de página XML compiladas para máximo desempenho e escalabilidade.

• Extensa biblioteca de componentes para rápido desenvolvimento.

Page 20: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 19

Extensibilidade Baseada em Objetos

ç

• Vários componentes pré-construídos;

• Criação rápida de componentes customizados através de herança (subclasses) de componentes

Zen.

Modelo de Objetos Compartilhados

……

ç á

é

é

• Página define métodos client e server sides.

• Servidor e browser acessam dados através de poderoso modelo de objetos compartilhados.

Page 21: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 20

Multi-linguagem

……

“ ”

……

• Texto de linguagem base extraído automaticamente. • Texto de linguagem local resgatado dinamicamente no momento da execução.

Segurança

…“ ç á ”

“ ”“ á ”

“ ”“ á ”“ ”

• Controle de acesso declarativo a nível de página e componente. • Sincronizado automaticamente com segurança a nível de base de dados.

Page 22: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 21

Page 23: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 22

Demo

Demo

Page 24: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 23

Page 25: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 24

Introdução – Demo Acesse a página de exemplos do Zen através do link: http://localhost:<port>/csp/samples/ZENDemo.Home.cls Login para os exercícios: http://localhost:<port>/csp/user/ISCZen.Pag.Login.cls Usuário: master Senha: máster

Page 26: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 25

Page 27: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 26

Módulo - Cliente e Servidor

Módulo - Cliente e Servidor

Page 28: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 27

Page 29: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 28

Zen e Caché Server Pages

• Os seguintes diagramas resumem as interações entre o cliente CSP e o servidor. Como páginas

Zen são páginas CSP, essas informações são também aplicadas ao Zen.

Os números do diagrama anterior demonstram o fluxo dos eventos em um processo CSP. A seqüência é

a seguinte:

1. O browser (ou cliente Web similar) faz uma requisição HTTP;

2. Se o servidor web determina que esta é uma requisição CSP, ele envia a requisição ao Gateway CSP

instalado no servidor Web. Alternativamente, se a requisição é de um arquivo estático (como um arquivo

.html ou .jpg), o servidor Web encontra o arquivo em seu sistema de arquivos local e envia o conteúdo

ao cliente.

Page 30: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 29

3. O Gateway CSP reempacota a requisição e envia ao servidor Caché correto.

4. O servidor Caché decodifica a mensagem, determina qual classe de manipulação de evento (parte da

aplicação) deveria processar o evento, e invoca o método OnPage desta classe.

Página Zen são páginas CSP, então cada classe de página Zen tem um método OnPage.

Entretanto, as páginas Zen possuem muito mais recursos.

5. O servidor Caché retorna a saída do método OnPage ao Gateway CSP como uma resposta HTTP;

6. O Gateway CSP entrega a resposta HTTP ao servidor Web;

7. O servidor Web retorna a resposta ao browser que então processa a resposta. No caso de HTML, a

página é apresentada.

Aplicações Zen usam tecnologia CSP para:

• Filtrar e responder as requisições HTTP;

• Gerenciar sessões e ciclos de vida das sessões;

• Gerenciar identidade do usuário, autenticação, e controle de acesso.

• Fornecer mecanismo de hiperevento usado para chamar métodos servidor a partir do cliente;

• Chamadas a partir do servidor para executar código com segurança no cliente.

Page 31: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 30

Páginas Zen em tempo de execução

• A seqüência do diagrama anterior mostra uma página Zen em um browser. A numeração em negrito

mostra como uma página Zen interage dentro do processo CSP, conforme aqui detalhado:

1. O browser envia uma requisição HTTP com nome específico de uma página Zen. O servidor Caché

recebe a requisição e automaticamente direciona para a classe da página Zen. Nota: CSP trata este

passo, como descrito anteriormente.

2. A classe da página invoca o método callback %OnBeforeCreatePage. Este método fornece a

oportunidade para a aplicação executar qualquer configuração que pode ser necessária antes que a

execução de %CreatePage inicie.

3. A classe da página cria uma instância de si mesma no servidor Caché.

Page 32: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 31

4. A classe da página invoca o método callback %OnAfterCreatePage. Neste método, a aplicação pode

modificar o conteúdo gerado pelo %CreatePage.

5. O objeto da página constrói um documento HTML a partir do DOM. A página invoca o método

%DrawHTML. Cada página Zen e objeto de componente tem um método %DrawHTML que sabe como

“desenhar” o objeto como HTML.

6. O servidor Caché entrega o documento HTML ao cliente, e o browser mostra o documento HTML.

Page 33: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 32

Módulo - Conceito de Aplicações Zen de Aplicações Zen

Módulo - Conceito de Aplicações Zen

Page 34: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 33

Page 35: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 34

Aplicações Zen

• Uma aplicação Zen consiste das seguintes partes:

– Uma classe de Aplicação:

• Cada aplicação Zen tem uma classe de aplicação. Esta é uma classe derivada

de %ZEN.application que fornece comportamento e estilo para a aplicação. A

folha de estilo é especificada como um bloco XML embutido dentro da classe.

– Classes de Página:

• Uma aplicação consiste em uma ou mais páginas. Cada página é uma classe

derivada de %ZEN.Component.page.

– Classes de Componente:

• Cada página contém componentes. Componentes permitem que o usuário

interaja com a página. Todos os componentes são derivados de

%ZEN.Component.component. Eles incluem botões, tabelas, campos de textos,

listas, painéis – basicamente qualquer item que pode ser apresentado na página.

Page 36: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 35

Classe de Aplicação Zen

• Um classe de aplicação Zen fornece alto nível de administração e age como base para todas as

páginas na aplicação.

• A aplicação não mantém um inventário de suas páginas.

• A associação entre a aplicação e suas páginas ocorre e toda página Zen identifica qual é a

aplicação a que pertence.

• A classe da aplicação pode definir estilos, inclusive com referências à arquivos externos, a

serem utilizados por todas as páginas desta aplicação.

Exercícios - Crie uma nova aplicação Zen

Neste exercício será criada uma nova aplicação Zen:

1. Abra o Caché Studio;

2. Escolha Arquivo -> Mudar Namespace ou F4;

3. Escolha o namespace User;

4. Escolha Arquivo -> Novo or Ctrl-N;

5. Clique na tab Personalizado;

Clique no ícone de Nova Aplicação Zen. Informe:

Pacote (O pacote que conterá as novas aplicações): ISCUser.Aplic

Nome da Classe (O nome da classe da nova aplicacao): Aplicacao

Nome da Aplicação (O nome lógico da aplicação): Minha Aplicacao

7. Clique em Terminar.

8. Copie o conteúdo do arquivo ‘estilo.txt’ para dentro do bloco XData Style.

Page 37: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 36

Páginas Zen

• Uma página Zen consiste de:

– Uma definição de conteúdos: Um bloco XML embutido dentro da classe da página,

que define o conjunto de componentes que constroem a página, junto com seus

parâmetros. É possível definir os conteúdos da página programaticamente, mas na

maioria dos casos um bloco XML é mais conveniente.

– Sobrescrever Estilo: Um bloco XML embutido dentro da classe da página, que

sobrescreve estilos CSS específicos da página para componentes desta

página.Métodos de Tratamento de Eventos: Uma classe de página geralmente contém

métodos que tratam eventos associados à página, como quando um usuário interage

com um componente. Alguns destes métodos podem executar no servidor e outros no

cliente.

Page 38: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 37

Exercícios – Criando uma página Zen Neste exercício você criará uma página Zen:

1. Abra o Caché Studio.

2. Escolha Arquivo -> Mudar Namespace ou F4.

3. Escolha o namespace User.

4. Escolha Arquivo > Novo ou Ctrl-N.

5. Clique na tab Personalizado.

6. Clique no ícone Nova Página Zen

Em Nome do Pacote escolha: ISCUser.Pag

Em Nome da Classe escreva: BoasVindas

Em Nome da Aplicação escolha: ISCUser.Aplic.Aplication

7. Clique Próximo;

8. Clique Terminar;

Page 39: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 38

Componentes Zen

• Classes de Componentes Zen definem o comportamento e layout da página. Cada componente

Zen tem as seguintes características:

– Define um conjunto de propriedades e métodos que determinam seu estado e

comportamento em tempo de execução;

– Define como seu HTML inicial é desenhado. É também possível definir componentes

que apenas são “desenhados” usando eles mesmos através de lado-cliente, HTML

dinâmico;

– Define uma folha de estilos CSS padrão que especifica como deveria ser apresentado

na página;

– Define parâmetros que ajustam a aparência ou comportamento de um componente;

– Novas classes de componentes podem ser derivadas de classes existentes.

– Novos componentes estão automaticamente prontos para usar dentro de definições de

conteúdo XML da página.

• Classes de componentes variam em complexidade desde um simples mapeamento de um

controle nativo HTML até componentes avançados como calendários, grids, .

• Componentes incluem os seguintes tipos especializados:

– Controles: mostram dados e permitem a entrada do usuário (como caixas de textos e

botões);

– Grupos: contém conjuntos de outros componentes (como grupos, grupos de tabelas,

menus e formulários);

– “Panes”: apresentam informações (como recuperadas de queries).

– Outros componentes que simplesmente apresentam dados na página.

Page 40: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 39

Exemplo grupos dentro da página:

XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title=""> <html id="title">Title</html> <vgroup width="100%"> <vgroup width="60%“ align="center" label="Vertical Group"> <hgroup width="40%" align="left" label="Horizontal Group" /> <hgroup width="20%" align="center" label="Horizontal Group" /> <hgroup width="40%“ align="right" label="Horizontal Group" /> </vgroup> </vgroup> </page> }

Resultado:

Page 41: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 40

Módulo – Conce

Módulo - Conceitos de Componentes Zen

Módulo - Conceitos de Componentes Zen

Page 42: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 41

Page 43: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 42

Componentes Zen

• Os componentes fornecem layout, estilo e comportamento para a página. A seguir uma tabela

que define os termos geralmente usados:

Term o I lust ração Resum o

PáginaRetângulo apresentado em uma janela do browser.

LayoutA posição de cada componente e de cada grupo de componentes, na página.

Est iloA aparência visual dos componentes, independente de sua posição na página.

Compor tamento

Uma ação da aplicação que resulta de uma entrada do usuário, um temporizador, ou algum outro evento.

Página

• Uma página é inicialmente vazia. Ela é preenchida com componentes que são adicionados à ela.

• Uma estratégia de layout é necessária para determinar onde estes componentes serão exibidos

na página.

Layout

• Componentes são inseridos dentro de grupos: um tipo especial de componente que pode conter

zero ou mais componentes. Um grupo é responsável pela localização dos seus componentes na

página.

• Zen gera tabelas HTML padrão baseado na definição de grupos.

• É possível distribuir os componentes em linhas verticalmente ou horizontalmente, inserindo-os

dentro de grupos verticais ou horizontais.

• Certos componentes permitem camadas, como folhas de papel que ocupam uma posição em

uma pilha. Apenas uma camada é mostrada a cada vez, baseado em cliques do usuário. Menus

e guias trabalham desta forma.

• Elementos XML que controlam o layout:

– <page> é um componente de grupo que atua como container de mais alto nível para

todos os elementos XML;

– <html> permite a inserção de fragmentos HTML diretamente na página;

– <hgroup> cria uma linha horizontal de componentes;

– <vgroup> cria uma coluna vertical de componentes;

– <spacer> insere um espaço entre os grupos;

– <pane> subdivide uma página em regiões.

Page 44: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 43

Layout – Exemplo de <pane>

• <pane paneName="menuPane"/>.

Estilo

• Estilo determina a aparência visual de um componente.

• Zen gerencia estilos gerando instruções CSS padrão baseados nas entradas fornecidas ao Zen.

• Há muitos atributos de estilos que podem ser configurados para cada componente. Estes

incluem cor de fundo, tamanho, fontes, ...

• É possível aceitar os estilos padrão dos componentes ou então sobrescrevê-los a nível de

componente, página ou aplicação.

• A seguir uma relação com alguns exemplos de atributos que configuram o estilo de um

componente, a lista completa de atributos está descrita na documentação:

– id: pode ser utilizado para selecionar uma definição de estilo CSS para um componente.

– name: especifica o nome do componente. Geralmente, é usado para identificar um

controle dentro de um formulário.

– align: controla o alinhamento do controle, os valores possíveis são: “left”, “right” ou

“center”.

Page 45: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 44

Comportamento

• Comportamento refere-se às ações internas ou externas na aplicação que são disparadas pela

entrada do usuário, um temporizador, ou algum outro tipo de evento.

• Comportamento envolve muitos aspectos, desde o processamento de cliques de usuários e

pressionamentos de teclas até a geração de tabelas baseadas em queries do banco de dados.

Personalização

• Uma das características mais poderosas do framework Zen é a de ter a capacidade de

desenvolver componentes novos, reusáveis, que automaticamente trabalham com outros

componentes Zen.

• A maneira mais comum para estender o Zen, é criar um componente personalizado.

Componentes personalizados se ajustam ao framework Zen existente com mínimo esforço.

• Opções para criar componentes personalizados:

– Construir um componente composto;

– Modificar o estilo de um componente;

– Criar um componente personalizado;

– Criar uma métrica personalizada.

• Estas opções serão detalhadas em um módulo posterior.

Page 46: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 45

Exercício – Conceitos de Componentes Zen

1. Abra a classe ISCUser.Pag.BoasVindas.

2. Posicione o cursor no início desta linha.

</page>

3. Pressione Enter.

4. Mova o cursor para a linha em branco acima.

5. Digite o sinal de menor “<“. Uma lista de elementos XML irá aparecer.

6. Clique button.

7. Pressione Enter.

8. Digite um espaço em branco. Uma lista de atributos XML irá aparecer.

9. Clique align=“enter”.

10. Clique caption=“Método Cliente“.

11. Complete a classe com:

<hgroup>

<vgroup width="30%">

<calendar align="center"/>

</vgroup>

<vgroup width="40%">

<image align="center" src="images\LabExam.jpg"/>

</vgroup>

<vgroup width="30%">

<colorPicker align="center"/>

</vgroup>

</hgroup>

Page 47: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 46

Convenções de Nomenclaturas

Convenções de Nomenclaturas

Page 48: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 47

Page 49: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 48

Convenções de Nomenclaturas

• Programas Zen são “case-sensitive”. Então “a” não é o mesmo que “A”;

As seguintes convenções de nomes são aplicadas em códigos Zen. Estas convenções usam “case”

(letras maiúsculas e minúsculas) para diferenciar entre categorias de métodos ou propriedades.

meuNomeMetodo e MeuNomeMetodo não são o mesmo nome;

Métodos lado-cliente:

• São definidos usando a frase-chave Language=JavaScript, e são escritos em JavaScript. Podem

ser chamados a partir do cliente, e quando chamados, executam no cliente. Os nomes iniciam

com letras minúsculas e as iniciais das palavras sucessivas com letras maiúsculas. O mesmo é

verdadeiro para propriedades apenas-cliente.

Exemplo: meuNomeMetodo

Métodos Zen:

• São definidos usando a palavra-chave ZenMethod. Eles podem ser chamados a partir do cliente,

mas são executados no servidor. Estes métodos são escritos em ObjectScript ou Basic, mas

podem incluir JavaScript embutido que retornam ao cliente. Os nomes iniciam com letras

maiúsculas, assim como as iniciais das palavras sucessivas.

Exemplo: MeuNomeMetodo

Métodos lado-servidor:

• Não usam nenhuma palavra-chave, e são escritos em ObjectScript ou Basic. Estão disponíveis

para serem chamados a partir do código que está executando no servidor, e quando chamados,

executam no servidor.

• Os nomes iniciam com o caracter %. Propriedades apenas-servidor usam esta convenção

também.

Exemplo: %MeuNomeMetodo

Classes Zen:

• Geralmente, os nomes de classes Zen iniciam com letra minúscula, semelhante as convenções

para métodos e propriedades lado-cliente.

• As exceções para esta regra incluem algumas classes de utilitários apenas-servidor, que iniciam

com uma letra maiúscula.

Page 50: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 49

Exemplo: tablePane

Atributos e Propriedades

• Nomes de atributos e propriedades iniciam com letra minúscula, exceto para manipuladores de

eventos e callbacks.

Exemplo: filterOp

Manipuladores de Eventos

• Atributos que identificam Manipuladores de Eventos de componentes seguem a convenção

JavaScript de todos os caracteres minúsculos.

• Exemplo: onmousedown

CallBacks

• Atributos que identificam callbacks lado-servidor de componentes iniciam com On (letra “O”

maiúscula).

Exemplo: OnCreateDataSet

Exercícios – Método do lado Cliente

• Neste exercício você irá adicionar um método JavaScript do lado cliente para a sua classe de

página Zen, como segue:

1. Abra ISCUser.Pag.BoasVindas no Caché Estudio.

2. Digite no manipulador de eventos onclick do botão a seguinte expressão:

zenPage.btnClique();

– Esta expressão executa um método chamado btnClique em um objeto chamado

zenPage.

• zenPage é a variável JavaScript que representa o objeto página no lado cliente.

btnClique está disponível no objeto página apenas se ele for definido na página

Zen como um método lado-cliente.

– Neste exercício iremos adicionar um método JavaScript lado-cliente na classe de página

Zen:

– Posicione o cursor logo abaixo do fechamento do bloco XData Contents;

Page 51: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 50

3. Escolha Ferramentas Modelos Modelos ou pressione CTRL-T para mostrar a caixa de

diálogo Modelos do Caché Studio. Escolha Zen Method Wizard. Clique em OK.

Informe os seguintes valores para os campos:

– Em Nome do Método informe btnClique

– Escolha é um método de instância

– Escolha é executado no cliente

– Informe uma descrição

– Clique em Terminar. O novo método aparece na classe da página assim:

4. Altere o código do método para este:

5. Escolha Compilar Compilar ou o ícone.

6. Escolha Exibir Página Web ou o ícone.

7. Clique no botão “Pressione”. O código JavaScript mostra uma mensagem.

8. Clique em OK para fechar a mensagem.

Page 52: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 51

Notas: método lado Cliente

• Alguns itens importantes a observar no método btnClique:

– Ele é definido como um método de instância (não usa a palavra-chave ClassMethod);

– A palavra-chave Language é configurada como JavaScript. Isto significa que a

implementação deste método usa JavaScript. O Studio valida e aplica cores de sintaxe

como JavaScript;

– Quando esta classe é compilada, o método btnClique não estará disponível como um

método acessível no servidor. Ele, no entanto, estará disponível como um método de

instância do objeto zenPage no cliente;

– O compilador de classe trata a herança. Isto significa que você pode definir métodos

JavaScript dentro de uma super classe e eles estarão automaticamente disponíveis para

qualquer subclasse.

– O corpo deste método usa o método alert padrão JavaScript para apresentar a

mensagem no cliente;

– Em tempo de execução, este método é executado dentro do ambiente cliente (browser);

– O método é definido dentro da mesma unidade lógica (isto é, dentro da mesma classe)

como a definição da página que o referência. Isto faz com que as páginas sejam fáceis

para desenvolver e manter.

Page 53: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 52

Exercícios – método do lado Servidor

• Neste exercício, faremos uma alteração em nossa página Zen. Esta alteração demonstra a

habilidade de invocar um método no servidor a partir de uma página cliente.

1. No Studio, abra a classe de página;

2. Usando as técnicas dos exercícios anteriores, adicione um novo botão dentro do bloco XData

Contents. Dê ao novo botão os seguintes valores de atributos:

id = meuBotaoServ

caption = Método Servidor

onclick = zenPage.BtnCliqueServ();

3. Posicione o cursor logo abaixo do final do bloco XData Contents;

4. Escolha Ferramentas Modelos Modelos ou pressione CTRL-T para mostrar a caixa de

diálogo do Studio. Escolha Zen Method Wizard. Clique em OK. Nesta tela informe o seguinte:

Em Nome do Método informe BtnCliqueServ

Escolha é um método de instância

Escolha executa no servidor

Informe uma descrição.

Clique em Finish. Seu novo método é criado com a seguinte aparência:

5. Altere o código do método para o seguinte:

6. Escolha Compilar Compilar ou o ícone

7. Escolha Exibir Página Web ou o ícone

8. Clique no botão Método Servidor. Uma mensagem é apresentada.

9. Clique em OK para fechar a mensagem.

10. Use a opção Ver Código Fonte do browser para visualizar o HTML gerado.

Page 54: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 53

• Alguns itens importantes a observar sobre o método BtnCliqueServ:

– Definido como um método de instância;

– Omite a palavra-chave Language. Isto significa que este método usará a linguagem de

script padrão do servidor (ObjectScript ou Basic, neste caso ObjectScript);

– Executa no servidor mas também envia um hiperevento para o cliente;

– Usa a palavra-chave ZenMethod. Isto significa que este é um método lado-servidor que

pode ser chamado a partir do cliente. Até quando este método é chamado a partir do

ambiente do cliente (browser), ele é executado no servidor;

– O método associa o valor do utilitário $ZVERSION a variável msg, então envia msg ao

cliente;

– &js<alert(‘#(msg)#’);> é um exemplo de sintaxe de JavaScript embutido. Ao executar

este método no servidor, Zen encontra o fragmento de código JavaScript entre &js<> e

envia este fragmento para o cliente executar. Nota: Este comportamento é fornecido

pelo mecanismo de hiperevento do CSP.

– Dentro do JavaScript embutido, a sintaxe #(msg)# é a convenção para transferir o valor

da variável msg do código ObjectScript executando no servidor para o JavaScript

embutido executando no cliente.

– O objeto zenPage do lado-cliente pode invocar o método BtnCliqueServ lado-servidor.

Isto porque foi definido como um método de instância, o servidor precisa do estado

completo do objeto lado-cliente atual para ser capaz de executar o método;

– O método não retorna nenhum valor. Isto é intencional. Ao usar hipereventos CSP, um

método sem valor de retorno executa assincronamente (não aguarda uma resposta).

Desta maneira, a interface do usuário não parece “congelar”.

Page 55: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 54

Módulo - Tabelas Zen

Módulo - Tabelas Zen

Page 56: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 55

Page 57: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 56

Tabelas Zen

• As tabelas Zen recebem um resultset retornado por uma query SQL e apresenta os dados como

uma tabela HTML.

• Há várias formas para gerar um resultset para uma tabela Zen. Você pode especificar um

comando SQL, fazer referência a uma query SQL pré-definida, ou fornecer ao Zen informações

necessárias para que o comando SQL seja gerado automaticamente.

• Uma vez que os dados são recuperados, é possível aplicar na tabela diversas opções de estilo e

funcionalidade.

Inserir uma Tabela em uma Página Zen

<tablePane>

• Para colocar uma tabela em uma página Zen, deve-se inserir um componente <tablePane>

dentro do bloco XData Contents na classe da página.

• Zen fornece vários componentes e classes auxiliares para suportar tabelas.

Elementos XML para usar com tabelas Zen

• <tablePane> - Desenha uma tabela HTML baseado em uma query SQL. Cada linha do resultset

é uma linha da tabela. Ela pode conter os seguintes elementos:

– <parameter> fornece parâmetros necessários para a construção da query <tablePane>;

– <column> especifica detalhes de layout, estilo e comportamento para uma determinada

coluna na tabela gerada. Seu uso é opcional quando deseja-se apresentar todas as

colunas do resultset.

– <condition> determina uma condição para aplicar um determinado estilo para a linha ou

célula da tabela. Ex.: se o valor da coluna Média for menor que 7 deve-se usar a cor

vermelha para o cor de fundo da linha.

– <tableNavigator> fornece automaticamente um conjunto padrão de botões para

navegação entre as páginas de uma tabela.

– <tableNavigatorBar> alternativo ao <tableNavigator>, fornece botões extra para ajudar

na navegação de páginas.

Page 58: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 57

Origem dos Dados

• O elemento <tablePane> usa umas das seguintes origens dos dados para a tabela:

1. Especificando um comando SQL;

2. Fornecendo uma simples descrição que o Zen usa para gerar o comando SQL;

3. Referenciando uma query de classe que gera o comando SQL;

4. Referenciando um método callback que gera o comando SQL;

1. Especificando um comando SQL:

Um <tablePane> pode fornecer um comando SQL completo como valor do atributo sql. Zen então

executa este comando SQL para obter o conteúdo da tabela.

Exemplo:

<tablePane id="tabela" sql="SELECT ID,Nome FROM

MinhaApl.Funcionarios WHERE Nome %STARTSWITH ? ORDER

BY Nome"/>

2. Gerando uma query SQL

– <tablePane> suporta atributos que permitem a geração automática da query baseado

em uma simples descrição.

– Para gerar a query SQL deve-se informar os seguintes atributos:

• groupByClause - (opcional) – uma cláusula SQL GroupBy como “Ano,Estado”;

• orderByClause – (opcional) – uma cláusula SQL OrderBy como “Nome,Estado”.

• tableName – o nome da tabela SQL que fornece os dados. Este é o valor usado

na cláusula From.

• whereClause – (opcional) – uma cláusula SQL Where como “Valor>100”.

• Exemplo:

<tablePane id="tabela"

tableName="MinhaApl.Funcionarios">

<column colName="ID" hidden="true" />

<column colName="Nome" />

</tablePane>

Page 59: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 58

3. Referenciando uma query de uma classe:

– Um <tablePane> pode fazer referência a queries já existentes em uma classe para obter

o objeto %ResultSet. Os seguintes atributos suportam esta técnica:

• queryClass – O nome da classe que contém a query.

• queryName – O nome da query contida na classe.

– Exemplo:

<tablePane id="tabela"

queryClass = "MinhaApl.Funcionarios"

queryName = "ListaFuncionarios" />

4. Usando um método CallBack

– Um <tablePane> pode gerar uma tabela usando um objeto %ResultSet definido pela

aplicação. Os seguintes atributos suportam esta técnica:

• OnCreateResultSet – O nome de um método CallBack lado-servidor a chamar

para criar o objeto %ResultSet.

• OnExecuteResultSet – O nome de um método CallBack lado-servidor a chamar

para executar o objeto %ResultSet retornado pelo método identificado pelo

OnCreateResultSet.

Exemplo:

<tablePane id="tabela" OnCreateResultSet="CriaRS"/>

Method CriaRS(Output pSC As %Status, pInfo as

%ZEN.Auxiliary.QueryInfo) As %ResultSet

{

Set pSC = $$$OK

Set tRS = ##class(%ResultSet).%New()

// .... Atividades do método ...

Quit tRS

}

Page 60: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 59

Parâmetros da Query

• Ao trabalhar com queries SQL para gerar tabelas Zen, muitas vezes é necessário fornecer

valores para parâmetros de entrada da query, definidos pelo caracter “?”. Para isso, deve-se

usar o elemento <parameter> dentro do elemento <tablePane>.

• Exemplo:

<tablePane id="tabela"

queryClass = "MinhaApl.Funcionarios"

queryName = "ListaFuncionarios">

<parameter value="Vendas"/>

<parameter value="Curitiba"/>

</tablePane>

Colunas da Tabela

• Conforme descrito anteriormente, o elemento <tablePane> “desenha” uma tabela HTML

baseada em uma query SQL, e cada linha do resultset é apresentada como uma linha da tabela.

• Um <tablePane> pode também conter um ou mais elementos <column>, que servem para

identificar quais colunas do resultset devem ser apresentadas na tabela.

• Os elementos <column> também especificam detalhes de layout, estilo e comportamento para

cada coluna.

• Exemplo:

<tablePane id="tabela"

tableName="MinhaApl.Funcionarios">

<column colName="ID" />

<column colName="Nome"/>

<column colName="Funcao" style="color: blue;"/>

</tablePane>

Page 61: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 60

• O elemento <column> possui vários atributos que podem ser utilizados para controlar layout,

estilo e comportamento. A lista completa encontra-se na documentação.

– colName: o nome da coluna SQL a que esta coluna está associada;

– header: um texto que especifica o cabeçalho da coluna;

– hidden: se o valor for igual a “true”, então esta coluna não é apresentada. O valor default

é “false”;

– style: valor do estilo CSS a ser aplicado nas células dentro da coluna. Ex.: “color: red;”

– width: especifica a largura da coluna (opcional).

Exercícios – Tabelas Zen

1. Crie uma página com o nome PesquisaPaciente.

1. Pacote e subpacote: ISCUser.Pag;

2. Inclua uma tabela Zen (<tablePane>);

2. Configure a tabela para ler os dados da classe ISCUser.Dados.Paciente. Utilize como origem de

dados ou a geração da query SQL (2) ou método CallBack (4), pois iremos configurar alguns

filtros na tabela.

3. Inclua as seguintes colunas na tabela: ID (oculto), Nome, Cidade, Sexo, Adulto e Prioridade

(com relacionamento para a propriedade descrição).

4. Inclua um elemento WhereClause para listar somente os pacientes adultos.

5. Configure um estilo para a coluna Sexo, fazendo com que o texto desta coluna seja apresentado

em vermelho(style=“color: red”).

Estilo da Tabela

• O elemento <tablePane> oferece vários atributos para configuração do estilo da tabela. A

relação completa encontra-se na documentação.

– caption: texto explicativo da tabela. É apresentado no cabeçalho da tabela;

– showRowNumber: se o valor for igual a “true”, então mostra uma coluna no lado

esquerdo da tabela com o número da linha;

– showZebra: se o valor for igual a “true”, então apresenta as linhas da tabela alternando

entre uma linha clara e outra escura.

Page 62: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 61

Estilo Condicional para Linhas e Células

• Cada elemento <condition> é uma expressão simples, baseada nos valores de uma determinada

linha, que controla o estilo da linha ou de uma célula individual.

<tablePane id="tabela"

sql="SELECT Nome,Salario FROM MinhaApl.Funcionarios">

<condition colName="Nome"

predicate="STARTSWITH"

value="A"

rowStyle="background: plum;"/>

</tablePane>

• No exemplo anterior, as linhas em que o valor do Nome inicia com a letra “A” será apresentada

com a cor de fundo “plum”;

• A quantidade de condições aumenta o processamento necessário para apresentar a tabela,

portanto deve-se usar conscientemente.

• O elemento <condition> possui vários atributos, segue alguns deles:

– cellStyle: estilo CSS a ser aplicado nas células dentro de colunas-alvo, para linhas em que a

condição é verdadeira. Ex.: “color: red;”

– colName: nome da coluna que fornece o dado a ser avaliado.

– predicate: operador lógico usado pela condição. O valor padrão é “EQ” (igual). A

sequência apresenta as opções para este atributo;

– targetCol: nome da coluna a aplicar o cellStyle. Se não for informado, é usado o

valor de colName;

– value: valor a ser comparado com o valor na coluna identificado em colName. Se

estiver entre {} será usado o nome de outra coluna, ex.: {Nome}

• Valores possíveis para o atributo predicate:

– CONTAINS: Verdadeiro se o valor na coluna identificada por colName contém (como uma

substring) o valor especificado por value;

– EXTEQ: Verdadeiro se o nome do arquivo tiver a extensão especificada em value;

– EQ: Igual (=);

– GT: Maior (>);

– GTEQ: Maior ou igual (=>);

– LT: Menor (<);

– LTEQ: Menor ou igual (=<);

– NEQ: Não for igual (‘=);

– STARTSWITH: inicia com ...

Page 63: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 62

Modo Snapshot

• Um <tablePane> pode operar em modo snapshot. Neste modo, Zen executa a query da tabela

uma vez e copia estes resultados para um local temporário no servidor.

• As próximas atualizações da página mostram os dados a partir deste local temporário.

• Este modo é especialmente útil ao trabalhar com tabelas multi-páginas, ou com tabelas que o

usuário pode escolher a ordem dos dados.

• Atributos:

– useSnapshot: quando for igual a “true” é ativado o modo snapshot. O valor padrão é

“false”.

– pageSize: para tabelas em modo snapshot, este atributo identifica que é para apresentar

os dados em várias páginas, e qual o tamanho da página (quantos registros apresentar

em cada vez). 0 (zero), o padrão, significa que é para apresentar todos os dados na

primeira página.

• Exemplo:

<tablePane id="tabela"

sql="SELECT Nome,Salario FROM Pac.Classe"

useSnapshot="true"

pageSize="25" />

Exercícios – Tabelas Zen

6. Insira uma coluna (a primeira) informando o númeor da linha.

showRowNumbers="true"

7. Configure para que tenha estilo ‘zebra’ (linhas claras e escuras alternadas).

showZebra="true"

8. Inclua uma condição, fazendo com que as linhas com pacientes masculinos tenham todo o texto

em negrito (“font: bold;”)

<condition colName="Sexo" predicate="EQ" value="M" rowStyle="font: bold;"/>

9. Configure a tabela para usar o modo Snapshot e apresentar 10 linhas por página.

useSnapshot="true" pageSize="10"

Page 64: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 63

Filtrando Colunas

• Uma tabela Zen pode criar “filtros” a serem apresentados acima do cabeçalho de qualquer

coluna. Um filtro é um campo de entrada onde o usuário pode informar um ou mais critérios de

pesquisa.

• Quando o usuário submete estas alterações, a query associada ao <tablePane> é re-executada

usando novos critérios.

• Os filtros trabalham apenas com tabelas que usam um comando SQL gerado automaticamente

ou um método callback OnCreateResultSet.

• O elemento <column> possui diversos atributos para trabalhar com filtros, entre eles:

– filterType: Indica que a coluna deve apresentar o filtro e qual tipo de filtro é usado. Os

valores possíveis são: "", "text", "range", "date", "datetime", "enum", "query", ou "custom".

– filterEnum: Se filterType for igual a Enum, este atributo define um conjunto de valores

possíveis a usar no filtro. Ex.: “vermelho,verde,azul”.

– filterEnumDisplay: Se filterType for igual a Enum, e se filterEnumDisplay fornece uma

lista de valores, a combo box apresenta estes valores no lugar dos valores

correspondentes em filterEnum.

– filterOp: Operador SQL a avaliar o filtro. Os valores possíveis são: "", "%STARTSWITH",

"=", ">=", "<=", "<>", ">", "<", "[","BETWEEN", "IN", ou "%CONTAINS".

– filterQuery: Se filterType for igual a query, este atributo define o comando SQL usado

para popular a combo box.

• Exemplo:

<tablePane id="tabela" useSnapshot="true"

tableName="MinhaApl.Funcionarios">

<column colName="ID" hidden="true"/>

<column colName="Nome" filterType="text" />

<column colName="Departamento"

filterType="enum"

filterEnum="Vendas,RH,Produção"

filterOp="=" />

</tablePane>

Page 65: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 64

Links em Colunas

• Colunas em tabelas Zen podem apresentar links, como por exemplo links que acessam outra

página para editar os dados do objeto mostrado na linha atual.

• Este link pode ser mostrado tanto em uma coluna que contém um dado, como em uma coluna

extra na tabela.

• Alguns atributos:

– link: Indica que a coluna é apresentada como um link, e o valor do atributo é a URL a

acessar. Para invocar um método JavaScript lado-cliente, inicie a URL com javascript:.

Ex.: link=“javascript:zenPage.meuMetodo();”

– linkCaption: Se a coluna tem um link definido e não apresenta um valor de um dado,

este atributo especifica um texto para usar como um texto explicativo do link.

– linkConfirm: Se a coluna tem um link definido, o texto deste atributo é apresentado como

uma mensagem de confirmação antes de o link ser executado.

• Exemplo:

<tablePane id="tabela"

sql="SELECT ID,Matricula,Nome FROM Apl.Funcionarios">

<column colName="ID" hidden="true"/>

<column colName="Matricula"

link="MinhaApl.EditFunc.cls?ID=#(%query.ID)#"

linkTitle="Ver informações do funcionário." />

<column

link="javascript:zenPage.inclDep('#(%query.ID)#');"

linkCaption="Incluir dependente"

linkConfirm="Deseja incluir um dependente?" />

</tablePane>

Page 66: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 65

Botões de Navegação

• O componente <tableNavigator> mostra automaticamente um conjunto de botões para

movimentação através das páginas de uma tabela Zen (<tablePane>).

• O <tableNavigatorBar> tem sintaxe idêntica ao <tableNavigator>, no entanto apresenta botões

extras para auxiliar na navegação entre as páginas.

• Para usar um dos componentes, coloque-o em qualquer lugar de uma página que contém um

<tablePane> e configure o atributo tablePaneId com o valor do atributo Id do elemento

<tablePane>.

• Exemplo:

<tablePane id="minhaTab" tableName="Apl.Funcionarios">

<column colName="ID" hidden="true"/>

<column colName="Nome"/>

</tablePane>

<tableNavigatorBar tablePaneId="minhaTab" />

Exercícios – Tabelas Zen

10. Inclua um filtro na coluna Nome para que sejam listados somente os pacientes cujo nome

iniciem com um determinado texto.

11. Inclua um filtro na coluna Prioridade para que sejam listados somente os pacientes de uma

determinada categoria.

12. Inclua uma coluna, a última da tabela, com um link. Este link, quando clicado, deve chamar um

método JavaScript que mostra uma mensagem de alerta informando o nome do paciente da

linha que o usuário clicou. Também deve pedir a confirmação do usuário, se realmente deseja

gerar um alerta.

13. Como nossa tabela está limitada a apresentar 10 registros por página, devemos incluir um

elemento de barra de navegação. Teste ambos o <tableNavigator> ou o <tableNavigatorBar>.

Exercícios – Tabelas Zen (Pesquisa Exames)

1. Crie uma página de pesquisa para exames, usando <tablePane...>, deve se chamar

PesquisaExames.

1. Nome do pacote e subpacote: ISCUser.Pag.

2. Inclua uma tabela Zen, <tablePane>.

Page 67: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 66

Módulo – Controles Zen

Módulo – Controles Zen

Page 68: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 67

Page 69: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 68

Controles Zen

• Controles Zen são os elementos de entrada do usuário que são inseridos em um formulário Zen

(discutido no próximo módulo).

• Cada controle tem um valor associado a ele. A propriedade que contém o valor atual do controle

é a value.

• Zen valida e submete todos os valores dos controles de um formulário, como uma unidade.

Categorias dos Controles

• Os controles Zen estão divididos nas seguintes categorias:

– Botões: <button>, <image>, <submit>;

– Textos: <label>, <text>, <textarea>, <password>;

– Escolhas simples: <checkbox>, <colorPicker>, <radioButton>, <radioset>;

– Listas: <select>, <listBox>, <dataListBox>, <combobox>, <dataCombo>;

– Calendários: <calendar>, <dateText>;

– Planilhas: <dynaGrid>;

– Ocultos: <hidden>.

Atributos Comuns

• Todos os controles Zen possuem atributos em comuns.

– clientType: Indica o tipo do dado (data type) JavaScript para o valor do controle. Por

padrão, um controle trata o valor como string, no entanto, para fins de validação, podem

ser usados os seguintes: “string”, “boolean”, “integer” e “float”.

– dataBinding: Se este controle está associado à um data controller, este atributo identifica

a propriedade que fornece o valor ao controle.

– disabled: a aparência não é alterada, mas não responde às ações do usuário;

– onblur: evento que é disparado quando o controle perde o foco. Ex.: <button

onblur=“alert(‘Perdeu o foco’);”>;

– onchange: disparado quando o valor do controle é alterado;

– onclick: disparado quando é clicado com o mouse no controle;

– ondblclick: disparado quando é clicado duas vezes com o mouse no controle;

– readOnly: quando verdadeiro, este controle é apenas-leitura e não é submetido seu valor

quando o formulário que o contém é submetido;

– required: quando verdadeiro, o usuário deve informar um valor para este controle, caso

contrário, a validação falhará;

Page 70: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 69

Botões

• Zen oferece os seguintes controles em estilo de botões:

– <button> o usuário clica em um botão que pode disparar ações;

– <image> o usuário clica em uma imagem;

– <submit> o usuário clica em um botão que submete um formulário;

<button> e <submit>

• O componente <button> é um simples “mapeamento” do elemento HTML <input type=“button”>.

• O componente <submit> é um tipo especial de botão que submete um formulário.

• Além dos atributos comuns a todos os controles, os componentes <button> e <submit> tem

ainda:

– caption: texto apresentado no botão.

Exemplo: <button caption=“Texto do botão”/>

<image>

• O controle <image> mostra uma imagem estática.

• Pode ser usado para apenas apresentar uma imagem, ou serve como um botão se for

especificado o atributo onclick.

• Atributos:

– src: identifica o caminho e o nome do arquivo da imagem. O caminho é relativo ao

diretório de instalação do Caché.

Ex.: <image id=“imgTeste” src=“/csp/Apl/imagens/imagem.png”>

Page 71: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 70

Textos

• Zen oferece os seguintes controles de estilo texto:

– <label> mostra um rótulo de texto;

– <text> o usuário informa um texto;

– <textarea> o usuário informa várias linhas de texto;

– <password> o usuário informa um texto como senha.

<label>, <text> e <password>

• O controle <label> mostra passivamente um texto estático.

• O controle <text> é um simples “mapeamento” do elemento HTML <input type=“text”>.

• O controle <password> é um “mapeamento” do elemento HTML <input type=“password”>.

Qualquer texto informado neste controle é apresentado com pontos, dessa forma não é possível

visualizar o que está sendo digitado.

• Além dos atributos comuns, os controles <text> e <password> possuem os seguintes:

– maxlength: número máximo de caracteres que o usuário pode informar dentro do

controle;

– size: valor inteiro que indica a largura do controle. O padrão é 20.

<textarea>

• O controle Zen <textarea> é uma caixa de texto multi-linha.

• É um “mapeamento” do elemento HTML <textarea>.

• Tem os seguintes atributos:

– cols: número de colunas do controle. O default é 19;

– rows: número de linhas do controle. O default é 2.

Page 72: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 71

Escolhas Simples

• Zen oferece os seguintes controles para simples escolhas:

– <checkbox> o usuário marca e desmarca uma caixa;

– <colorPicker> o usuário seleciona uma cor de uma paleta;

– <radioSet> o usuário clica em uma opção em uma linha de botões “radio”;

– <radioButton> botões “radio” podem ser colocados em qualquer lugar da página.

• A únicas diferença entre <radioSet> e <radioButton> é que <radioSet> tem layout mais simples.

– Use <radioSet> para uma simples lista de opções;

– Use <radioButton> quando você quer um layout mais sofisticado.

<checkbox>

• O controle Zen <checkbox> é um “mapeamento” do elemento HTML <input type=“check”>.

• Apresenta um texto perto da caixa e detecta cliques do usuário no texto ou no caixa.

• Diferente do checkbox HTML, o controle Zen sempre submete um valor.

• Exemplo:

Page 73: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 72

<colorPicker>

• O componente <colorPicker> mostra uma linha de cores para o usuário escolher. O usuário clica

em uma cor para escolhê-la;

• <colorPicker> oferece uma alternativa para a paleta complexa <colorPane>;

• Possui os seguintes atributos (além dos atributos comuns):

– colorList: lista de cores (valor CSS) separadas por vírgula a apresentar dentro do

controle, da esquerda para a direita. O valor padrão como mostrado na imagem acima é:

“,black,gray,darkblue,darkred,darkgreen,blue,red,green,yellow,

orange,plum,purple,white”

<radioSet>

• Este controle apresenta uma lista concisa de botões radio de um conjunto de opções;

• A maneira mais simples para definir um <radioSet> é fornecer um valueList para o usuário

escolher. É possível informar valores correspondentes ao valueList para o usuário visualizar

através do displayList.

• Exemplo:

• É possível também indicar uma fonte de dados para as opções dos botões através de queries

SQL.

Page 74: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 73

• Quando é usada esta técnica, as colunas retornadas pela query determinam o que é mostrado

no <radioSet>.

– Se o %ResultSet tem apenas uma coluna, o conteúdo desta coluna é usado tanto para o

valor lógico (valueList) quanto para o apresentado (displayList).

– Se o %ResultSet tem duas (ou mais) colunas, o conteúdo da primeira coluna fornece o

valor lógico (valueList) e o da segunda coluna fornece o valor a ser apresentado

(displayList);

• Os seguintes atributos dão suporte o uso de queries SQL:

– maxRows: Opcional, informa o número de máximo de itens a retornar pelo SQL.

– queryClass: Opcional, o nome da classe que contém a query. Deve-se informar também

o atributo queryName.

– queryName: Opcional, o nome da query na classe que irá fornecer o %ResultSet.

– sql: Opcional, comando SQL que fornece os dados para o <radioSet>.

Exemplo:

Page 75: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 74

<radioButton>

• É um “mapeamento” do elemento HTML <input type=“radio”> com algumas capacidades

melhoradas.

• Possui os seguintes atributos (além dos comuns):

– name: (não id) estabelece a associação entre os botões radio. É criado um conjunto de

botões associados informando o mesmo nome (name) para todos os botões;

– caption: o texto a ser apresentado no botão radio;

– optionValue: define o valor lógico associado ao botão.

Exemplo:

Listas

• Zen oferece os seguintes controles de listas:

– <select> mostra uma caixa de lista. “Mapeamento” do elemento HTML <select>.

– <listBox> define uma caixa de lista com opções fixas para o usuário escolher.

– <dataListBox> Zen gera uma caixa de lista, baseado em uma query.

– <combobox> define uma combo box com opções fixas.

– <dataCombo> Zen gera uma combo box, baseado em uma query.

Page 76: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 75

<select>

• Este elemento produz uma lista de opções (combobox) onde o usuário pode escolher um item.

• A maneira mais simples para definir um <select> é fornecer um valueList para o usuário

escolher. É possível informar valores correspondentes ao valueList para o usuário visualizar

através do displayList.

• Exemplo:

• É possível também indicar uma fonte de dados para as opções através de queries SQL.

• Quando é usada esta técnica, as colunas retornadas pela query determinam o que é mostrado

no <select>.

– Se o %ResultSet tem apenas uma coluna, o conteúdo desta coluna é usado tanto para o

valor lógico quanto para o apresentado.

– Se o %ResultSet tem duas (ou mais) colunas, o conteúdo da primeira coluna fornece o

valor lógico (valueList) e o da segunda coluna fornece o valor a ser apresentado

(displayList);

• Os seguintes atributos dão suporte ao uso de queries SQL:

– maxRows: Opcional, informa o número de máximo de itens a retornar pelo SQL.

– queryClass: Opcional, o nome da classe que contém a query. Deve-se informar também

o atributo queryName.

– queryName: Opcional, o nome da query na classe que irá fornecer o %ResultSet.

– sql: Opcional, comando SQL que fornece os dados para o <select>.

– Exemplo:

Page 77: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 76

<listBox>

• O controle Zen <listBox> apresenta uma caixa de lista, cujas opções podem ser formatadas

individualmente.

• Este controle não é um “mapeamento” do elemento HTML <select>. Isto permite fornecer

funcionalidades não disponíveis com <select> HTML, incluindo:

– Mais controle sobre o conteúdo da lista;

Exemplo:

– Solução de problemas com Internet Explorer operando em conjunto com CSS.

Page 78: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 77

<dataListBox>

• É um tipo especializado de <listBox> que apresenta ao usuário uma lista de opções obtidas

através de uma query SQL.

• Diferente do <listBox>, este controle não permite adicionar elementos <option> ou configurar os

elementos individualmente.

– Não há opções estáticas definidas, então não há elementos <option>.

• Para fornecer os dados a um <dataListBox> são utilizados os mesmos recursos das tabelas Zen,

ou seja, é possível:

– Especificar uma query SQL (atributo sql).

– Gerar uma query SQL (atributos groupByClause, orderByClause, tableName e

whereClause).

– Referenciar uma query de uma classe (atributos queryClass e queryName).

– Usar um método CallBack (atributos onCreateResultSet e onExecuteResultSet).

Exemplo:

Page 79: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 78

<comboBox>

• O controle Zen <combobox> não é um “mapeamento” do elemento HTML <select>. Este controle

fornece funcionalidade não disponível com o <select> HTML, incluindo:

– A habilidade de editar os valores em uma caixa de texto;

– Maior controle sobre o conteúdo da lista;

– Soluções de problemas com Internet Explorer junto com CSS.

• A maneira mais simples para criar um <combobox> é fornecer os atributos valueList e

displayList, de forma semelhante aos outros controles abordados anteriormente.

• Alternativamente, é possível fornecer elementos <option> dentro do componente <combobox>.

– <option> é mais flexível do que valueList e displayList porque ele permite a aplicação de

estilos CSS para cada item da lista.

• Exemplo:

• Os controles <combobox> e <dataCombo> possuem vários atributos, entre eles:

– comboType: Como a caixa dropdown é ativada pelo combo box:

• “image” indica que será apresentada uma imagem para o usuário clicar;

• “button” indica que um botão é apresentado perto do texto do combo box;

• “timer” indica que a caixa dropdown é apresentada automaticamente após um

determinado tempo depois que o usuário informar algo na combo box.

– buttonCaption: texto a apresentar no botão quando comboType é “button”;

Page 80: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 79

– delay: quando comboType é “timer”, especifica número de milisegundos a aguardar

depois que o usuário termina de digitar e antes de apresentar o dropdown. O default é

250.

– editable: se verdadeiro, o usuário pode editar um valor dentro da caixa de entrada, como

se fosse um campo de texto.

– maxlength: número máximo de caracteres que o usuário pode informar dentro do

controle.

– selectedIndex: índice baseado em 0 da opção selecionada na lista dropdown.

Page 81: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 80

<dataCombo>

• É um tipo especializado de <combobox> que apresenta ao usuário uma lista de opções obtidas

através de uma query SQL.

• Diferente do <combobox>, este controle não permite adicionar elementos <option> ou configurar

os elementos individualmente.

– Como não há opções estáticas definidas, então não há elementos <option>.

• O <dataCombo> fornece sua lista criando, executando e lendo um objeto %ResultSet no

servidor.

• As colunas retornadas determinam o que é apresentado na lista <dataCombo>:

– Se o %ResultSet, tem apenas uma coluna, o conteúdo desta coluna é usado tanto para

o valor lógico quanto para o valor a ser apresentado.

– Se tiver duas (ou mais) colunas, a primeira coluna fornece o valor lógico e as demais

colunas fornecem os valores a apresentar. Através dos atributos valueColumn e

choiceColumn é possível alterar essas colunas.

– Se tiver mais de duas colunas, é possível utilizar os atributos displayColumns e

columnHeaders para especificar que a lista dropdown tem várias colunas.

• Para fornecer os dados a um <dataCombo> são utilizados os mesmos recursos das tabelas Zen,

ou seja, é possível:

– Especificar uma query SQL (atributo sql).

– Gerar uma query SQL (atributos groupByClause, orderByClause, tableName e

whereClause).

– Referenciar uma query de uma classe (atributos queryClass e queryName).

– Usar um método CallBack (atributos onCreateResultSet e onExecuteResultSet).

Exemplo:

Page 82: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 81

Exemplo:

• Esta definição de <dataCombo> tem os seguintes efeitos:

– A query definida pelo sql é chamada sempre que a lista dropdown é apresentada. Ela

fornece um conjunto de valores lógicos (ID) e de apresentação (Nome). O parâmetro ?

recebe o valor do campo texto do <dataCombo>; o valor de searchKeyLen indica que os

primeiros 10 caracteres serão usados nesta busca.

– A query definida pelo sqlLookup é usada para encontrar um específico valor de

apresentação para um específico valor lógico. Esta query deve retornar uma única linha

contendo um valor de apresentação.

Page 83: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 82

Calendários

• Zen oferece os seguintes controles para seleção de datas:

– <calendar> o usuário seleciona datas a partir de um calendário popup;

– <dateText> o usuário pode informar/digitar ou selecionar uma data.

<calendar>

• Componente que apresenta um calendário navegável por mês, onde o usuário pode visualizar e

selecionar uma data.

• Segue relação de alguns atributos deste controle:

– dayList: lista separada por vírgula das abreviações dos dias a apresentar no início do

calendário. O valor padrão é: $$$Text(“S,M,T,W,T,F,S”);

– endYear e startYear: número do ano máximo/mínimo (4 dígitos) a considerar no

calendário.

– fixedMonth: se verdadeiro, o calendário apresenta apenas um mês, e não fornece

maneira para o usuário mudar o mês/ano.

– maxDate e minDate: string no formato AAAA-MM-DD. Se especificado indica a maior e a

menor data a considerar.

– monthList: lista separada por vírgula dos nomes dos meses. Ex.:

$$$Text(“Jan”,”Fev”,”Mar”,..).

– showTime: se verdadeiro, é apresentando além do calendário uma caixa de texto para

informação de horário.

– timeCaption: texto para mostrar no campo de horário quando showTime é verdadeiro.

Page 84: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 83

<dateText>

• O controle <dateText> é essencialmente uma combo box. Apresenta uma caixa de texto e um

botão, que quando pressionado, mostra um calendário popup.

• Este controle também faz a conversão do valor digitado pelo usuário para o formato data ou

mostra uma mensagem de data inválida.

• Deve-se informar a data no formato AAAA-MM-DD.

• Pode-se configurar nos parâmetros ‘format’ como ‘DMY’ e separator como ‘/’ para as datas no

formato europeu.

• Atributos:

– invalidDateMessage: mensagem apresentada pelo controle quando o usuário digita uma

data inválida. O padrão é $$$Text(“Invalid Date”,”%ZEN”);

– minDate e MaxDate: opcional; no formato AAAA-MM-DD; indica a menor e a maior data

a considerar no calendário;

– showTime: se verdadeiro, é apresentado além do calendário uma caixa de texto para

informação de horário.

– format: ‘DMY’,’MDY’, ‘YMD’.

– separator: “/”,”.”,”-”

Exemplo:

Page 85: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 84

Planilhas

• O controle <dynaGrid> mostra um grid editável, em duas ou três dimensões, semelhante a uma

planilha.

• É possível criar um <dynaGrid> das seguintes formas:

– Especificar um dataset, linhas e colunas (descrito neste módulo);

Associar o <dynaGrid> a um MVC.

<dynaGrid> com Data Set

• Os dados apresentados em um <dynaGrid> são fornecidos por um objeto

%ZEN.Auxiliary.dataSet.

• dataSet é um objeto especial que contém dados usados para definir uma, duas ou três

dimensões de dados.

• O <dynaGrid> cria automaticamente um objeto dataSet com duas dimensões, com o número de

linhas (dimensão 1) e colunas (dimensão 2) especificados pelo número de entradas <gridRow> e

<gridColumn> dentro da definição do <dynaGrid>.

Page 86: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 85

• O seguinte exemplo especifica 4 linhas e 4 colunas para o objeto dataSet inicial:

• Uma aplicação pode alterar o tamanho e conteúdo do objeto dataSet inicial através da definição

de um método callBack.

• Deve-se especificar o nome deste método no atributo OnCreateDataSet.

• A assinatura do método callback OnCreateDataSet deve ser:

• Onde:

– pGrid: é o objeto dynaGrid que está invocando o callback;

– pDataSet: é o objeto dataSet associado ao objeto dynaGrid;

– O método retorna um valor %Status indicando sucesso ou falha.

Page 87: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 86

• Exemplo de método callBack:

• Quando o método callback altera o objeto dataSet para conter 3 dimensões, isso dá ao

<dynaGrid> a habilidade para movimentar entre “páginas” de dados.

• Cada página é apresentada como um grid de duas dimensões que representa a página atual que

está sendo visualizada.

• A imagem abaixo ilustra este modelo de dados.

Page 88: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 87

Campos Ocultos

• O controle Zen <hidden> é um “mapeamento” do elemento HTML <input type=“hidden”>.

• Está presente em um formulário, e tem um valor (value) associado, mas nunca é visível ao

usuário.

• O valor pode ser alterado programaticamente.

• Os controles <hidden> são submetidos junto com o formulário.

Page 89: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 88

Exercícios - Controles Zen

1. Crie uma nova página Zen com:

1. Pacote: ISCUser.Page;

2. Aplicação: ISCUser.Aplic.Aplication;

3. Nome da Classe: PacienteControles;

2. No cabeçalho da página, insira o texto: Exercício – Controles Zen.

3. Insira um texto no início da página: Cadastro de Pacientes (<label>).

4. Insira um grupo horizontal com:

1. Um texto (<label>): Nome do Paciente:

2. Uma caixa de texto (<text>). Atribua um id.

5. Insira um outro grupo horizontal com:

1. Um texto (<label>): Prioridade:

2. Um conjunto de botões de rádio (<radioSet>) que lê a classe

‘ISCUser.Dados.PacientePrioridade’

e apresente todas as prioridades dos pacientes.

6. Insira outro grupo horizontal com:

1. Um texto (<label>): Adulto:

2. Um checkbox (<checkbox>).

7. Insira outro grupo horizontal com:

1. Um texto (<label>): Sexo:

2. Uma caixa de seleção (<select>) com duas opções: Masculino e Feminino (valores

lógicos 1 and 2).

8. Insira outro grupo horizontal com:

1. Um texto (<label>): Indicação:

2. Um combo box (<dataCombo>) que lê a classe ISCUser.Dados.Paciente e apresente

todos os pacientes. Este combo box deve permitir que o usuário informe os primeiros

caracteres do nome do paciente para filtrar os registros.

9. Insira outro grupo horizontal com:

1. Um texto (<label>): Data de Nascimento:

2. Um calendário (<calendar>) com os dias da semana e o nome dos meses.

10. Insira outro grupo horizontal com:

1. Um botão com o texto: Limpar.

2. Um botão com o texto : Salvar.

3. Um botão com o texto : Deletar.

Page 90: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 89

Page 91: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 90

Módulo – Formulários Zen

Módulo – Formulários Zen

Page 92: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 91

Page 93: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 92

Formulários Zen

• Formulário Zen é um grupo especializado desenvolvido para conter controles.

• Tem os mesmos atributos de estilo e layout de qualquer outro grupo Zen.

• Há dois componentes de formulários disponíveis:

– <form> um grupo Zen que contem uma lista específica de componentes. Estes

componentes podem ou não estar ligados a um data controller. O layout é inteiramente

determinado pela definição do <form> no XData Contents;

– <dynaForm> uma extensão do <form> que insere dinamicamente os controles. A lista de

controles pode ser determinada pelas propriedades de um data controller associado, ou

por um método callback que gera a lista de controles. Layout é automático.

Hierarquia de Classes Zen

Page 94: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 93

Interações com o Usuário

• A interação básica entre o usuário de uma aplicação Zen e um formulário Zen é a seguinte:

1. O usuário interage com os controles no formulário;

2. Zen pode validar os dados no momento que são informados;

3. Uma ação do usuário indica que é para submeter o formulário;

4. Zen pode validar os dados antes de tentar submeter o formulário;

5. Zen interage com o usuário para tratar qualquer erro encontrado;

6. Quando estiver tudo certo, Zen submete os dados do formulário;

7. Então pode ocorrer:

– Dados do formulário podem ser gravados no servidor;

– A mesma página Zen pode ser reapresentada;

– Uma página Zen diferente pode ser apresentada;

– A mesma página Zen pode ser apresentada, mas com componentes

adicionados ou alterados.

Definindo um Formulário

• Os componentes Zen <form> e <dynaForm> suportam vários atributos, entre eles:

– autoValidate: se verdadeiro (padrão), automaticamente valida o formulário

sempre que ele é submetido;

– controllerId: associa o formulário a um data controller que fornece os dados ao

formulário;

– nextPage: próxima página a ser apresentada quando o formulário é submetido

com sucesso;

– onchange: expressão JavaScript invocada quando o valor de um controle deste

formulário é alterado pelo usuário;

Page 95: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 94

Fornecendo valores para um Formulário

• Um formulário pode inicialmente mostrar os campos em branco, ou você pode fornecer os dados

para os campos.

• Fornecer dados para um campo significa atribuir um valor para a propriedade value do controle.

• Há várias formas para fazer isso:

– Atribuir um valor ao atributo value:

<text value=“olá”/>

– Atribuir um valor ao atributo onLoadForm:

<form id=“MeuForm” onLoadForm=“CarregaForm”>

– Atribuir as propriedades value a partir do método da página %OnAfterCreatePage.

Do ..%SetValueById(“Nome”,$G(^formTeste(“Nome”)))

– No lado cliente, chamar o método setValue para cada controle.

Exemplo:

Page 96: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 95

Detectando Modificações no Formulário

• Um formulário Zen rastreia se ocorreram ou não alterações em algum controle do formulário.

• Os métodos isModified dos controles retornam verdadeiro se o valor lógico do controle

(propriedade value) for diferente do valor lógico original (propriedade originalValue).

• Ao chamar o método isModified do formulário, é invocado o isModified de cada controle do

formulário, e se algum deles retornar verdadeiro, então o isModified do formulário retorna

verdadeiro.

Validando um Formulário

• Todo formulário Zen tem um método validate, que valida os valores dos controles do formulário.

• Se o atributo autoValidate for verdadeiro, o método validate é chamado automaticamente cada

vez que o formulário é submetido. No entanto, o método validate pode ser chamado

explicitamente pela aplicação.

• O método validate faz o seguinte:

– Chama o manipulador onvalidate do formulário, se definido. Se este evento retornar

falso, Zen declara o formulário como inválido e não executa demais verificações.

– Zera a propriedade invalid de todos os controles do formulário, e testa cada controle

chamando o método validationHandler de cada controle, que faz:

• Se os atributos readOnly ou disabled forem verdadeiros, retorna verdadeiro;

• Se o atributo required for verdadeiro e o controle não possui um valor, retorna

falso;

• Se o controle define um evento onvalidate, ele é executado e retorna seu valor.

– Como o método validate testa cada controle, um array de controles inválidos é criado;

– Após todos os testes do método validate, se retornar verdadeiro, então o formulário é

válido;

– Se o formulário contiver um ou mais controles com valores inválidos, ele é inválido e as

ações necessárias são tomadas.

Page 97: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 96

Submetendo um Formulário

• A requisição para submeter o conteúdo de um formulário pode ser disparada das seguintes

maneiras:

– O usuário clica em um botão <submit> colocado dentro do formulário;

– A aplicação chama o método submit do formulário em resposta a um evento do usuário:

%form.submit

• Quando um formulário é submetido, os valores dos controles do formulário são enviados ao

servidor e o método %OnSubmit da página que contém o formulário é chamado.

• O método %OnSubmit recebe todos os valores submetidos. Zen automaticamente trata todos os

detalhes da operação submit, incluindo chamadas a métodos no servidor, e processamento de

erros.

• Todos os formulários são submetidos usando o método HTTP POST.

Exemplo:

Page 98: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 97

Page 99: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 98

Formulário para Login

• Um página de login é um caso especial de formulário Zen.

• Por padrão, dependendo das configurações de segurança do Caché, quando um usuário inicia

uma aplicação Zen, uma janela, padrão do Caché, solicitando usuário e senha é apresentado.

• Para criar um formulário de login personalizado, é necessário:

– Criar uma classe de página Zen;

– No bloco XData Contents, inserir um formulário com controles para usuário e senha. O

atributo name dos controles devem respeitar o exemplo:

<page>

<form>

<text name="CacheUserName" />

<password name="CachePassword" />

<submit caption="OK" />

</form>

</page>

– No Portal de Administração, vá em Home Administração de Segurança Aplicações

CSP.

– Clique no botão Editar da aplicação;

– No campo Página de Login informe o caminho e nome da classe da página Zen. Ex.:

/csp/MinhaApl/MinhaPagLogin.cls

– Clique em Salvar.

Page 100: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 99

Exercícios – Formulários Zen

Crie uma nova página chamada Login;

1. Insira um Formulário:

1. Inclua um Text para Login;

2. Inclua um Password para Password;

3. Inclua um botão Submit ;

2. Sobrescreva o método %OnSubmit com o código a seguir:

ClassMethod %OnSubmit(pSubmit As %ZEN.Submit) As %Status

{

Set loginok = 1

Set vuser = pSubmit.%Data("txtusuario")

Set vpass = pSubmit.%Data("txtsenha")

Set rs=##class(%ResultSet).%New()

Set sql="Select Password From ISCUser_Dados.Usuarios Where Login = ?"

Do rs.Prepare(sql)

Do rs.Execute(vuser)

If 'rs.Next() { Do pSubmit.%SetError("formlogin",”Login Inválido“) }

Else {

If rs.GetData(1) '= vpass

{

Do pSubmit.%SetError("formlogin","Invalid Password")

}

Else {

Set UserId = 1

Do %session.Set("UsuarioId",UserId)

Do %session.Set(“NomeUsuario",vuser)

Set pSubmit.%NextPage = ..Link("ISCUser.Pag.Menu.cls")

}

}

Quit $$$OK

Page 101: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 100

Exercícios – Formulários Zen (Controles.)

1. Neste exercício iremos aprimorar a página ISCUser.Pag.PacienteControles criada no módulo

anterior.

2. Faça com que ao ser carregada a página, no calendário que informa a data de nascimento já

venha selecionado o dia atual, e que o checkbox Ativo venha marcado, para fazer isso:

• Crie o método callback %OnAfterCreatePage() e insira:

do ..%SetValueById(“calNasc”,$zdate($horolog,3))

do ..%SetValueById(“chkAdulto”,1)

Quit $$$OK

3. Insira um formulário (<form>) fazendo com que todos os controles da página sejam filhos dele.

4. Altere o botão Salvar para o tipo Submit.

5. Altere a caixa de texto Nome do Cliente para que o seu preenchimento seja obrigatório.

6. Configure o campo Nome do Cliente para apresentar a seguinte mensagem em caso de não

preenchimento: “Informe o Nome do Paciente.”.

7. Configure o formulário para que em casos de erros na validação seja apresentada a seguinte

mensagem: “Falha na Validação da Página.”.

8. Teste a página informando e não informando um valor para o campo Nome do Cliente.

Formulários Dinâmicos

• <dynaForm> é um tipo de formulário especializado que insere dinamicamente os componentes

de controles em uma página Zen.

• Layout é determinado automaticamente pelo código interno do <dynaForm>.

• A lista de controles pode ser determinada pelas propriedades de um data controller associado,

ou por um método callback.

Page 102: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 101

Page 103: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 102

Módulo - MVC

Módulo - MVC

Page 104: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 103

Page 105: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 104

Modelo-Visão-Controle (MVC)

• Para simplificar o fluxo de dados entre a origem dos dados e a página Zen, são fornecidos um

conjunto de classes que definem o modelo de dados (o Modelo) e conecta-o a um conjunto de

componentes Zen (a Visão) através de um objeto intermediário (o Controle).

• Exemplos de usos típicos de MVC:

– Criar um formulário que apresenta um conjunto de propriedades, carregadas a partir de

um objeto persistente do banco de dados. O formulário apresenta automaticamente

controles apropriados para o tipo de dado (data type) de cada propriedade.

– Criar um gráfico baseado em valores de um formulário. O gráfico atualiza-se

automaticamente cada vez que o usuário submete alguma alteração no formulário.

– Mostrar medidores representando um conjunto de valores calculados no servidor. Sempre

que a página é atualizada, os medidores automaticamente atualizam-se com os valores

atuais do servidor.

Arquitetura

Page 106: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 105

Modelo de Dados (Data Model)

• Um modelo de dados define um conjunto de propriedades com nome e valor.

• Um modelo de dados tem a habilidade de recuperar valores de dados de uma ou mais origem (um

objeto persistente, banco de dados externo, ou global) e colocar estes valores em suas próprias

propriedades.

• Estas propriedades então tornam-se disponíveis para serem acessadas por um componente data

controller em uma página Zen.

• O desenvolvedor da classe de modelo de dados é responsável pela implementação dos métodos

que:

– Carrega os valores de uma origem para as propriedades da classe modelo;

– Grava os valores novamente no servidor;

– E valida os valores.

• Há duas variações de classes de modelos de dados:

– Uma subclasse de %ZEN.DataModel.ObjectDataModel é chamada de objeto de modelo

de dados. Contém um conjunto de valores nomeados, que são propriedades

formalmente definidas dentro da subclasse.

– A classe abstrata %ZEN.DataModel.Adaptor define uma interface. Qualquer classe

persistente que implemente esta classe torna-se um modelo de dados.

Controlador de Dados (Data Controller)

• O controlador de dados gerencia a comunicação entre um modelo de dados e uma visão dos

dados.

• É um componente (dataController) que é inserido em uma página Zen junto com outros

componentes, mas não é visível.

• A propriedade modelClass informa o nome da classe de modelo de dados associada.

Page 107: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 106

Visão dos Dados (Data View)

• A visão dos dados é qualquer componente Zen que implemente a interface

%ZEN.Component.dataView.

• Um componente de visualização de dados conecta a um data controller associado em tempo de

execução e usa-o para receber e gravar valores a partir do modelo de dados associado.

• Mais do que um componente de visualização de dados podem “apontar” para o mesmo data

controller.

• A seguir a lista de componentes Zen que implementam a interface %ZEN.Component.dataView,

ou seja, os componentes que visualizam dados (que podem ser ligados a um data controller):

– <dynaGrid>

– Todos os formulários;

– Todos os gráficos;

– Todos os medidores.

Criando um Formulário

• As sequências mostram um exemplo simples de como usar o MVC para criar um formulário.

• Suponha um objeto persistente chamado Dados.Cliente que contém registros de clientes. Este

objeto pode ter dezenas de propriedades. No entanto, nós queremos criar uma página simples

que apenas apresente as informações demográficas, neste caso o nome e a cidade do cliente.

• Passo 1: Modelo de Dados.

– Primeiro, definimos uma classe de modelo de dados (ModeloCliente) que saiba como

carregar e armazenar as propriedades do objeto Cliente:

Page 108: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 107

• Passo 2: Controlador de Dados

– Suponha que já temos criado uma classe de página Zen. Agora inserimos um

componente data controller na página Zen adicionando um elemento <dataController>

no bloco XData Contents.

– Onde:

• id é o nome que os visualizadores de dados usarão para identificar o

dataController.

• modelClass é o nome do pacote e da classe de modelo de dados.

• modelId é o número que identifica o registro a ser carregado inicialmente da

origem de dados.

• Passo 3: Visualizador de Dados

– Agora é possível criar um formulário e conectá-lo ao controlador de dados

(dataController).

– Para isso deve-se configurar a propriedade controllerId do <form> para ser igual a

propriedade id do <dataController>.

– Dentro do formulário criamos 2 controles <text>. E fazemos referência entre os controles

<text> e as propriedades da classe de modelo de dados através do atributo dataBinding.

Page 109: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 108

– Exemplo:

• Cada controle <text> está agora “conectado” a uma propriedade da classe de modelo de dados.

• Passo 4: Resultado

– Quando a página Zen que contém o formulário é apresentada, o componente

dataController cria um objeto Apl.ModeloCliente no servidor, e carrega os dados do

registro número 1 (identificado pelo atribulo modelId do <dataController>) em suas

próprias propriedades.

– O dataController coloca estes dados nos controles apropriados dentro do formulário.

– O atributo dataBinding de cada controle identifica qual propriedade fornece o valor para

cada controle.

– A imagem sequinte mostra o formulário com os valores do registro número 1.

• Um dataController pode ser compartilhado entre vários componentes. Por exemplo, o mesmo

dataController pode fornecer dados para um formulário, um gráfico e um medidor em uma

página Zen.

Page 110: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 109

Formulários Dinâmicos

• O elemento Zen <dynaForm> cria um formulário dinamicamente contendo todas as propriedades

da classe de modelo de dados a que o formulário está conectado através do dataController.

• Desta maneira não é necessário a criação manual dos controles de apresentação do valor de cada

propriedade, como foi utilizado com o elemento <form>.

• O sequência apresenta um exemplo da utilização do <dynaForm>.

• Este simples código cria automaticamente todos os controles necessários para a entrada de dados

de todas as propriedades contidas na classe de modelo de dados (Apl.Cliente).

• O tipo do controle (textbox, checkbox, ...) criado é determinado pelo tipo de dado (data type) de

cada propriedade.

• Onde:

– Como visto anteriormente, o elemento <dataController> conecta-se a um registro de

uma classe de modelo de dados, através dos atributos modelClass e modelId.

– O elemento <dynaForm> cria um formulário dinamicamente com base nas propriedades

da classe de modelo

• Como resultado do simples código apresentado anteriormente, temos a seguinte página Web.

Page 111: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 110

Gravação dos dados do Formulário

• Para gravar os valores de um formulário associado a um dataController, chame o método save do

componente dataController, ou do formulário que está conectado ao data controller.

• O método save retorna ao servidor e grava os dados chamando os métodos apropriados da

classe de modelo de dados.

• A diferença entre chamar o método save do formulário ou do dataController, é que o método save

do formulário, além de gravar as informações, executa a validação do formulário.

Validação dos dados

• Ao invés de aguardar pela validação no servidor, é possível adicionar validação no lado cliente.

Para isso deve-se definir o método IsValidJS de uma propriedade específica na classe de

modelo de dados.

• O código abaixo é um método de classe, JavaScript, que usa a convenção de nome

propriedadeIsValidJS e retorna uma mensagem de erro se o valor da propriedade é inválido ou

‘’ (uma string vazia) se valor estiver OK.

Page 112: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 111

Componentes de Visualização de Dados

• A sequência apresenta a relação de atributos que permitem aos componentes Zen agir como

componentes de visualização de dados.

• Nem todos os componentes Zen suportam estes atributos, a distinção é:

– controllerId e onnotifyView são parte da interface de visualização de dados, então eles

são aplicados a componentes Zen que implementam esta interface, como <dynaGrid>,

formulários, gráficos e medidores;

– dataBinding é adaptável apenas aos componentes que mostram apenas um valor, como

medidores e controles

– controllerId: identifica o dataController para este visualizador de dados. O controllerId

deve ser compatível com o valor do atributo id do componente <dataController>.

– dataBinding: identifica a propriedade do modelo de dados que está “conectada” a este

componente.

– onnotifyView: expressão JavaScript lado cliente que é executada cada vez que o

dataController associado com o visualizador de dados executa um evento.

Classes de Modelos de Dados

• Na maioria dos casos, o Modelo de Dados consiste de dois objetos: o Modelo de Dados que

fornece a interface e o objeto de origem (ou objetos) que fornecem os dados.

• A criação de um Modelo de Dados é feita através da criação de uma subclasse de um tipo

específico de Modelo de Classes e implementando um ou mais métodos callback.

• A forma mais simples de criar um modelo de dados é adicionando a superclasse

%ZEN.DataModel.Adaptor a uma classe persistente. Isto automaticamente fornece a interface

de Modelo de Dados para a classe persistente.

• Para casos personalizados, deve-se criar uma nova classe que deriva de

%ZEN.DataModel.ObjectDataModel e implementar seus vários métodos callback.

• As propriedades de uma classe de Modelo de Dados definem o conteúdo do modelo de dados.

Consumidores de modelos de dados (como formulários dinâmicos) podem usar as definições de

propriedades para apresentar automaticamente o conteúdo do modelo de dados.

Page 113: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 112

Object Data Model x Adaptor Data Model

• Como dito anteriormente, há duas maneiras para trabalhar com classes de modelos de dados:

– Herdando de %ZEN.DataModel.ObjectDataModel: a classe de modelo de dados serve

como um “mapeamento” de uma classe de dados independente. Neste caso deve-se

implementar os métodos que recupera os dados do objeto persistente, grava os dados,

abre o objeto, etc.

– Herdando de %ZEN.DataModel.DataModelAdaptor: torna qualquer classe persistente um

Modelo de Dados. Neste caso você não tem a necessidade de implementar os métodos

básicos para recuperação, gravação dos dados, etc. No entanto a conveniência

oferecida por esta técnica torna a classe pouco flexível.

Page 114: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 113

Personalizando o Modelo de Dados

• Uma das maneiras de personalizar a forma com que as propriedades da classe de modelo de

dados são apresentadas em uma página Zen, é sobrescrever o método callback

%OnGetPropertyInfo.

• Por exemplo, para que uma propriedade Avaliacao seja apresentada em um formulário dinâmico

como uma combobox ao invés de um campo texto (padrão):

• Exemplo: ClassMethod %OnGetPropertyInfo(pIndex As %Integer, ByRef pInfo As %String, pExtended As %Boolean = 0) As %Status

{ Set pIndex = pIndex + 3 #; adiciona um campo no final do formulário Set pInfo("Extra") = pIndex Set pInfo("Extra","%type") = "checkbox" Set pInfo("Extra","caption") = "Extra!" Set pInfo("Extra","label") = "This is an extra checkbox." Set pIndex = pIndex + 1 #; adiciona outro campo no final do formulário Set pInfo("Comments") = pIndex Set pInfo("Comments","%type") = "textarea" Set pInfo("Comments","caption") = "Please enter additional comments:" Set pIndex = pIndex + 1 Quit $$$OK }

• As superclasses de Modelos de Dados fornecem parâmetros de propriedades úteis para

personalizar a forma com que é feita a exibição na página Zen.

• A seguir relação de alguns desses atributos, a utilização deles é opcional:

– ZENCONTROL: tipo do controle a ser usado para mostrar a propriedade dentro do

formulário. Se não definido, Zen escolhe o controle baseado no tipo do dado da

propriedade.

– ZENHIDDEN: 1 (verdadeiro) ou 0 (falso). Se verdadeiro, indica que este é um campo

oculto.

– ZENLABEL: texto usado pela propriedade dentro do formulário.

– ZENREADONLY: 1 ou 0. Se verdadeiro, o controle não pode ser editado pelo usuário.

– ZENSQL: corresponde a propriedade sql que vários componentes Zen possuem.

– ZENSQLLOOKUP: corresponde a propriedade sqllookup que vários componentes Zen

possuem.

– ZENTAB: ordem que o controle é apresentado dentro do formulário.

Page 115: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 114

Exercícios – MVC

1. Modifique a classe persistente ‘PacientePrioridade’, tornando-a uma classe de modelo de

dados. Para isso faça com que herde de %ZEN.DataModel.Adaptor.

2. Crie uma nova página Zen ‘ISCUser.Pag.Prioridade’ e insira:

1. Um componente <dataController> com ligação com o ID de número 1 do objeto da

classe de modelo de dados PacientePrioridade.

2. Um form (<form>) com ligação com o <dataController>.

3. Dois componentes <text>, sendo um para a propriedade ‘Codigo’ e outro para a

propriedade ‘Descricao’.

4. Dois botões que permitam a ‘navegação’ entre registros.

5. Insira o seguinte código ao atributo onclick do botão ‘Anterior’:

onclick="zenPage.anterior(); “

6. Insira o seguinte código ao atributo onclick do botão ‘Próximo’:

onclick="zenPage.proximo(); “

7. Insira o seguinte método JavaScript que fará acesso ao registro prévio.

8. Insira um método JavaScript que fará acesso ao próximo registro.

Exercícios – MVC (Paciente)

1. Crie uma nova classe de modelo de dados chamada ISCUser.MVC.Paciente que herde de

%ZEN.DataModel.ObjectDataModel.

2. Insira nesta nova classe todas as propriedades da classe persistente.

3. Sobrescreva o método ‘%OnNewSource’, que cria uma nova instância do objeto Paciente.

Page 116: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 115

Method %OnNewSource(Output pSC As %Status = {$$$OK}) As %RegisteredObject

{

Set status = ##class(ISCUser.Dados.Paciente).%New()

Quit status

}

4. Crie o método ‘%OnOpenSource’, que abre um objeto:

5. Crie o método ‘%OnLoadModel’, que traz para a classe de modelo de dados os valores das

propriedades do objeto persistente.

6. Crie o método ‘%OnSaveSource’, que salva um objeto.

7. Crie o método ‘%OnStoreModel’, que atualiza a classe de dados com os valores inseridos na

classe de modelo de dados.

Page 117: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 116

8. Crie o método ‘%OnDeleteSource’ , que deleta um objeto.

9. Crie uma nova página Zen, ‘ISCUser.Pag.Paciente’.

10. Insira um <dataController>. Faça com que seja carregado o primeiro registro da classe

de modelo ‘ISCUser.MVC.Paciente ’ criada no passo anterior.

11. Insira um formulário dinâmico ligado ao <dataController> criado anteriormente. Lembre-

se de incluir um valor para o atributo id, será necessário depois.

12. Insira 5 botões após o <dynaForm> para:

1. Ir para o registro anterior.

2. Ir para o próximo registro.

3. Criar um novo registro, que chama o método JavaScript novo();

4. Salvar o registro, que chama o método JavaScript salva();

5. Deletar um registro, que chama o método JavaScript deleta().

13. Codifique os métodos JavasCript: novo(), salva() e deleta(), na página Zen.

Page 118: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 117

14. Modifique a propriedade ‘Prioridade’ na classe de modelo de dados incluindo os parâmetros

ZENSQL e ZENSQLLOOKUP, como a seguir:

ZENSQL = "SELECT ID,Descricao FROM ISCUser_Dados.PacientePrioridade“

ZENSQLLOOKUP = "SELECT Descricao

FROM ISCUser_Dados.PacientePrioridade

WHERE ID = ?“

15. Inclua em algumas propriedades da classe de modelo de dados, parâmetros para a configuração

da aparência, usando:

ZENCONTROL, ZENLABEL, ZENTAB, ...

Page 119: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 118

Módulo MVC – Exercícios Adicionais

Módulo MVC – Exercícios Adicionais

Page 120: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 119

Page 121: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 120

Exercícios Adicionais – Super Classe de Página

Crie uma superclasse de página usando a herança

1. Crie uma superclasse de página para as classes até o momento.

2. Nomeie a classe: ‘ISCUser.Pag.Pagina.cls‘ e faça com que herde de %ZEN.Component.Page.

Para o ‘layout’ use o ‘Default’.

1. Esta superclasse será usada pelas páginas desenvolvidas com MVC e <dynaForm>.

3. Modifique o ‘Xdata Contents’ da superclasse.

1. Abra a classe ‘ISCUser.Pag.Paciente’ e copie o conteúdo do XData Contents.

2. Cole no ‘Contents’ de Pagina.cls.

3. Mude o título em html por “Title”. 4. No <dataControler>

1. Altere o parâmetro modelClass:

De: "ISCUser.MVC.Paciente“ -> Para: " #(%page.ClasseModelo)# "

2. Altere o parâmetro modelId:

De: “1“-> Para: "#(%page.ModelId)#”

5. Crie o parâmetro.

Parameter CLASSEMODELO As %String;

6. Crie as propriedades.

Property ClasseModelo As %String [ InitialExpression = {..#CLASSEMODELO} ];

Property ModelId As %String(ZENURL = "ModelId");

7. Altere o id do ‘controller’ para id = “controller” e o id do ‘form’ para id = “form”.

8. Copie os métodos de instância da classe de página ‘Paciente.cls’ para a ‘Pagina.cls’.

9. Faça alterações nos métodos:

1. Altere zenPage.getComponentById('orgPaciente'); para

zenPage.getComponentById('controller');

2. Altere zenPage.getComponentById('frmPaciente'); para

zenPage.getComponentById('form');

Page 122: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 121

Exercícios Adicionais – Usando relacionamentos

1. Crie as páginas ‘ISCUser.Pag.Exames.cls’ e ‘ISCUser.Pag.ExamesItem.cls’.

2. Faça com que herdem de ‘ISCUser.Pag.Pagina’, a superclasse para páginas.

3. Salve e compile.

4. Em ‘Exames.cls’:

1. Crie: Parameter CLASSEMODELO = “ISCUser.Dados.Exames";

2. Elimine o ‘XData Style’ e o ‘Contents’.

3. Remova os parâmetros ‘APPLICATION’ e ‘DOMAIN’.

5. Em ‘ExamesItem.cls’:

1. Crie: Parameter CLASSEMODELO = “ISCUser.Dados.ExamesItem";

2. Elimine o ‘XData Style’ e ‘Contents’.

3. Remova os parâmetros ‘APPLICATION’ e ‘DOMAIN’.

6. Crie a página ‘ISCUser.Pag.Menu.cls’ e links para acessar as páginas:

1. Use: <html><a href=”...”>...</a></html>

1. <html><a href="ISCUser.Pag.Paciente.cls">Pacientes</a></html>

2. <html><a href="ISCUser.Pag.Prioridade.cls">Prioridades</a></html>

3. <html><a href="ISCUser.Pag.Exames.cls">Exames</a></html>

4. <html><a href="ISCUser.Pag.ExamesItem.cls">Itens dos Exames</a></html>

5. Observe o funcionamento da herança, veja que os campos e botões já foram

criados.

Exercícios Adicionais – Fazendo pesquisas usando <tablePane> e manipulando métodos

1. Crie a página ‘ISCUser.Pag.PesquisaItens.cls’.

2. Adicione um componente <tablePane>.

3. Crie colunas na <tablePane> para as colunas, ‘ID’, ‘Tipo’ e ‘Quantidade’ da tabela

‘ISCUser_Dados.ExamesItem’.

4. Mostre a descrição do ‘Tipo’, fazendo:

colName = “Tipo->Descricao," observe que a seta (->) é um ‘join’ entre as tabelas ‘Exames’ e

‘Itens’. Adicione um header.

5. Adicione um navegador para os dados:

Para isso: useSnapshot = 'true‘ e pageSize = ‘10 ‘ na definição da <tablePane>.

6. Adicione um link na classe 'ExamesItem.cls‘ para pesquisar todas as requisições e itens

requisitados.

Page 123: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 122

Abra a classe 'ExamesItem.cls'. Onde deveria ser colocado o link?

Para isso temos que modificar a superclasse de página e não a classe de itens diretamente.

Abra a classe ‘Pagina.cls’ e insira após os botões:

<vgroup width="30%">

<pane paneName="Links" width="100%"/>

</vgroup>

7. Na classe ‘ExamesItem’ crie um 'XData Links‘ e dentro um <pane> e dentro dele um link para a

página de pesquisa criada anteriormente. Vá em Classe->Adicionar->Novo Xdata.

Observe que o nome do Xdata é o mesmo que foi atribuído ao parâmetro ‘paneName’

anteriormente.

XData Links [ XMLNamespace = "http://www.intersystems.com/zen" ]

{

<pane xmlns="http://www.intersystems.com/zen">

<vgroup align="left">

<link href="ISCUser.Pag.PesquisaItens.cls" caption=“Pesquisa Itens "/>

</vgroup>

</pane>

}

8. Em ‘PesquisaItens.cls', para facilitar a pesquisa pode-se filtrar os itens por exames, adicione na

classe:

Property ExameId As %String (ZENURL = “exame");

Receberemos como parâmetro de url o id do exame e usaremos como filtro para a query na

pesquisa.

9. Adicione entre <table…> e </table …> um elemento <parameter>.

Na definição da <tablePane> uma cláusula where: whereClause = “Exame = ?".

'Exame’ é o nome da coluna da tabela.

<parameter value="#(%page.ExameId)#"/>

10. Teste o funcionamento chamando a url e passando um parâmetro:

http://localhost: <port> /csp/user/ISCUser.Pag.PesquisaItem.cls?exame = 1

Deveriam ser listados somente os itens daquele exame.

Page 124: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 123

Exercícios Adicionais– Usando ‘launchPopupWindow'

11. Retorne para a página de cadastro de exames e crie um link para a pesquisa, faça isso:

1. Crie o XData Links.

2. Depois: <link href="javascript: zenPage.pesquisa();" caption=“Pesquisa Exames"/>

12. Crie o método pesquisa():

Method pesquisa() [ Language = javascript ]

{

var link = 'ISCUser.Pag.PesquisaExames.cls';

zenPage.launchPopupWindow(link,’Página de Pesquisa -

Exames','status,scrollbars,resizable,top=100,left=100,width=400,height=500');

}

13. Em ‘PesquisaExames.cls‘ na definição da <tablePane> adicione:

<... valueColumn="ID" ... onselectrow="zenPage.fire();" ...>

Onde: o primeiro parâmetro é o valor a ser retornado quando você seleciona uma linha e o

segundo o método a ser invocado.

14. Crie o método fire(): observe que a tabela é referenciada pelo id, neste caso ‘tblExames’,

'getValue ()‘ é usado para pegar o valor que foi selecionado.

Method fire() [ Language = javascript ]

{

var idTabela = zenPage.getComponentById(‘tblExames').getValue();

zenPage.firePopupAction('Action', idTabela);

}

Onde: 'Action‘ é uma ação qualquer e idTabela é o valor atribuído ao ‘valueColumn’.

Page 125: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 124

Neste ponto você ainda não poderá testar.

15. Na página ISCUser.Pag.Exames.cls sobrescreva o método onPopupAction (Classe->

sobrescrever) e atribua ao parâmetro modelId do <dataController> o valor recebido da linha

selecionada.

Method onPopupAction(popupName, action, value) [ Language = javascript ]

{ var controller = zenPage.getComponentById('controller'); controller.setModelId(value);

}

'Action‘ e 'value‘ são os valores retornados pelo método fire ();

setModelId atribui ao controller o id selecionado na pesquisa e retornado em value.

16. Altere agora ‘ExamesItem‘ e ‘PesquisaItens'. Abra a pesquisa numa janela popup.

17. Faça alterações: 1. Em ‘Exames’, inclua um link para o cadastro 'ExamesItem.cls‘

<link href="javascript: zenPage.chamaItem();" caption=“Cadastro de Itens"/> 2. Crie o método chamaItem().

Veja que estamos enviando o id (pai) para o cadastro dos itens (filhos). Method chamaItem() [ Language = javascript ] { var controller = zenPage.getComponentById('controller'); var id = controller.getModelId(); if (id=='') { alert(‘Pesquise um exame!'); return; } var link = "ISCUser.Pag.ExamesItem.cls?exame=“ + id; location.href = link; }

18. Na classe 'ExamesItem.cls' crie a propriedade.

Property ExameId As %String(ZENURL=“exame");

19. Na classe 'ExamesItem' crie o método atualiza() que será chamado por 'onloadHandler‘:

Method atualiza() [ Language = javascript ] { var controller = zenPage.getComponentById('controller');

Page 126: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 125

controller.setDataByName('Exame',zenPage.ExameId); // informa a tela para atualizar... zenPage.getComponentById('form.Exame').setValue(zenPage.ExameId); zenPage.getComponentById('form.Exame').setProperty('disabled',"true"); }

Confia as mudanças. Veja que o campo ficou protegido.

20. Sobrescreva o método 'onloadHandler‘ e chame o método atualiza(): zenPage.atualiza (); dentro de 'onloadHandler‘;

21. Para filtrar os itens, para a pesquisa de itens, passe o id como parâmetro de url na página onde a pesquisa é chamada:

1. Abra a classe ‘ExamesItem.cls’ e modifique o link para 'javascript: zenPage.pesquisa (); “ 2. Adicione um caption. 3. No método pesquisa () altere o link para a chamada de itens. Passe o id do exame. 4. Teste.

Page 127: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 126

Exercícios Adicionais – usando ‘OnGetPropertyInfo' Na tela de cadastro de exames, queremos o Nome do paciente e não o ID e na tela que itens queremos a Descrição e não o ID do tipo, como faríamos isso? Lembre-se não possuímos um ‘form’ para manipular diretamente. Para manipular os campos da tela temos que sobrescrever o método ‘%OnGetPropertyInfo’ na classe de modelo de dados ou usar o parâmetro "OnGetPropertyInfo" do <dynaForm> que deve chamar um método na página, cujo nome é especificado neste parâmetro. Os parâmetros dos campos serão informados neste método. O método deve ter uma assinatura padrão: vamos chamá-lo PropriedadeInfo.

Method PropriedadeInfo (pIndex As %Integer,ByRef pInfo As %String,pModelId As %String) As %Status { Set pInfo("Field1") = pIndex Set pInfo("Field1","%type") = "textarea" Set pInfo("Field1","label") = "LabelField1: " ... Quit $System.Status.OK() }

22. Faça as alterações necessárias.

1. Em 'Exames.cls' atribua parâmetros para a propriedade ‘Paciente’: veja o nome da propriedade na classe de dados se necessário.

Method PropriedadeInfo(pIndex As %Integer, ByRef pInfo As %String, pModelId As %String) As %Status { Set pInfo("Paciente","sql") = "Select ID,Nome

From ISCUser_Dados.Paciente Order By Nome"

Set pInfo("Paciente","sqllookup") = "Select Nome From ISCUser_Dados.Paciente Where ID = ?"

Quit $System.Status.OK() }

23. Na superclasse faça alterações na definição do <dynaform> no parâmetro OnGetPropertyInfo = "PropriedadeInfo”.

24. Teste suas alterações.

Page 128: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 127

Page 129: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 128

Módulo - Relatórios Zen

Módulo - Relatórios Zen

Page 130: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 129

Page 131: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 130

Relatórios Zen

• Zen fornece um framework extensível para a criação de relatórios no formato XHTML ou PDF.

• A criação de um relatório exige 3 passos:

1. O desenvolvedor cria uma classe de relatório Zen e, dentro dela, fornece dois blocos

XML:

– XData ReportDefinition que define os dados

– XData ReportDisplay que define o layout

2. O desenvolvedor ou usuário final gera a saída informando a URI da classe do relatório

em um browser, ou chamando o método GenerateReport a partir da linha de comando

ou de dentro da aplicação. O tipo da saída deve ser informado: XHTML ou PDF.

3. A classe do relatório direciona os dados e as informações de exibição através de uma

das duas seqüências: XHTML ou PDF.

Page 132: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 131

XData ReportDefinition

• O bloco XData ReportDefinition especifica os dados a apresentar no relatório.

• Também descreve como formatar estes dados em XML.

• Pode conter referências a seguinte variável:

– %val – o valor do atributo field no mesmo elemento.

• E pode conter os seguintes elementos XML:

– <report> - identifica a query que retorna os dados;

– Que contém os seguintes elementos em qualquer ordem e quantidade:

• <element> - escreve um elemento XML;

• <attribute> - escreve um atributo XML;

• <aggregate> - calcula totais, médias para o relatório.

– Contem 0 ou 1:

• <group> - agrupa itens para que operações possam ser executadas em grupo.

• É possível omitir ou sobrescrever o bloco XData ReportDefinition se for fornecido um valor válido

para o parâmetro de classe DATASOURCE.

• Se for fornecido o parâmetro de classe e o bloco XML, o valor do parâmetro terá preferência.

<report>

• O elemento <report> é o container de nível mais alto dentro do bloco XData ReportDefinition.

• Um <report> pode conter vários elementos <element>, <attribute> e <aggregate> em qualquer

ordem.

• Um <report> pode conter um <group>. Cada <group> pode conter um outro <group>.

• <report> requer um atributo name e alguma combinação de atributos de query.

Page 133: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 132

<element>

• O elemento <element> é válido dentro de um <group> ou <report>.

• Cada <element> adiciona um elemento XML no documento XML.

• Tem os seguintes atributos:

– expression: Opcional. Pode ser usado para processar o valor de field antes de gerá-lo. A

linguagem da expressão deve ser COS. Dentro da expressão, a variável %val

representa o valor de field. O atributo expression pode ser usado sem o atributo field

para retornar um dado estático como a data do relatório. Ex.:

<element name=“dataAtual” expression=‘$ZDate($Horolog,3)’ />

– field: especifica uma coluna do resultset.

– name: gera um elemento XML deste nome na saída. Uma entrada como esta:

<element name=“meuMes” field=‘mes’ />

Produz um elemento XML assim:

<meuMes>Julho</meuMes>

<attribute>

• O elemento <attribute> é válido dentro de um <group> ou <report>.

• <attribute> funciona exatamente igual ao <element>, mas a sua informação é gerada como um

atributo do elemento <group> ou <element> que o contém.

<aggregate>

• O elemento <aggregate> pode aparecer dentro de um <group> ou <report>.

• <aggregate> executa cálculos sobre todos os registros do resultset retornado pela query do

<report>.

• Tem os seguintes atributos:

– type: especifica o tipo de cálculo a executar. Os valores possíveis são: “SUM”, “COUNT”,

“AVG”, “MAX”, “MIN”, “CLASS”, “CUSTOM”.

– class: se o type for igual a CLASS, deve especificar o nome do pacote e da classe que

deriva de %ZEN.Report.CustomAggregate.

– method: se o type for igual a CUSTOM, deve especificar um nome de método lado-

servidor da classe do relatório Zen.

Page 134: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 133

<group>

• O elemento <group> indica que o Zen deveria executar o mesmo conjunto de operações em todos

os registros do resultset compatíveis com um critério especificado.

• Se o <group> não especifica nenhum critério, Zen executa as operações do <group> em cada

registro do resultset.

• Os elementos contidos dentro do <group> especificam o que fazer.

• Um <report> pode conter um <group>. E cada <group> pode conter outro <group>.

• Apenas um <group> deve existir em cada nível.

• Atributos dos elementos <group> e <report>:

– name: o elemento <group> gera um elemento XML com este nome no arquivo de saída

XML.

– breakOnField: o termo breakOnField significa: “Se encontrar este campo, pare para

examinar seu valor”. Todos os registros do resultset que contém o mesmo valor no

campo especificado por este atributo são processados juntos.

Se este atributo não for informado, o <group> processa todos os registros do resultset da

mesma forma.

O campo informado neste atributo, deveria estar ordenando o resultset, pois o resultset é

examinado sequencialmente e cria uma parada sempre que o campo especificado muda.

Então se a query não estiver ordenada por este campo, uma parada pode ocorrer

inesperadamente.

– breakOnExpression: Fornece uma expressão a aplicar ao valor do campo especificado

por breakOnField.

A linguagem da expressão deve ser COS.

Por exemplo, suponha que você queira agrupar por mês, e você tem um método na

classe de relatório Zen chamado LeMes que lê uma data e retorna o mês. Então você

poderia fornecer um <group> como este:

<group name=‘mes’ breakOnField=‘data’ breakOnExpression=‘..LeMes(%val)’>

Page 135: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 134

• Um <group> ou <report> pode especificar uma query. A seguir relação de atributos que suportam

query.

– sql: Opcional. Query SQL que retorna o conteúdo da lista <select>.

– queryClass: Opcional. Nome da classe que contém uma query. O atributo queryName

deve ser também fornecido.

– queryName: Opcional. Nome da query da classe que fornece o %ResultSet para lista

<select>. O atributo queryClass deve ser também fornecido.

– OnCreateResultSet: Opcional. Nome de um método callback que cria um objeto

%ResultSet.

Exercícios – Relatórios

1. Crie uma nova página de relatório Zen com:

1. Pacote: ISCUser.Rel

2. Nome da classe: Paciente

3. Nome do relatório: Paciente

2. O ‘wizard’ solicitará que você informe uma ‘query’ que suprirá os dados para o relatório, digite :

Select ID,Nome,Cidade,Estado,Sexo,Adulto,Prioridade->Descricao as Prioridade

From ISCUser_Dados.Paciente

Order By Prioridade,Nome

3. O ‘wizard’ criará e apresentará uma classe de relatório Zen com alguns parâmetros e os blocos

XData ReportDefinition e XData ReportDisplay.

4. Um relatório consiste de um ou mais agrupamentos. Defina o primeiro grupo adicionando um

elemento <group> dentro do XData ReportDefinition. Informe o seguinte código depois do

comentário existente neste bloco e antes de </report>.

<group name="Prioridade" breakOnField="Prioridade“></group>

5. Compile e veja a página web gerada.

6. Adicione um elemento <attribute> dentro do <group>:

<attribute name=“nome” field=“Prioridade” />

Page 136: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 135

7. Compile e veja a página web gerada.

8. Adicione um elemento <aggregate> entre o element <attribute> e </group>

<aggregate name="qt" type="COUNT" field="ID" />

9. Adicione dentro de <group> mais um elemento <group> e mais elementos <element> no bloco

XData ReportDefinition.

<group name="Paciente" breakOnField="ID">

<element name="Cidade" field="Cidade"/>

<element name=“Estado" field=“Estado"/>

<element name="Sexo" field="Sexo"/>

<element name="Adulto" field="Adulto"/>

<attribute name=“Nome" field=“Nome"/>

</group>

Page 137: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 136

XData ReportDisplay

• O bloco XData ReportDisplay é responsável pela especificação da apresentação dos dados

obtidos pelo bloco XData ReportDefinition.

• Os estilos no bloco XData são independentes do formato de saída.

• Um relatório pode ser chamado/iniciado a partir do browser ou da linha de comando de um

Terminal.

• O relatório pode gerar a sua saída nos formatos XHTML e PDF.

Elementos do bloco XData ReportDisplay

– <element>: identifica o título. Contém os seguintes elementos (na seguinte ordem):

• <document> - características gerais da página, principalmente para formato

PDF.

• <pageheader> - cabeçalhos da página, usado no PDF e opcionalmente no

HTML.

• <pagefooter> - rodapés da página, usado no PDF e opcionalmente no HTML.

• <body> - container de elementos que controlam:

– Layout Gráfico;

– Estilo e Aparência;

• É possível omitir o bloco XData ReportDisplay completamente, desde que seja informado uma

valor válido para os parâmetros de classe HTMLSTYLESHEET e XSLFOSTYLESHEET.

• É também possível omitir o XData ReportDisplay se quiser usar a classe de relatório Zen para

apenas gerar arquivos de dados XML.

<report>

• O elemento <report> é o container de nível mais alto em um bloco XData ReportDisplay.

• Ele pode conter apenas os seguintes elementos, na seguinte ordem e quantidade:

– <document> (0 ou 1)

– <pageheader> (0 ou 1)

– <pagefooter> (0 ou 1)

– <body> (1).

• O elemento <report> tem os seguintes atributos:

Page 138: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 137

– name: o nome do relatório, que deve ser compatível com o nome do relatório no bloco

XData ReportDefition.

– title: o título do relatório, usado por itens como o nome do arquivo PDF ou título da

página XHTML.

– style: se style=“none”, a folha de estilo padrão Zen não é “desenhada”, do contrário é.

A folha de estilo padrão é uma coleção de classes de estilo disponíveis que incluem

p.banner1, table.table1, td.table1, th.table1, ...

<document>

• O elemento <document> é aplicado principalmente para saída PDF.

• Especifica características de layout física como dimensões de páginas e margens.

• Pode conter vários elementos <class>, <xslinclude> e <cssinclude> para personalizar o estilo.

• Se for omitido, mesmo se for gerar um PDF, características de layout padrão são aplicados, como

tamanho de página de 8.5x11 polegadas.

• O elemento <document> tem os seguintes atributos:

– headerHeight: especifica a altura do bloco destinado ao cabeçalho, entre a margem

superior e o corpo do relatório.

– footerHeight: especifica a altura do bloco destinado ao rodapé.

– height: especifica a altura da página.

– width: especifica largura da página.

– marginBottom: especifica a margem inferior.

– marginLeft: especifica a margem esquerda.

– marginRight: especifica a margem direita.

– marginTop: especifica a margem superior

O elemento <class> cria estilos CSS a serem aplicados no relatório.

Os subelementos <att> descrevem as características do estilo.

Para fornecer o seguinte fragmento de documento CSS:

Page 139: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 138

É necessário o seguinte elemento <class> e elementos <att>:

• O elemento <cssinclude> referencia um arquivo de estilos CSS externo e a ser aplicado em saídas

XHTML.

• O elemento <xslinclude> referencia um arquivo de estilos CSS externo a ser aplicado em saídas

PDF.

• Exemplo: para importar a classe th.minhaTabela de arquivos externos, o elemento <document>

deveria conter:

• Com o arquivo meuEstilo.css contendo:

• E meuEstilo.xsl contendo:

<pageheader>

• O elemento <pageheader> contém o cabeçalho do relatório. Se presente no <report>, deve estar

antes do elemento <body>.

• Pode conter os mesmos elementos de layout e aparência descritos em <body>, mas todo o seu

conteúdo é apresentado no espaço em branco fornecido pelo atributo headerHeight do elemento

<report>.

• Relatórios XHTML não suportam o cabeçalho página-a-página, então o cabeçalho é apresentado

apenas no início do relatório.

Page 140: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 139

<pagefooter>

• O elemento <pagefooter> contém o rodapé do relatório. Se presente no <report>, deve estar antes

do elemento <body>.

• O rodapé não é apresentado em relatórios XHTML.

<body>

• Deve estar localizado obrigatoriamente dentro de <report>.

• Não tem atributos, mas contém a maior parte das informações do relatório.

• Contém elementos que controlam:

– Layout gráfico;

– Estilo e aparência.

Page 141: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 140

Elementos de Layout e Apresentação

• Abaixo relação de elementos que apresentam o conteúdo visual ao relatório. Podem estar

contidos em <pageheader>, <pagefooter>, <body>, ou <group>:

– <barChart>, <lineChart> e <pieChart> - gráfico de barras, linhas e pizza;

– <block> - grupo de itens para uma tabela em linha ou coluna;

– <header> e <footer> - grupo de itens do cabeçalho e rodapé da página;

– <group> - grupo de itens para ações repetidas;

– <img> - imagem;

– <item> - valor de um dado;

– <line> - linha horizontal;

– <list> - lista numerada ou com marcadores;

– <p> - texto de qualquer tamanho;

– <table> - tabela

Elementos de Layout e Apresentação – Atributos

• Cada um dos elementos listados anteriormente possui 3 atributos.

• Os elementos podem também ter atributos específicos conforme a sequência.

– class: classe de estilo CSS a ser aplicado ao elemento. Classes de estilo são definidos

por elementos <class>.

Exemplo: <table class=‘minhaTabela’ ...>

– style: informa as características de estilo do elemento.

Exemplo: style=“fill:yellow; font-size: 6pt ;”

– width: largura do elemento.

• Os elementos podem também ter atributos específicos conforme a sequência.

<block>

• O elemento <block> “desenha” todos os seus elementos-filhos sequencialmente.

• Pode ser usado em qualquer lugar no <report> como um tipo de elemento de expansão, mas é

mais útil como um container dentro do <table>.

• Em geral, o <table> trata cada elemento-filho como uma nova linha e coluna, então o elemento

<block> pode ser usado para agrupar vários elementos em uma única linha ou coluna.

Page 142: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 141

<group>

• Permite o relatório Zen apresentar dados estruturados hierarquicamente, que é típico de XML.

• Além dos atributos comuns, ainda contém:

– line: especifica a densidade da linha a ser desenhada entre cada iteração do <group>.

Se o valor for 0, a linha não é criada.

– name: apresenta o conteúdo dos dados XML cujo nome é compatível com este atributo.

Então, se os dados XML contém elementos <Clientes>, o bloco XData ReportDisplay

deveria conter: <group name=“Clientes”> ... </group>

Pode haver outro <group> dentro de um <group>. Ex.:

<group name=“Clientes”> <group name=“Vendas”> ... </group></group>

– pagebreak: se verdadeiro, é inserido uma quebra de página a cada iteração de <group>.

<header> e <footer>

• Os elementos <header> e <footer> são simples containers que identificam os elementos a serem

apresentados no cabeçalho e rodapé da página.

<img>

• Insere uma imagem no relatório.

• Além dos atributos comuns, ainda possui:

– height: especifica a altura da imagem;

– width: especifica a largura da imagem;

– src: URI da origem da imagem. Se o atributo src iniciar com um ponto de exclamação,

ele é interpretado como uma expressão XPath. Isto permite a você criar URIs

dinamicamente dentro de dados XML, e então usar estas URIs customizadas como

origem da imagem.

Page 143: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 142

<item>

• O elemento <item> mostra um valor literal ou um valor a partir de XML no relatório.

• Deve ter UM dos seus atributos value, field ou special especificado.

• Além dos atributos comuns, ainda possui:

– field: apresenta o valor de um campo XML. field é geralmente usado com expressões

XPath, então se você tem o dado:

<Vendas id=‘1’><cliente>ABC Systems</cliente></Vendas>

Para obter o valor o atributo id você precisa da expressão XPath: field=‘@id’.

Entretanto para obter o valor do elemento <cliente> você precisa da expressão XPath:

field=‘cliente’.

O atributo field é interpretado com relação ao atual <group> compatível. Para um <item>

dentro de <group name=‘Vendas’>, apenas atributos de <Vendas> e seus filhos são

disponíveis.

– link: cria um hyperlink sobre o dado apresentado.

– special: apresenta dados dinâmicos pré-definidos:

• number – mostra o número do registro dentro do grupo.

• page-number – insere o número da página em um relatório PDF.

• page-count – insere o número de páginas em um relatório PDF.

• page-number-of – insere o número da página no formato ‘2 of 18’ em um

relatório PDF.

• page-number-/ - insere o número da página no formato ‘2/18’ em um relatório

PDF.

As referências ao contador de total de páginas podem ser lentas em extensos relatórios PDF.

– formatNumber: String que especifica o formato de número a usar. Esta string usa as

mesmas convenções como a função XSLT format-number. Ex.: ###.# representa um

número de 3 dígitos com 1 casa decimal.

– value: apresenta o valor literal do atributo.

Page 144: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 143

<line>

• Insere uma linha no relatório. Pode ser tanto uma linha horizontal visível como apenas um espaço

horizontal.

• Além dos atributos comuns, ainda possui:

– align: alinhamento dentro da página do relatório. Possíveis valores são: “left”, “right”, e

“center”.

– pattern: possíveis valores são “empty”, “solid” e “dashed”.

– color: cor da linha no formato CSS. Aplica-se apenas à linhas do tipo solid ou dashed.

– count: quantidade de linhas a apresentar.

– length: especifica o comprimento da linha.

– thickness: especifica a densidade da linha. Aplica-se apenas à linhas do tipo solid ou

dashed.

– lineHeight: altura em branco reservada para a linha.

<list>

• Usado para apresentar uma lista (numerada/ordenada) em um relatório Zen.

• O atributo style aplica-se aos marcadores ou números.

• Além dos atributos comuns, possui ainda:

– group: Obrigatório. Identifica o grupo que fornece os valores para a lista. Deve ser

compatível com algum grupo definido no bloco XData ReportDefinition.

– image: A URI de uma imagem a ser apresentada como um marcador personalizado.

– startvalue: o valor do primeiro item da lista. Seu valor é sempre especificado como um

valor inteiro.

– type: o estilo do marcador ou numeração a usar na lista. Possíveis valores são: “none”,

“circle”, “square”, “disc”, “1”, “A”, “a”, “I”, “i”. Relatórios PDF não suportam “square” ou

“circle”.

Page 145: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 144

<p> e <pagebreak>

• <p> cria um bloco de conteúdo estático.

• Trata seu conteúdo como texto puro e usa a opção “p” para a classe de estilo.

• <pagebreak> insere uma quebra de página em relatórios PDF.

• Insere uma linha tracejada em relatórios XHTML apresentados em tela, e quebra a página quando

o relatório XHTML é impresso.

<table>

• Cria uma tabela no relatório. Além dos atributos comuns, ainda possui:

– align: alinha o relatório dentro do relatório. Os valores possíveis são “left”, “right” e

“center”.

– orient: cada elemento contido dentro da tabela é tratado ou como uma linha ou como

uma coluna, dependendo do valor deste atributo. Os valores possíveis são “col” e “row”.

– group: uma tabela pode ser usada para mostrar um grupo de dados. Se este atributo é

especificado, a tabela mostra uma linha ou coluna na tabela para cada item no grupo.

– altcolor: valor CSS que especifica a cor de fundo para linhas alternadas (2,4,6,..). É

apenas possível quando orient é “col” e group é definido.

– layout: identifica se o tamanho das linhas e colunas são fixas ou determinados

automaticamente. Os valores possíveis são: “auto” e “fixed”.

Page 146: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 145

Exercício – Relatório Paciente (cont.)

10. Continuando com a classe de relatório criada no início deste módulo, iremos especificar como

apresentar os dados gerados na primeira parte do exercício em XHTML ou PDF.

11. Um relatório básico consiste de um <body> e elementos de apresentação. Adicione <body> e

<p> no bloco XData ReportDisplay:

12. Modifique o valor do parâmetro de classe ‘DEFAULTMODE’ de "xml“ para "HTML“.

13. Compile e visualize os relatório.

14. Adicione a seguinte tabela no bloco XData ReportDisplay

<report xmlns="http://www.intersystems.com/zen/report/display" name="Paciente">

<body>

<p class="Banner1"> Relatório de Pacientes por Prioridade </p>

<group name="Prioridade" line="1px">

<table orient="row" width="4in">

<item field="@nome" width="2in“><caption value="Prioridade:" width="2in"/></item>

<item field="qt“><caption value=“Qtd. Pacientes:"/></item>

</table>

</group>

</body>

</report>

Onde:

• <group name=“Prioridade”> é uma referência ao elemento <Prioridade> no XML

gerado.

• <item field=“@nome” é a sintaxe para referenciar o atributo ‘nome’.

• <item field=“qt” é a sintaxe para referenciar o atributo ‘qt’.

Page 147: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 146

15. Faça as modificações necessárias no bloco XData ReportDisplay como apresentado abaixo:

<line pattern="empty"/>

<table orient="col" group=“Paciente" altcolor="#FFDFDF" width="3.8in">

<item field=“Nome" ><caption value=“Nome:"/></item>

<item field=“Cidade" ><caption value="Cidade:"/></item>

<item field=“Estado" ><caption value=“Estado:"/></item>

<item field=“Sexo" ><caption value=“Sexo:"/></item>

<item field=“Adulto" ><caption value="Adulto:"/></item>

</table>

</group>

</body>

</report>

Page 148: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 147

Gráficos em Relatórios Zen

• Relatórios Zen suportam apenas os elementos <lineChart>, <barChart> e <pieChart>.

• <lineChart> não suportam marcadores ou linhas preenchidas em relatórios Zen.

• Gráficos em relatórios Zen não são interativos.

• A squência apresenta a relação de atributos disponíveis nos gráficos em relatórios:

– dataFields: lista de campos separados por vírgula para obter os dados.

– dataGroup: especifica o grupo que fornece os elementos de dados para o gráfico.

– seriesColors: lista de valores CSS de cores separadas por vírgula usada para as séries

de dados.

– seriesCount: número de séries de dados a apresentar no gráfico.

– seriesGroup: o grupo que fornece a lista de séries para o gráfico.

– seriesNames: lista de nomes separados por vírgula usado como título para cada série de

dados na caixa de legenda.

Exercícios – Relatórios (cont.)

16. O seguinte código insere um gráfico no seu relatório. Adicione o código ente </p> e <group>:

<barChart width="4in" height="3in" title=“Pacientes por Prioridade"

dataFields="!qt" dataGroup=“Prioridade">

</barChart>

Onde:

dataGroup=“Prioridade” é uma referência ao elemento categoria no XML gerado.

dataFields=“!qt” é a sintaxe que referencia o elemento <qt> no gráfico.

17. Compile a classe e visualize o gráfico gerado.

Page 149: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 148

Relatórios Zen a partir do Browser

• Os relatórios XHTML ou PDF podem ser visualizados em um browser informando a URI do

arquivo .cls.

• Para especificar o formato de saída use o parâmetro $MODE na URI. Por exemplo:

– Para visualizar um relatório em formato HTML:

http://localhost:57772/csp/Apl/Apl.Relatorio.cls?$MODE=html

– Para visualizar um relatório em formato PDF:

http://localhost:57772/csp/Apl/Apl.Relatorio.cls?$MODE=pdf

Para visualizar em formato PDF deve-se instalar e configurar uma ferramenta de

terceiros. A documentação Zen descreve este procedimento.

– Para visualizar os dados do relatório em formato XML:

http://localhost:57772/csp/Apl/Apl.Relatorio.cls?$MODE=xml

Relatórios Zen a partir da Linha de Comando

• É possível executar um relatório Zen a partir da linha de comando, fazendo o seguinte:

1. Alterar para o namespace que contem a classe do relatório:

ZN "meuNameSpace"

2. Criar uma instância da classe do relatório:

Set relatorio = ##class(meuPacote.MinhaClasse).%New()

3. Executar o relatório:

Do relatorio.GenerateReport("C:\Temp\MeuExemplo.pdf",2)

Onde:

• C:\Temp\MeuExemplo.pdf é o caminho do arquivo a criar.

• 2 é o tipo da saída do relatório. Possíveis valores incluem:

• 0 – XML

• 1 – XHTML

• 2 – PDF

• 3 – HTML (depuração)

• 4 – XSLFO (depuração)

Page 150: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 149

Exercícios Adicionais – Pré Relatório e datas

1. Em 'Exames.cls', adicione um link que irá chamar um relatório por data.

Você pode apresentar como uma janela ‘popup’ ou outra janela do ‘browser’.

1. Chame 'ISCUser.Pag.PreExame.cls‘

2. Crie uma página pré relatório onde irá informar as datas a serem usadas como filtro no

relatório. Salve como ‘ISCUser.Pag.PreExame.cls’. Esta página irá chamar o relatório.

1. Adicione no 'Contents' dois componentes <dateText>.

- Um para data inicial

<dateText id="txtDataInicial" label="Data Inicial" separator="/" format="DMY"/>

- Um para data final

<dateText id="txtDataFinal" label="Data Final" separator="/" format="DMY"/>

- Um botão “Ok" que fará a chamada de um método que redirecionará

para o relatório.

<button id="btnEnviar" caption=“Enviar" onclick="zenPage.relatorio();"/>

Exercícios Adicionais – usando ‘window.open’

3. Crie o método relatorio().

Method relatorio() [ Language = javascript ]

{

var inicio = zenPage.getComponentById('txtDataInicial').getValue();

var fim = zenPage.getComponentById('txtDataFinal').getValue();

var link = 'ISCUser.Rel.Exames.cls?datainicial=‘+inicio+"&datafinal="+fim;

window.open(link,'','Relatório de

Exames','status,scrollbars,resizable,top=10,left=10,width=800,height=800');

}

4. Crie uma página de relatório 'ISCUser.Rel.Exames.cls‘ herdando de

%ZEN.Report.reportPage. Configure o XData ReportDefinition. Para o sql selecione as

colunas: ID, Codigo, DataExame, ValorExame, Paciente-> Nome da tabela 'Exames‘.

1. Pegue as datas inicial e final: faça isso dentro da classe do relatório.

Page 151: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 150

Property DataInicial As% String (ZENURL = “datainicial");

Property DataFinal As% String (ZENURL = "datafinal");

5. Formate o 'XData ReportDisplay‘ para ter um cabeçalho com as dimensões das margens.

<document width="210mm" height="297mm" headerHeight="25mm“ marginLeft="15mm"

marginRight="7mm" marginTop="7mm“ marginBottom="7mm">

</ document>

6. O cabeçalho deve ter: data e hora um título e as datas de início e fim. Faça isso em

<pageheader> no ‘ReportDisplay’:

<pageheader>

<item field="@Hospital"/>

<line pattern="empty"/>

<item field="@Data"/>

<line pattern="empty"/>

<item field="@Titulo"/>

<line pattern="empty"/>

<item displayCaption="true" caption="Data inicial: " field="@Inicio"/>

<line pattern="empty"/>

<item displayCaption="true" caption="Data final: " field="@Fim"/>

<line pattern="empty"/>

<line pattern="dashed"/>

</pageheader>

7. Para isso você deve ter definido a empresa, datas e título. Faça isso no início do relatório.

Parameter HOSPITAL = "Hospital";

Parameter TITULO = "Título do Relatório";

Property DataInicial As %String(ZENURL = "datainicial");

Property DataFinal As %String(ZENURL = "datafinal");

Property Formato As %Integer(ZENURL = "format") [ InitialExpression = 4 ];

Property Hospital As %String [ InitialExpression = {..#HOSPITAL} ];

Property Titulo As %String [ InitialExpression = {..#TITULO} ];

Page 152: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 151

8. E em seguida no ‘ReportDefinition’:

<attribute name="Data" expression="$ZDateTime($horolog,4)"/>

<attribute name="Hospital" expression="..Hospital"/>

<attribute name="Titulo" expression="..Titulo"/>

<attribute name=“Inicio" expression="$zdate($zdateh(..DataInicial,8),..Formato)"/>

<attribute name=“Fim" expression="$zdate($zdateh(..DataFinal,8),..Formato)"/>

9. Adicione uma cláusula ‘Where’ para o sql:

Where DataExame BETWEEN ? and ?”

10. A seguir adicione abaixo de <report>:

<parameter expression="..EditaData(..DataInicial)"/>

<parameter expression="..EditaData(..DataFinal)"/>

11. Importe a classe 'EstiloRelatorio.cls' e forneça um estilo. Esta classe escreve o estilo

diretamente na página gerada, usando o método %DrawHTMLPage.

Faça isso em <document> no ‘XData ReportDisplay’ inclua o elemento:

<cssinclude href=“ISCUser.Pag.EstiloRelatorio.cls"/>

12. Configure os estilos de : Hospital, Titulo, Data, Data de Inicio e Data de Fim e

a tabela de apresentação dos dados do relatório. Faça no atributo ‘class‘ .

Page 153: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 152

Módulo – Zen e SVG

Módulo – Zen e SVG

Page 154: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 153

Page 155: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 154

Zen e SVG

• SVG (Scalable Vector Graphics) é uma linguagem que permite descrever gráficos vetoriais em 2

dimensões em formato XML.

• Zen usa SVG para apresentar com alto desempenho, gráficos e medidores orientados a dados.

• É possível usar componentes SVG embutidos ao Zen para definir painéis de controle que

atualizam estatísticas em tempo real.

Layout de Componentes SVG

• Os seguintes componentes permitem a inclusão de componentes SVG em uma página Zen:

– <svgFrame>

– <svgGroup>

– <svgSpacer>

<svgFrame>

• É um componente Zen que cria um quadro retangular na página Zen, onde é possível incluir

componentes SVG.

• Apenas componentes SVG podem ser inseridos dentro deste quadro.

• Qualquer componente SVG dinâmico, como um medidor ou gráfico, exige um <svgFrame> para

contê-lo.

• A imagem seguinte apresenta um exemplo de componentes Zen e componentes SVG.

Page 156: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 155

• O elemento <svgFrame> possui vários atributos, entre eles:

– backgroundStyle: especifica o estilo de fundo do quadro em formato CSS.

– disabled: se verdadeiro, este quadro e seus filhos são desabilitados.

– editMode: modo de edição do quadro. Os valores possíveis são:

• “none” – o usuário não pode editar o conteúdo do quadro. Padrão.

• “select” – o usuário pode clicar em um componente SVG para selecioná-lo.

• “drag”- o usuário pode mover um componente SVG dentro do quadro.

– layout: especifica como os componentes SVG são dispostos no quadro. Os valores

possíveis são “horizontal” e “vertical”.

Se o valor for igual “none” ou for deixado em branco, os componentes podem ser

posicionados usando coordenadas x e y específicas.

– snapToGrid: se verdadeiro, todas as operações do mouse (redimensionamento e

posicionamento) são forçadas a ocorrer no grid definido por gridX e gridY.

<svgGroup>

• <svgGroup> é um container especial que contém e controla layout de componentes SVG dentro

de um <svgFrame>.

• Possui os seguintes atributos:

– disabled: se verdadeiro, este grupo e seus filhos são desabilitados.

– layout: especifica como os componentes SVG dentro deste grupo devem estar

dispostos. Possíveis valores são: “horizontal” e “vertical”.

<svgSpacer>

• O elemento <svgSpacer> é útil dentro de containers <svgGroup> para criar um espaço entre os

componentes.

• Use <svgSpacer> com o atributo width para inserir um espaço na horizontal, e com o atributo

height para inserir um espaço na vertical.

Page 157: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 156

<rect>

• O elemento Zen <rect> desenha um retângulo.

• Este elemento insere um espaço dentro de um <svgGroup> ou <svgFrame>, mas é diferente do

<svgSpacer>.

• A diferença entre <svgSpacer> e <rect> é que <rect> pode ter atributos estilo de exibição, como

uma cor de preenchimento.

• Atributos:

– rx: define um retângulo com cantos arredondados.

– style: define um estilo para o elemento.

Atributos de Componentes SVG

• Todos os componentes SVG tem os mesmos atributos para definição de estilo. Estes atributos

são totalmente diferentes dos atributos dos componentes Zen normais.

• Alguns deles são:

– height: altura do componente.

– width: largura do componente.

– hidden: se verdadeiro, o componente fica desabilitado.

– x: posição x do componente. A posição atual do componente pode depender do layout

do <svgGroup> onde ele está inserido. Se o <svgGroup> tem layout vertical ou

horizontal, esta coordenada é ignorada.

– y: posição y do componente.

Page 158: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 157

Medidores

• Um medidor é um componente SVG que apresenta uma representação gráfica de um único valor

numérico.

• Zen fornece vários medidores pré-construídos. Para inserir em uma página Zen, forneça o

elemento do medidor dentro de um <svgFrame> ou <svgGroup>:

– <fuelGauge> - medidor de combustível

– <indicatorLamp> - luz indicadora

– <lightBar> - barra de luzes

– <smiley> - expressão facial

– <speedometer> - velocímetro

– <trafficLight> - semáforo

Fornecendo Dados para os Medidores

• É possível atualizar o valor apresentado pelo medidor dinamicamente de duas maneiras:

– A partir de método JavaScript, ajustando o valor do atributo value do medidor através

dos métodos de classe getComponentById e setValue:

Ex.: this.getComponentById(“meuMedidorID”).setValue(Valor);

– Associar o medidor a um data controller (visto no módulo MVC). Exemplo:

– No exemplo anterior, há um componente data controller vinculado à classe modelo

Apl.Cliente. E um medidor de expressão facial conectado à este data controller

apresentando o valor da propriedade Avaliacao.

Page 159: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 158

Atributos de Medidores

• Todos os medidores tem atributos comuns, entre eles:

– animate: controla a animação do medidor em verdadeiro ou falso. A animação de um

medidor é por exemplo a movimentação do ponteiro de velocímetro.

– controllerId: indica o data controller que fornece os dados.

– dataBinding: indica a propriedade da classe conectada ao data controller que fornece os

dados.

– label: um texto a apresentar no medidor.

– rangeLower: valor inteiro ou decimal que define o menor valor da faixa de valores

representado pelo medidor.

– rangeUpper: valor inteiro ou decimal que define o maior valor da faixa de valores

representado pelo medidor.

– thresholdLower: valor inteiro ou decimal que define um “piso” para o comportamento do

medidor. O medidor irá fazer algo quando o valor for menor que este atributo.

Geralmente, este atributo é maior que rangeLower e serve com um aviso que o valor do

medidor está aproximando do valor mínimo.

– thresholdUpper: é o inverso do atributo anterior. Serve como um aviso que o valor do

medidor está aproximando do valor máximo.

value: representa o valor atual do medidor.

Page 160: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 159

Exercícios – Zen e SVG

Neste exercício inclua uma tag <svg> para mostrar o valor da renda de um paciente.

1. Insira um componente <svgFrame> na classe ‘ISCUser.Pag.Paciente’ após os botões de

navegação.

2. Insira um medidor <fuelGauge> dentro do <svgFrame> conectando ao <dataController> através

do atributo controllerId e à propriedade Renda através do atributo dataBinding.

3. Abaixo estão algumas configuração que podem ser usadas como referência.

Page 161: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 160

Módulo – Gráficos Zen

Módulo – Gráficos Zen

Page 162: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 161

Page 163: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 162

Gráficos Zen

• Zen oferece vários tipos de gráficos como: gráficos de linha, gráficos de barras, gráficos em

forma de pizza, etc.

• Todo gráfico é um componente SVG.

• Todos os gráficos são criados dentro de um espaço virtual que mede 100 unidades por 100

unidades. As dimensões atuais deste espaço são representadas pelos atributos height e width.

• Dentro deste espaço virtual há uma área menor onde o gráfico é apresentado. Margens

preenchem o espaço ao redor do gráfico. E geralmente estas margens são usadas para

apresentar textos e legendas.

Convenções de Layout para Gráficos Zen

Page 164: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 163

Gráfico de Linhas

• Um <lineChart> mostra uma ou mais séries de dados como um conjunto de linhas que cruzam

um grid.

• Possui os seguintes atributos especiais:

– chartFilled: se verdadeiro, a área abaixo de cada linha é preenchida (como um gráfico de

área).

– chartPivot: se verdadeiro, mostra as categorias verticalmente e os valores

horizontalmente.

– chartStacked: útil para gráficos com mais de uma série de dados. Se verdadeiro, as

linhas são “empilhadas” uma sobre a outra.

Gráfico de Barras

• Um <barChart> mostra uma ou mais séries de dados como um conjunto de barras horizontais ou

verticais.

• Possui os seguintes atributos especiais:

– chartPivot: se verdadeiro, mostra as categorias verticalmente e os valores

horizontalmente.

– chartStacked: útil para gráficos com mais de uma série de dados. Se verdadeiro, as

barras são “empilhadas” uma sobre a outra.

Page 165: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 164

Fornecendo Dados ao Gráfico

• Os dados de um gráfico consistem de uma ou mais séries de dados.

• Cada série é um simples array de valores numéricos.

• É possível fornecer dados a um gráfico de duas maneiras:

– Invocando um método JavaScript na classe da página, através do atributo ongetData do

gráfico.

– Associando o gráfico à um data controller, através do atributo controllerId.

Invocando um método JavaScript

• Todos os gráficos suportam o atributo ongetData. O valor deste atributo é uma expressão

JavaScript que Zen invoca quando:

– O gráfico é mostrado inicialmente.

– O método updateChart do gráfico é invocado.

• Exemplo:

ongetData=“return zenPage.leDados(series);”

• O método chamado pelo ongetData deve aceitar um único argumento, series, que contém o

número de séries (baseado em 0) a ser gerado pelo gráfico.

• O código seguinte apresenta um exemplo de um método que gera valores aleatórios para o

gráfico.

• A imagem abaixo apresenta um exemplo de um método que gera valores aleatórios para o

gráfico.

Page 166: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 165

Usando um <dataController>

• Todos os gráficos suportam os seguintes atributos, que associam um gráfico à uma visão de um

dataController.

– controllerId: identifica o <dataController> que fornece os dados para o gráfico.

– onnotififyView: expressão JavaScript que é executada toda vez que o dataController

conectado ao gráfico causa um evento.

• O código seguinte apresenta um exemplo de utilização de <dataController> para fornecer dados

a um gráfico.

• O gráfico lê o valor para seriesSize a partir do número de propriedades da Classe Modelo

conectada ao <dataController>.

Page 167: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 166

Atributos de Gráficos

• A classe %ZEN.SVGComponent.chart oferece um grande número de atributos aplicáveis aos

gráficos Zen que controlam:

– Layout e estilo;

– Área de impressão;

– Marcadores;

– Legendas;

– Títulos;

– Coordenadas dos eixos.

Atributos de Layout e Estilo

– backgroundStyle: definição de estilo CSS SVG. Especifica o estilo do fundo do quadro

do gráfico.

– marginBottom: especifica a margem inferior. Textos do eixo X ou a legenda do gráfico

geralmente aparecem neste espaço.

– marginLeft: especifica a margem esquerda. Textos do eixo Y ou a legenda do gráfico

geralmente aparecem neste espaço.

– marginRight: especifica a margem direita.

– marginTop: especifica a margem superior. O título do gráfico geralmente aparece neste

espaço.

Atributos de Área de Impressão

– gridStyle: estilo CSS SVG para o grid.

– labelStyle: estilo CSS SVG para os textos do gráfico.

– labelsVisible: se verdadeiro, o gráfico apresenta os textos dos eixos do gráfico.

– ongetLabelX: expressão JavaScript que fornece os textos para o eixo X.

– ongetLabelY: expressão JavaScript que fornece os textos para o eixo Y.

– plotAreaStyle: estilo CSS SVG para a área de impressão do gráfico.

– seriesColor: cores para as séries de dados no estilo CSS. O valor padrão é:

“blue,red,green,yellow,orange,plum,purple”

Page 168: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 167

Exercícios – Gráficos Zen

• Crie uma página com um gráfico de prioridade de exames:

1. Crie ‘ISCUser.Pag.Grafico.cls’

1. Inclua um ‘dataController’

<dataController id=“origem”

modelClass="ISCUser.MVC.GraficoPrioridade"

modelId=“1“/>

2. Inclua um ‘dynaGrid’

<dynaGrid align="center" width="400"

id="dynaGrid"

gridLabel="dynaGrid"

controllerId=“origem"/>

3. Inclua um componente <svgFrame>.

<svgFrame id="svgFrame"

height="300"

width=“300"

backgroundStyle="fill: black;"

layout="horizontal">

4. Inclua um gráfico.

Escolha um gráfico e atribua os parâmetros.

Page 169: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 168

Exercícios - Modificando a página de Menu

• Continuando com as definições na página de Menu:

1. Limpe o bloco dentro de <page></page>

2. Inclua os grupos Vertical e Horizontal.

3. Dentro de <vgroup id="image“ ...> inclua.

<image src="images\intersystems.jpg" width="982" height="60"/>

4. Dentro de <vgroup id="frame“ ..> inclua.

<iframe frameBorder="false" id="framePrincipal"

name="framePrincipal" align="center" width="100%"

height="450" src="ISCUser.Pag.BoasVindas.cls"/>

Page 170: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 169

Page 171: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 170

Módulo – Componentes de Navegação

Módulo – Componentes de Navegação

Page 172: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 171

Page 173: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 172

Links, Menus e Guias

• Componentes de navegação permitem grande flexibilidade ao desenvolvedor Zen.

• Este módulo agrupa os componentes disponíveis de acordo com o tipo do item que cada

componente é projetado a apresentar.

– Links

– Menus

– Guias

Links

• Os seguintes componentes Zen fornecem links disponíveis através de URI:

– <link>

– <locatorBar>

<link>

• O componente <link> apresenta um simples link (um elemento HTML <a>) em uma página Zen.

• Possui vários atributos, entre eles:

– caption: texto a apresentar no link.

– disabled: se verdadeiro, o link é desabilitado.

– href: URI do conteúdo a apresentar quando o usuário clica no texto do link. Para invocar

um método JavaScript deve-se iniciar a URI com javascript:.

Exemplo: href=“javascript:zenPage.meuMetodo();”

– title: mensagem de ajuda que aparece quando o usuário pára o mouse sobre o texto do

link.

Exercícios – Links

1. Crie uma nova página Zen chamada Links.

2. Insira 3 links para outras páginas Zen criadas em exercícios anteriores.

Page 174: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 173

3. Insira um link que ao ser clicado mostre uma mensagem (alert) ao usuário.

<locatorBar>

• A barra de localização apresenta vários links que representam a localização da navegação do

usuário.

• O código necessário para criar a barra de localização acima é o seguinte:

• Como pode-se notar a barra de localização é composta por um elemento <locatorBar> e vários

elementos <locatorLink>, um para cada link a apresentar.

<locatorLink>

• O elemento <locatorLink> pode aparecer somente dentro de um elemento <locatorBar>.

• Cada <locatorLink> define um link dentro da barra de localização.

• Este componente tem vários atributos, entre eles:

– id: valor que pode ser usado para selecionar um estilo CSS.

– caption: texto a apresentar no link.

– href: URI do conteúdo a apresentar quando o usuário clica no texto do link.

– title: mensagem de ajuda que é apresentada quando o usuário pára o mouse sobre o

link.

Page 175: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 174

Exercícios – Links

• Crie um ‘locator bar’ dentro da página de Menu.

1. Crie um grupo vertical como:

<vgroup id="menus" width="100%">

<hgroup width="100%" >

<hgroup id="locator" width="60%" height="100%" >

<hgroup/>

2. Dentro de <hgroup id="locator“ …>, inclua:

<locatorBar id="locator"

containerStyle="background: #A0B088;

background-image: url(images/locatorgradient.png);

background-repeat: repeat-x;

padding-top: 6px;">

3. Adicione um <locatorBar></locatorBar>, e inclua:

1. <locatorLink caption="Home" href="ISCUser.Pag.Menu.cls" />

2. Faça o mesmo para:

1. Login

2. Logout

3. Grafico

3. E um ‘LocatorLink’ para o site da “intersystems”:

1. <locatorLink caption="InterSystems“

2. href="http://www.intersystems.com" />

Page 176: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 175

4. Teste o link do Gráfico:

A página chamada será aberta sobre a página de menu, nós gostaríamos que fosse

mostrada no frame principal, para isso é necessário fazer:

1 - Crie um método ‘JavaScript’, mostra():

Method mostra(pLink) [ Language = javascript ]

{

framePrincipal.location = pLink;

}

2 - Altere o ‘locatorlink’ para:

<locatorLink caption="Grafico" href="javascript:

zenPage.mostra('ISCUser.Pag.Grafico.cls')" />

Page 177: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 176

Menus

• Componentes de menus permitem a criação de menus clássicos de navegação, com listas de

opções que o usuário pode selecionar clicando em um item.

• Ao selecionar um item de menu, várias ações podem ser disparadas, dependendo de sua

programação:

– Um submenu pode ser apresentado;

– Uma mensagem pop-up (alert) pode ser apresentada;

– Uma página diferente pode ser acessada;

– O conteúdo da página atual pode ser alterado.

• Para produzir o menu anterior, o seguinte código é necessário:

Page 178: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 177

• Como pode ser observado no código anterior, a criação de um menu é feita através do elemento

<menu>.

• Cada item do menu é um elemento <menuItem>.

• A criação de um submenu é feita através da inserção de outro <menu> dentro de um <menu>.

• Alguns itens de menu apresentam uma mensagem (alert) ao ser selecionados e outros acessam

uma página Zen diferente. Esta ação é programada através do atributo href.

• É possível criar separações dentro dos itens do menus através do elemento <menuSeparator>,

isto cria uma linha horizontal dentro do menu.

<menu>, <hmenu> e <vmenu>

• Os componentes <menu>, <hmenu> e <vmenu> são muito similares.

• A diferença entre eles é a forma de layout que cada um possui:

– <menu> é possível especificar o layout vertical ou horizontal através do atributo layout.

– <hmenu> os itens de menu inseridos dentro deste componente são posicionados

horizontalmente.

– <vmenu> os itens de menu inseridos dentro deste componente são posicionados

verticalmente.

<menuItem>

• Este componente representa cada item dentro de um menu.

• Possui vários atributos, entre eles:

– caption: texto do item do menu.

– help: mensagem de ajuda que é apresentada quando o usuário pára o mouse sobre o

item de menu.

– image: identifica o caminho e nome do arquivo da imagem a ser apresentada no item do

menu. Se tanto este atributo como o atributo caption forem especificados, ambos serão

apresentados um ao lado do outro.

– link: URI do conteúdo a apresentar quando o usuário clica no texto do item do menu.

Page 179: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 178

Exercícios – Menus

• Crie um Menu de opções dentro da página de Menu.

1. Crie entre <vgroup id=“menu”></vgroup> outro <hgroup>:

<hgroup id="principal" width="100%">

<vgroup id="menu" width="20%" valign="top">

<hgroup width="65%" id="hGroupItem" hidden="true">

</hgroup>

</vgroup>

2. Dentro de <hgroup id=“hGroupItem“ …>, inclua o Menu:

<menu id="menu1" layout="vertical" width="60%">

<menu caption=“Cadastro" layout="vertical">

<menuItem caption=“Paciente"

link="javascript: zenPage.mostra('ISCUser.Pag.Paciente.cls')" />

<menuSeparator/>

<menu caption="InterSystems" layout="vertical">

<menuItem caption="Site" link="http:\\www.intersystems.com"/>

<menuItem caption="Downloads"

link="http://www.intersystems.com/cache/downloads/index.html"/>

</menu>

</menu>

</menu>

Page 180: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 179

Guias (tabs)

• Os seguintes componentes Zen suportam o uso guias (tabs) em aplicações Zen.

– <tabGroup>

– <tab>

– <lookoutMenu>

<tabGroup>

• Apresenta um conjunto de guias (componentes <tab>).

• Pode ser apresentado apenas uma guia por vez.

• O código para a criação do conjunto de guias acima é:

Page 181: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 180

• <tabGroup> possui vários atributos, entre eles:

– currTab: identifica a guia atualmente selecionada.

– onhideTab: expressão JavaScript que é invocada quando uma guia que estava sendo

apresentada é trocada por outra.

– onshowTab: expressão JavaScript que é invocada quando o usuário seleciona uma nova

guia.

– remember: se verdadeiro, armazena em um cookie da sessão a última guia

apresentada, para que quando a página for acessada novamente esta guia venha

selecionada automaticamente.

– showTabBar: se verdadeiro, apresenta o conjunto de botões para a seleção das guias.

<tab>

• É um tipo de grupo especializado que define uma guia dentro de um <tabGroup> ou

<lookoutMenu>.

• Possui os seguintes recursos:

– caption: texto que identifica a guia;

– tabResource: nome de um recurso do Caché. O usuário precisa ter privilégios para

acessar este recurso ou a guia torna-se desabilitada.

Page 182: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 181

<lookoutMenu>

• Um <lookoutMenu> apresenta uma pilha de botões, um em cada guia.

• Clicando em um botão os outros botões são deslocados para apresentar as outras opções.

• Um <lookoutMenu> contém um conjunto de componentes <tab>, que contém componentes

<menuItem> e <menuSeparator>.

• O seguinte código é necessário para criar o menu ao lado.

Page 183: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 182

• O componente <lookoutMenu> possui os seguintes atributos:

– expandable: se verdadeiro, o componente pode ser expandido e contraído/encolhido.

– expanded: se verdadeiro, o componente aparece expandido, ou seja, seus filhos são

visíveis.

– oncontract: expressão JavaScript invocada quando o componente é contraído/encolhido.

– onexpand: expressão JavaScript invocada quando o componente é expandido.

Exercícios – Lookout Menu

• Crie um ‘lookoutMenu’ dentro da página de Menu.

1. Crie dentro de <hgroup id="principal" …> um:

<hgroup width="100%" id="hGroupLook" >

2. Dentro de <hgroup width="100%" id="hGroupLook“ …>, inclua um lookoutMenu:

Page 184: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 183

Page 185: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 184

Módulo – Janelas de Expansão e Popup

Módulo – Janelas de Expansão e Popup

Page 186: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 185

Page 187: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 186

Janelas de Expansão e Popup

• Este módulo descreve componentes que possuem comportamento visual dinâmico, como

janelas popup, componentes com recursos para ocultar ou apresentar seu conteúdo, etc.

• Esses componentes são:

– <expando> - grupo expansível.

– <repeatingGroup> - grupo de repetição.

– <dynaTree> - árvore dinâmica.

– <dynaView> - caixa com conteúdo dinâmico.

– <modalGroup> - conteúdo HTML que torna-se visível em resposta a um evento de

usuário.

– Janelas de Diálogo.

<expando>

• O componente <expando> é um grupo com a habilidade de mostrar ou ocultar seus filhos.

• Para criar um grupo que possa ser exibido ou ocultado, basta inserir os componentes Zen

diversos dentro do componente <expando>. Exemplo:

Page 188: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 187

<repeatingGroup>

• É um grupo especializado que define o layout para uma única entrada do grupo, e então através

de uma query em tempo de execução são geradas várias entradas com este layout.

• Exemplo de utilização:

• O página do exemplo anterior é produzida com o código:

• Este código cria um grupo que é repetido de acordo com o atributo sql, isto é, cria 10 entradas,

uma para cada registro do comando SQL.

• Em cada grupo é criado um botão com o nome do cliente e um texto com a cidade do cliente.

Page 189: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 188

<dynaTree>

• O componente <dynaTree> mostra um conjunto de itens definidos pelo usuário como uma árvore

expansível.

• É semelhante ao componente <expando>, no entanto ao invés de especificar os componentes, o

<dynaTree> adquire seu conteúdo dinamicamente através de:

– Uma global, ou

– Método Callback

<dynaTree> Usando uma Global

• A maneira mais simples de fornecer o conteúdo para um <dynaTree> é especificar uma global

no atributo dataGlobal.

• Suponha que a global ^minhaArvore tenha os seguintes nós:

• Isto produz a seguinte página Zen:

<dynaTree> Usando um Método Callback

• É possível também fornecer conteúdo a um <dynaTree> através de método Callback.

• Para isso deve-se informar o atributo OnGetNodeInfo igual a um método callback servidor.

Exemplo:

• Sendo a assinatura do método GeraConteudo:

Page 190: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 189

<dynaView>

• O componente <dynaView> mostra um conjunto de itens definidos pelo usuário dentro de uma

caixa.

• Os itens podem ser apresentados de dois modos:

– “list” – onde apenas a primeira coluna é apresentada.

– “details” – cada item é mostrado em uma linha.

• O <dynaView> recebe a lista de itens invocando um método callback no servidor. O nome do

método é especificado no atributo OnGetViewContents. Ex.:

• O método GeraConteudo cria a lista de itens:

Page 191: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 190

• Onde:

– pContents(x) – array multidimensional que contém os itens a apresentar no componente.

O array é subscrito pelo número do item (iniciando com 1). Cada array contém uma

estrutura $List com as seguintes informações:

• 1º. Campo: texto a apresentar na primeira coluna;

• 2º. Campo: valor interno/lógico que representa a linha;

• 3º. Campo: URI da imagem a ser apresentada com o item.

• 4º./5º./... Campos: demais colunas a apresentar.

– pHeaders(x) – array multidimensional que fornece o cabeçalho das colunas, subscrito

pelo número da coluna.

Exercícios – Dyna Tree

• Crie um <dynaTree> dentro da página de Menu.

1. Crie dentro de <hgroup id="principal" …> a:

<hgroup id="hGroupDyna" hidden="true" enclosingClass="celulaMenu" width="100%" >

2. Dentro de <hgroup width="100%" id=" hGroupDyna “ …>, inclua um dynaTree:

<dynaTree id="dytMenu" OnGetTreeInfo="GetTreeInfo"/>

3. Crie o método GetTreeInfo:

ClassMethod GetTreeInfo(pRoot As %String, Output pTree, ByRef pParms) As %Status

{

Set userID = %session.Get("UserId")

#; top-most nodes are children of 0

Set pTree(0,"ch",1) = ""

Set pTree(0,"ch",2) = ""

Set pTree(0,"ch",3) = ""

#; each node supplies: $LB(caption, value, hasChildren, link, expanded, icon)

Set pTree(1)=$LB(("Cadastros"),("Cadastros"),1,"",1,,”Cadastros Gerais")

Page 192: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 191

Set pTree(2)=$LB(("Relatórios"),("Relatórios"),1,"",1,,"Relatórios Gerais")

Set pTree(3)=$LB((“Pesquisas"),(" Pesquisas "),1,"",1,,"Pesquisas Gerais")

Set pTree(4) = $LB(("Paciente"),("Paciente"),0,"javascript:

zenPage.mostra('ISCUser.Pag.Paciente.cls')",1)

Set pTree(1,"ch",4) = ""

Set pTree(5) = $LB(("Exames"),("Exames"),0,"javascript:

zenPage.mostra('ISCUser.Pag.Exames.cls')",1)

Set pTree(1,"ch",5) = ""

Set pTree(6) = $LB(("Prioridade"),("Prioridade"),0,"javascript:

zenPage.mostra('ISCUser.Pag.Prioridade.cls')",1)

Set pTree(1,"ch",6) = ""

Set pTree(7) = $LB(("Exames por Data"),("Exames por Data"),0,"javascript:

zenPage.mostra('ISCUser.Pag.PreExame.cls')",1)

Set pTree(2,"ch",7) = ""

Set pTree(8) = $LB(("Exames"),("Exames"),0,"javascript:

zenPage.mostra('ISCUser.Pag.PesquisaExames.cls')",1)

Set pTree(9) = $LB(("Exames Itens"),("Exames Itens"),0,"javascript:

zenPage.mostra('ISCUser.Pag.PesquisaItem.cls')",1)

Set pTree(10) = $LB(("Paciente"),("Paciente"),0,"javascript:

zenPage.mostra('ISCUser.Pag.PesquisaPaciente.cls')",1)

Set pTree(3,"ch",8) = ""

Set pTree(3,"ch",9) = ""

Set pTree(3,"ch",10) = ""

Quit $System.Status.OK()

}

Page 193: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 192

Grupos Modais

• Um grupo modal é um tipo especializado de grupo que normalmente não apresenta seu

conteúdo. O conteúdo é apresentado através de um interação na página.

• Quando o grupo modal torna-se visível, apenas seu conteúdo recebe eventos do usuário.

• Qualquer evento que ocorre fora do grupo modal (como um clique de mouse) automaticamente

faz com que o grupo modal fique oculto novamente.

• É possível definir o conteúdo de um grupo modal inserindo um componente <modalGroup>

dentro de classe de página ou criando uma instância da classe %ZEN.Component.modalGroup

programaticamente.

• Há três opções de grupos modais:

– Estático: insira um componente <modalGroup> no bloco XData Contents. Seu conteúdo

permanecerá oculto até que seja chamado o método show do grupo modal.

– Dinâmico: a página chama o método createComponent para criar um componente de

grupo modal dinamicamente.

– Embutido: deve-se chamar o método show do grupo modal para mostrar um grupo

embutido:

• msgBox

• calendar

• Para fechar um grupo modal, deve-se chamar o método endModal.

Exemplo: Grupo Modal Estático

• O bloco XData Contents possui:

– Um componente HTML que mostra o valor digitado na janela modal.

– Componente <groupModal> que cria um grupo modal estático. Dentro do grupo é

inserido uma caixa de texto e um botão OK.

– Um botão que chama o método show fazendo com que o grupo seja apresentado.

Page 194: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 193

• O método grupoModalEstatico é chamado quando o usuário clica no botão com o texto

“Informe um valor”. Ao clicar neste botão o grupo modal é apresentado, pois é feita a chamada

ao método show.

• O método mgBtnClique é chamado quando o usuário clica no botão OK do grupo modal. Este

método lê o valor que o usuário digitou, coloca este valor na página principal e fecha o grupo

modal através do método endModal.

Page 195: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 194

Exemplo: Grupo Modal Dinâmico

• O bloco XData Contents possui apenas:

– Um componente HTML que apresenta o valor que usuário informou;

– Um botão que chama um método que cria o grupo modal dinamicamente.

– Neste exemplo não há o elemento <groupModal>. O grupo é criado inteiramente dentro

de um método e não através de elementos.

• O método grupoModalDinamico, chamado quando o usuário clica no botão da página principal,

cria dinamicamente o grupo modal e seus controles:

Page 196: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 195

• O método btnClique, chamado quando o usuário clica no botão Salvar do grupo modal, lê os

dados informados pelo usuário, escreve esses dados na página principal e fecha o grupo modal:

Page 197: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 196

Exemplo: Grupos Modais Embutidos – calendar

• O bloco XData Contents possui apenas um botão que ao ser pressionado chama o método

grupoModalCalendario:

• O método grupoModalCalendario cria um grupo modal embutido do tipo calendário e especifica

a chamada ao método acaoCalendario quando o usuário escolhe uma data:

• O método acaoCalendario, que é chamado quando o usuário escolhe uma data, gera uma

mensagem na tela mostrando a data selecionada.

Page 198: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 197

Exemplo: Grupos Modais Embutidos – Msgbox

• Semelhante ao grupo modal calendário, no bloco XData Contents há apenas um botão que

chama um método que cria a caixa de mensagem.

• O método grupoModalMsg apresenta o grupo modal do tipo caixa de mensagem:

Page 199: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 198

Janelas de Diálogo

• Zen possui classes embutidas que oferecem os seguintes recursos para trabalhar com caixas de

diálogo:

– Janela de diálogo;

– Janela para seleção de cores;

– Janela para seleção de arquivos;

– Possibilidade de criação de nova janela de diálogo;

– Possibilidade de criação de novo modelo de janela de diálogo.

Exemplo de Seleção de Arquivos

• O código abaixo cria uma página Zen com um botão que ao ser pressionado apresenta uma

janela de diálogo para a seleção de um arquivo.

Page 200: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 199

Exercícios Adicionais – Menu

1. Podemos agora selecionar o tipo de menu que gostaríamos, selecionando das opções de um

combobox.

2. Inclua abaixo de ‘locatorbar’:

1. <label label=“Opções de Menu: " labelStyle="font-size: 0.80em;" />

2. <select name="sel" id="OpMenu"

valueList="1,2,3" displayList="DynaTree,Menu,LookOut"

onchange="zenPage.mudaMenu();" />

3. Crie o método mudaMenu().

Method mudaMenu() [ Language = javascript ]

{

var op = zenPage.getComponentById('OpMenu').getValue();

var dy = zenPage.getComponentById('hGroupDyna');

var mi = zenPage.getComponentById('hGroupItem');

var lo = zenPage.getComponentById('hGroupLook');

var lb = zenPage.getComponentById('labelMenu');

if (op == '')

{

dy.setProperty('hidden',false);

mi.setProperty('hidden',false);

lo.setProperty('hidden',false);

lb.setProperty('label','All...');

}

...

}

4. Crie as propriedades.

Property Usuario As %String [ InitialExpression = {%session.Get("NomeUsuario")} ];

Property Sessao As %String [ InitialExpression = {%session.SessionId} ];

Page 201: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 200

5. Crie dentro de <vgroup id="user" width="10%">

<label align="left" label='User: #(%page.Usuario)#'/>

<label align="left" labelStyle="bold;" label="Session: #(%page.Sessao)#"/>

<link id="lnkSair" align="left" caption=“Sair" href="ISCUser.Pag.Logout.cls"/>

6. Crie uma página de logout que será chamada quando o usuário fechar a aplicação ou um pouco antes de expirar o tempo da sessão.

1. Ela deverá conter um link para logar novamente.

2. <link href="ISCUser.Pag.Login.cls" caption="Clique aqui para o login!."/>

3. Deverá conter uma mensagem de que a sessão foi encerrada. A sessão será encerrada com %session.EndSession = 1

4. Em 'onloadHandler‘ você deve encerrar a sessão chamando o método FimSessao() (ZenMethod) e no método adicionar

Set %session.EndSession = 1 Faça: zenPage.FimSessao (); dentro de 'onloadHandler';

ClassMethod FimSessao() As %Status [ ZenMethod ] { Set %session.EndSession = 1 Quit $System.Status.OK() }

Page 202: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 201

Page 203: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 202

Módulo - Miscelânea

Módulo - Miscelânea

Page 204: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 203

Page 205: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 204

<timer>

• O elemento <timer> não tem nenhuma representação visual, ele apenas dispara um evento no

lado cliente em um específico período de tempo.

• A contagem do atributo timeout (em miIisegundos) inicia automaticamente sempre que a página

é carregada.

• Um <timer> dispara o evento apenas uma vez, então para reiniciar o temporizador, deve-se

chamar o método startTime de dentro do método especificado no atributo ontimeout.

<fieldSet>

• O elemento <fieldSet> é um componente agrupador que desenha uma caixa exterior ao redor

dos controles contidos nele.

• Cria um painel visual que ajuda a organizar os controles dentro de uma página.

• Para inserir este componente basta inserir um <fieldSet> e dentro dele os componentes filho.

Page 206: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 205

• Possui 2 atributos:

– legend: especifica o texto a apresentar na borda do componente.

– title: especifica o texto a apresentar quando o usuário pára o mouse sobre o texto de

legend.

<colorPane>

• O componente deixa o usuário ver e selecionar cores ou incorporar valores do RGB a um paleta

grande da cor. A paleta é uma grade que possa ser visualizada como uma fatia possível de um

cubo tridimensional de cores disponíveis.

• O <colorPane> captura uma fatia do cubo aceitando a escolha do usuário de uma de três faces

(vermelho, verde, ou azul) e cortando através do cubo, paralela a essa face, em algum nível de

saturação (mais brilhante ou menos ofuscante) para produzir uma grade das cores.

Page 207: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 206

Exercícios – FieldSet

1. Usando o fieldSet.

1. Em 'Pagina.cls' adicione um <fieldSet> para conter o ‘controller’ o ‘dynaForm’ e os

‘buttons’. Use 'align = left‘.

2. Crie outro <fieldSet> para conter os links. Atribua a ambos width = "95%".

Exercícios – TimeOut

O timeout padrão é de 900s para a sessão.

Se nada acontecer antes destes 900s ela automaticamente expira.

Entretanto, para prevenir que a sessão expire é necessário controlar este tempo, ou seja, há quanto

tempo a sessão está aberta, e momentos antes de expirar chamar uma página adequada para

tratamento.

Isto é feito criando na página de menu um controle de tempo de sessão.

1 – É criado na superclasse de página um parâmetro para contar o tempo de sessão e gravado

no %session.

Property SessionTimeout As %Integer [ InitialExpression = {..SessionControlerTimeout()}

];

2 – Criar o método SessionControlerTimeout()

ClassMethod SessionControlerTimeout() As %Status [ Final, Private ]

{

// inicializa a propriedade ‘ControleTimeout‘

Do %session.Set("ControleTimeout",0)

Quit $$$OK

}

Page 208: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 207

Na página de Menu crie dois métodos.

Method %OnAfterCreatePage() As %Status

{

Set timer = ##class(%ZEN.Component.timer).%New()

Set timer.id = "timer"

Set timer.timeout = 30*1000 //a cada 30s

Set timer.ontimeout =

"zenPage.atualizaTimer();zenPage.getComponentById('timer').startTimer()"

Do %page.%AddChild(timer)

Quit $$$OK

}

ClassMethod atualizaTimer() As %Status [ ZenMethod ]

{

Set valorAtual = %session.Get("ControlTimeout")

Set valorAtual = valorAtual + 30

If %session.AppTimeout-valorAtual<60

{

&js<zenPage.logout();>

}

Do %session.Set("ControlTimeout",valorAtual)

Quit $system.Status.OK()

}

Page 209: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 208

Módulo – Componentes Customizados

Módulo – Componentes Customizados

Page 210: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 209

Page 211: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 210

Componentes Customizados

• Zen é um framework EXTENSÍVEL devido a possibilidade de poder criar novos componentes,

personalizar componentes existentes, construir novos medidores, etc.

• Há 4 opções para criar componentes personalizados:

– Construir um componente composto;

– Modificar o estilo de um componente;

– Criar um componente novo;

– Criar um novo medidor.

Componentes Compostos

• Um componente composto une um grupo de componentes embutidos ao Zen, e permite

referenciar este grupo, dentro do bloco XData Contents, como se fosse um único componente.

• Exemplo: A classe seguinte cria um novo componente composto.

Este novo componente, chamado compComposto, possui dois botões e um método que é

executado ao clicar em um dos botões.

• Uma vez criada a classe do componente composto, ele pode ser utilizada em qualquer outra

página Zen.

• Para incluir o componente composto criado pela classe anterior, basta inserir o componente e

fazer as devidas referências ao namespace do componente.

Page 212: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 211

Criando componentes customizados

• Para criar um componente novo, uma nova classe deve ser criada que herde de uma classe

base Zen.

• Sua classe nova começa automaticamente com as seguintes características:

– Uma projeção XML para usar na classe da página XData Contents

– Algumas propriedades, métodos, parâmetros, ou outras características.

– Manipulação apropriada de algum material do lado cliente da classe:

• JavaScript

• CSS style definitions

• HTML

• SVG

– As propriedades podem ser expostas para configuração, para visualização e usar para

modificar os métodos do lado cliente getProperty e setProperty.

• A tabela seguinte é uma lista de verificação para criar uma classe de componente customizada

Task Descrição

Page 213: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 212

Classes Bases para componentes Customizados

Estilo Customizado

• Para definir um novo estilo CSS para um componente customizado, você pode colocar um

XData Style block dentro de uma sub-classe. Dentro deste bloco abra um <style type="text/css">

e feche com </style>.

• Exemplo

XData Style {

<style type="text/css"> /* @doc="Main style definition for MyComponent." */ .MyComponent { color: blue; background: yellow; white-space: nowrap; }

</style> }

Page 214: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 213

Propriedades Customizadas

• Sendo um componente uma classe, você pode definir propriedades além das herdadas.

– Nomenclatura

• Propriedades somente cliente: minhaPropriedade

• Propriedade somente Servidor (o % é essencial): %MinhaPropriedade

• Propriedades que invocam um evento JavaScript: onmousedown

• Propriedades que identificam um método callback server-side callback :

OnCreateDataSet

• Outras Propriedades: minhaPropriedade

– Projeção XML

• Todos os componentes Zen são derivados da classe %XML.Adaptor e usam

este mecanismo para definir o comportamento XML

• Toda propriedade simples de componente Zen pode ter um valor de atributo

XMLPROJECTION. Se você não quiser fazer uma propriedade visível através de

XML, ajuste seu parâmetro de XMLPROJECTION para “none" como no seguinte

exemplo:

• Property beeswax As %ZEN.Datatype.string(XMLPROJECTION="none");

– Método setProperty

• Se você adicionar uma propriedade a uma classe de componente customizada,

você deve cancelar o método setProperty. – Parâmetros Datatype

• Toda a classe Zen herda (de %ZEN.componentParameters) o seguinte conjunto

de parâmetros da propriedade, que você pode aplicar a toda a propriedade você

adiciona a uma classe de Zen

– ZENENCRYPT

– ZENEXPRESSION

– ZENLOCALIZE

– ZENSETTING

– Classes Datatype

• Para a conveniência, Zen fornece um conjunto de classes datatype que você

pode usar ao definir propriedades Zen. As classes do datatype estão no pacote

de %ZEN.Datatype.

Page 215: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 214

Métodos Customizados

As definições destes métodos influenciam onde e como podem ser usadas.

Chamado de Executado em Linguagem Keyword Nomenclatura

Cliente Cliente JavaScript Language =

JavaScript myMethod

Cliente Server ObjectScript ou

Basic ZenMethod MyMethod

Server Server ObjectScript ou

Basic — %MyMethod

Criação de um medidor personalizado

Esta tabela é seu checklist para construir um componente medidor personalizado. Veja os exemplos no

próximo slide.

Task Description

Subclass Extend %ZEN.SVGComponent.meter to create a new class.

renderMeter

Any subclass of %ZEN.SVGComponent.meter must override this method to render

the SVG contents of the meter. The odometer and clock examples show how to make

SVG calls from the meter class.

Parameters

(Optional) Provide class parameters and appropriate values. The odometer example

overrides the DEFAULTHEIGHT and DEFAULTVIEWBOXHEIGHT parameters from

the base meter class.

Properties

(Optional) Provide properties, if needed. The odometer sets a maximum number of

digits for its display. The clock overrides the value property from the base meter class

with an ObjectScript expression that is evaluated each time the meter is displayed.

For the clock, this expression calculates the current time.

Page 216: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 215

XData SVGStyle (Optional) Provide any CSS style definitions for the meter.

XData SVGDef (Optional) Provide any SVG definitions for the meter.

setProperty

(Optional) You may override this method to provide unique ways to set certain

properties of the meter. The clock example does this for the value property, then

defers to the superclass for setting all other properties.

Methods (Optional) Provide supporting methods as needed for component behavior.

renderLabel (Optional) Any subclass of %ZEN.SVGComponent.meter may override this method to

set the x and y positions of the meter label.

XML Element To add the component to a page, place it within that page’s XData Contents block as

an XML element. Examples of this convention follow this table.

Criação de um novo medidor

• Para criar um novo medidor é também necessário criar uma classe que deriva de uma classe

Zen de componentes SVG.

• Também pode-se criar novos parâmetros para classe, propriedades, escrever métodos que

desenham o medidor, etc.

• Exemplos de medidores personalizados:

Page 217: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 216

Exercícios – Componentes Customizados

Podemos customizar o componente ‘DateText‘ para criar um componente com barras automáticas na

digitação, por exemplo. Queremos a data no padrão 'D / M / Y'. Depois de digitar os dois primeiros

números uma barra será adicionada depois mais dois e mais um barra e depois mais 4 dígitos.

1. Crie a classe ‘ISCUser.Componente.Data.cls’, derivada de %ZEN.Component.dateText.

2. Localize a tag <input type="text“> dentro do método %DrawHTML e modifique o manipulador de

eventos 'onkeyup‘ para chamar o método mascara():

‘zenPage.getComponent(#(..index)#).mascara(event,this)’

O argumento 'event' é o evento no cliente e ‘this’ é o objeto do componente na página.

Crie método mascara() que possui dois argumentos, pE é a tecla digitada e pComponent é o

objeto.

Method mascara(pE, pComponent) [ Language = javascript ]

{

var whichCode = (window.Event) ? pE.which : pE.keyCode;

//cod. teclado: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

var strCheck = '48,49,50,51,52,53,54,55,56,57,96,97,98,99,100,101,102,103,104,105';

if (strCheck.indexOf(whichCode) == -1 || whichCode==8) return;

vr = new String(pComponent.value);

tam = vr.length;

if (tam == 2)

{

pComponent.value = vr + '/';

}

if (tam == 5)

{

pComponent.value = vr + '/';

}

}

Page 218: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 217

4. Crie na classe do componente os parâmetros.

Parameter DOMAIN = "iscuser";

Parameter NAMESPACE = "http://www.iscuser.com/iscuser";

5. Teste sua Data na classe ‘Exames.cls’, no método PropriedadeInfo.

Set pInfo ( "Data", "%type") = “ISCUser.Componente.Data“

Set pInfo ( "Data", "format") = "DMY"

Set pInfo ( "Data", "separator ")="/"

Para que informemos a data no formato Europeu e tenha ‘/’ como delimitador.

Page 219: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 218

Módulo – Localização

Módulo – Localização

Page 220: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 219

Page 221: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 220

Localização

• A localização é um poderoso recurso do Caché disponível tanto para CSP quanto para Zen que

torna possível a tradução dos textos da aplicação, para mensagens apresentadas ao usuário,

título dos controles, textos informativos para botões, etc.

• Com o Zen esse recurso é ainda mais fácil de ser utilizado, pois faz automaticamente a

identificação dos textos que precisam ser traduzidos.

Page 222: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 221

O próximo código mostra o uso de Linguagem utilizando uma página Zen

/// Created using the page template: Default Class CursoZen.Aplic.localizacao Extends %ZEN.Component.page { /// Class name of application this page belongs to. Parameter APPLICATION = “CursoZen.Aplic.MinhaNovaAplic"; /// Displayed name of this page. Parameter PAGENAME = "localizacao"; /// Domain used for localization. Parameter DOMAIN = “CursoZen"; /// This Style block contains page-specific CSS style definitions. XData Style { <style type="text/css"> </style> } /// This XML block defines the contents of this page. XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title=""> <label label="Page Test with Localization ..." labelStyle="font-size:20px" /> <fieldSet legend="Controls" align="center"> <text label="Code"/> <text label="Name"/> <hgroup> <button caption="Save"/> <button caption="Return"/> <button caption="Language" onclick="zenPage.Message();"/> </hgroup> </fieldSet> </page> } ClassMethod Message() [ ZenMethod ] { set msg = $$$TextJS("Your Language is: ") &js<alert('#(msg_" - "_%session.Language)#');> Quit } }

Textos à traduzir

Page 223: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 222

Page 224: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 223

"Nome"=^CacheMsg("CursoZen","pt-br",4262580536)17:

"Salvar"=^CacheMsg("CursoZen","pt-br",4115961312)16:

"Código"=^CacheMsg("CursoZen","pt-br",3609698214)15:

"SuaLinguagemé: "=^CacheMsg("CursoZen","pt-br",2722840033)

14:

"Voltar"=^CacheMsg("CursoZen","pt-br",2687646265)13:

"Página de Teste com Zen"=^CacheMsg("CursoZen","pt-br",1403964196)12:

"Language"=^CacheMsg("CursoZen","pt-br",766317539)11:

"Controles"=^CacheMsg("CursoZen","pt-br",60550761)10:

"Name"=^CacheMsg("CursoZen","en",4262580536)9:

"Save"=^CacheMsg("CursoZen","en",4115961312)8:

"Code"=^CacheMsg("CursoZen","en",3609698214)7:

"Your Language is: "

=^CacheMsg("CursoZen","en",2722840033)

6:

"Return"=^CacheMsg("CursoZen","en",2687646265)5:

"Page Test with Localization ..."=^CacheMsg("CursoZen","en",1403964196)4:

"Language"=^CacheMsg("CursoZen","en",766317539)3:

"Controls"=^CacheMsg("CursoZen","en",60550761)2:

“pt-br"=^CacheMsg("CursoZen")1:

"Nome"=^CacheMsg("CursoZen","pt-br",4262580536)17:

"Salvar"=^CacheMsg("CursoZen","pt-br",4115961312)16:

"Código"=^CacheMsg("CursoZen","pt-br",3609698214)15:

"SuaLinguagemé: "=^CacheMsg("CursoZen","pt-br",2722840033)

14:

"Voltar"=^CacheMsg("CursoZen","pt-br",2687646265)13:

"Página de Teste com Zen"=^CacheMsg("CursoZen","pt-br",1403964196)12:

"Language"=^CacheMsg("CursoZen","pt-br",766317539)11:

"Controles"=^CacheMsg("CursoZen","pt-br",60550761)10:

"Name"=^CacheMsg("CursoZen","en",4262580536)9:

"Save"=^CacheMsg("CursoZen","en",4115961312)8:

"Code"=^CacheMsg("CursoZen","en",3609698214)7:

"Your Language is: "

=^CacheMsg("CursoZen","en",2722840033)

6:

"Return"=^CacheMsg("CursoZen","en",2687646265)5:

"Page Test with Localization ..."=^CacheMsg("CursoZen","en",1403964196)4:

"Language"=^CacheMsg("CursoZen","en",766317539)3:

"Controls"=^CacheMsg("CursoZen","en",60550761)2:

“pt-br"=^CacheMsg("CursoZen")1:

Page 225: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 224

Exercícios – Language (Localização)

1. Crie uma Propriedade na página de Menu. Property SessionLanguage As %String [ InitialExpression = {%session.Language} ];

2. Crie dentro de <vgroup id="flags" width="10%“>

<label id="lan" align="center" label="Language: #(%page.SessionLanguage)#"/> <spacer width="100" /> <hgroup width="100%"> <image id="flag1" src="images\BandeiraBrasil.jpg" width="30" height="15"

onclick="zenPage.Modifica('pt-br');"/> <image id="flag2" src="images\BandeiraUsa.jpg" width="30" height="15"

onclick="zenPage. Modifica('en');"/> <image id="flag3" src="images\BandeiraEspanha.jpg" width="30" height="15"

onclick="zenPage. Modifica('es');"/> </hgroup>

3. Crie o método Modifica(); Method Modifica(pFlag) [ ZenMethod ] { set (%session.Language,%page.SessionLanguage)= pFlag &js<zenPage.reloadPage();> Quit } Method reloadPage() [ Language = javascript ] { document.location.reload(); }

4. Exporte o texto através de: Do ##class(%Library.MessageDictionary).Export(file) Traduza. Importe através de: Do ##class(%Library.MessageDictionary).Import(file). Consulte a global ^CacheMsg.

Page 226: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 225

Page 227: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 226

Módulo – Programação da Aplicação

Módulo – Programação da Aplicação

Page 228: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 227

Page 229: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 228

Programação da Aplicação

Uma aplicação de Zen especifica um conjunto de atividades que podem resultar quando um cliente Zen e um servidor Zen interagem. Estas atividades podem consistir em páginas Web pages, query’s de uma base de dados, gravar dados no disco, e mais. Quando você cria uma aplicação de Zen, você cria um suite das classes de Zen que especificam estas atividades. A linguagem que você usa para estas classes é o Caché ObjectScript - com possibilidades de uso de XML, de HTML, de SVG, e de Javascript quando necessário Zen é um framework extensível para criação rápida de aplicações baseadas na Web.

Classes Zen são Classes CSP

• A base das classes da aplicação %ZEN.application e a base das classes de páginas %ZEN.Componente.page são herança de %CSP.page.

• Isto significa que cada classe da aplicação Zen e cada classe de página Zen são também uma instancia de Caché Server Page.

• Todas as propriedades, métodos, parâmetros e variáveis do CSP (como a %session) estão disponíveis nas páginas de uma aplicação Zen.

Classes de Applicação Zen

• Cada aplicação de Zen tem uma classe da aplicação. Esta é uma classe derivada de

%ZEN.application que fornece tarefas comuns e age como a única raiz para todas as páginas na aplicação.

• A seguinte tabela lista os elementos de uma classe de Aplicação Zen:

Elemento Tipo

APPLICATIONNAME Parâmetro de Classe

CSSINCLUDES Parâmetro de Classe

HOMEPAGE Parâmetro de Classe

JSINCLUDES Parâmetro de Classe

USERPACKAGES Parâmetro de Classe

USERSVGPACKAGES Parâmetro de Classe

XData Style Documento XML Embutido

Page 230: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 229

Classe de Páginas Zen

• As páginas dentro de uma aplicação de Zen são derivadas da classe %ZEN.Component.page.

Uma classe da página define e serve aos componentes de uma página Zen em um browser. • A seguinte tabela lista os elementos de uma classe de Página Zen:

Parâmetros Descrição

APPLICATION Nome do pacote e da classe da aplicação associada.

AUTOLOGOUT Se 1 (true) tentative de refresh nesta págian quando a sessão expirar. Se 0 (false) não faz. O default é 1.

CSSINCLUDES Lista separada por virgule do estilo CSS.

DOMAIN Usado para a Localização. O default é "" (vazio).

JSINCLUDES Lista separada por vírgula, de arquivos JavaScript incluidos na página.

PAGENAME Define uma string que você possa usar nos títulos ou nos label´s. Se não especificado, o nome da classe da página de Zen é usado

PAGETITLE Valor default para o atributo title.

RESOURCE Nome de um recurso de sistema para que o usuário atual deve prender privilégios do USO a fim ver esta página ou invocar alguns de seus métodos do server-side do cliente.

USERPACKAGES Lista separada por vírgulas dos pacotes definidos pelo usuário da classe cujas definições da classe e do estilo do HTML estão pré geradas incluindo arquivos.

USERSVGPACKAGES Lista separada por vírgulas dos pacotes definidos pelo usuário da classe cujas definições SVG que estão pré geradas incluindo arquivos.

Page 231: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 230

Classe de Páginas Zen

• Zen oferece diversas variáveis especiais que representam instâncias de objetos de vários tipos

dentro da aplicação de Zen. • A seguinte tabela lista as variáveis especiais:

Server Side Variáveis Refers To Uso nestas classes

Uso em Zen Runtime Expressions

%application Objeto da aplicação Página Não

%composite Objeto composto atual Página, Componente Sim

%page Objeto da página atual Página, Componente Sim

%query Objeto atual de ResultSet Página, Componente Sim

%session Objeto atual da sessão CSP Página, Componente Sim

%this Objeto atual (página ou componente) Página, Componente Sim

%url

Um objeto cujas as propriedades sejam parâmetros de URI da página atual

Página, Componente Sim

%zenContext String que indica o que o código do usuário está fazendo atualmente

Página Não

Page 232: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 231

Classes de Páginas Zen – Variáveis Especiais

• %application:

• A variável de server-side %application está disponível em cada classe da página de Zen.

Pretende-se para o uso nos métodos que funcionam quando o objeto da página for criado.

• Para o exemplo, o seguinte método é definido na classe ZENDemo.Application da aplicação: ClassMethod GetQuickLinks(Output pLinks) As %Status { Set pLinks("Home") = "ZENDemo.Home.cls" Set pLinks("Expense Calculator") = "ZENDemo.ExpenseCalculator.cls" Set pLinks("MVC Master Detail") = "ZENMVC.MVCMasterDetail.cls" Set pLinks("MVC Chart") = "ZENMVC.MVCChart.cls" Set pLinks("MVC Meters") = "ZENMVC.MVCMeters.cls" Set pLinks("MVC Form") = "ZENMVC.MVCForm.cls" Set pLinks("Test Suite") = "ZENTest.HomePage.cls" Set pLinks("Controls") = "ZENDemo.ControlTest.cls" Set pLinks("Methods") = "ZENDemo.MethodTest.cls" Quit $$$OK }

• As classes que são associadas com esta aplicação podem então invocar este método

como: Class ZENDemo.ExpenseCalculator Extends %ZEN.Component.page { /// Application this page belongs to. Parameter APPLICATION = "ZENDemo.Application"; // ...Intervening lines removed... /// Return an array of quick links to be displayed by the locator bar. ClassMethod GetQuickLinks(Output pLinks) As %Status { // dispatch to our application class Quit %application.GetQuickLinks(.pLinks) } }

Page 233: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 232

• %page e zenPage

• Zen oferece variáveis especiais para representar o objeto da página de Zen nos lados client e server :

• Em ObjectScript ou no código Basic que funciona no lado do usuário, o objeto da página é %page: Set btn = %page.%GetComponentById("NewBtn1“)

• Em Zen runtime expressions, o objeto da página é %page: text id="rows" label="Rows:" value="#(%page.Rows)#" size="5"/>

• Em métodos JavaScript que rodam no lado clint, o objeto da página é zenPage: var chart = zenPage.getComponentById('chart');

• Em JavaScript expressions que são valores de atributos XML, o objeto da página é zenPage: <button caption="+" onclick="zenPage.makeBigger();"/>

• %this, this, e zenThis

• Zen oferece variáveis especiais representar um objeto de Zen (componente ou página) no client e server sides:

• Em ObjectScript ou no código Basic que funciona no lado do usuário, o objeto da página é %this:

Set %this.Name = pSource.Name • Em Zen runtime expressions, o objeto da página é %this:

<html>Item #(%this.tuple)#: <b>#(%query.Title)#</b></html> • Em métodos JavaScript que rodam no lado clint, o objeto da página é this:

var out = this.getComponentById('events'); • Em JavaScript expressions que são valores de atributos XML, o objeto da

página é zenThis: onchange="zenPage.changeLayout('svgFrame',zenThis.getValue());"

• zenEvent

• Suponha que você tem uma expressão Javascript como o valor de um atributo do evento

de XML, tal como o onchange no seguinte exemplo do listBox. <listBox id="listBox" label="listBox" listWidth="240px" onchange="zenPage.notifyOnChange(zenThis);" value="2">

<option value="1" text=“Maça" /> <option value="2" text="Banana" style="font-size: 1.5em; "/> <option value="3" text=“Cereja" /> <option value="4" text=“Abóbora" /> <option value="5" text="Eggplant" style="font-size: 2.1em; "/> </listBox>

A variável especial zenEvent consulta o objeto atual do evento Javascript que descreve o evento zenEvent fornece uma maneira “browser-neutra” de começar o acesso ao evento atual (tal como um clique No mouse). No exemplo acima, o onchange references o método do notifyOnChange. O método notifyOnChange do lado cliente pode referenciar a variável especial zenEvent dentro de seu código do Javascript.

Page 234: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 233

• %zenContext

• Quando toda a atividade no usuário está pelo Zen, a variável especial %zenContext do server-side diz que tipo de atividade é esta. %zenContext é uma String. Se %zenContext tiver o valor, será:

• page, Zen está servindo à página em resposta a um pedido do HTTP • submit, Zen está processando um submit request • method, Zen está processando um hyperevent

Classe de Páginas Zen – Zen Runtime Expressions

• Zen Runtime Expressions

• Páginas sempre fornecendo a informação estática em uma descrição de página Zen, às

vezes é útil para a página que funciona no cliente para poder invocar as runtime Expression que executam no server.

• Uma runtime expression é incluido dentro # () # e vê algo assim:

<button caption="#(minhaPropriedade)#" /> • Onde minhaPropriedade tem um valor específico no server.

• A sintaxe Zen runtime expression pode ser usada, com restrições, somente nos

seguintes contextos • XML que está embutido com o bloco Xdata

<button caption="#(%query.Name)#" onclick="alert('#(%query.Name)#')"/>

• Um método server-side Caché ObjectScript ou ZenMethod (mas não um método JavaScript) &html<<li>#($ZCVT(tBullet.text,"O","HTML"))#</li>>

• JavaScript que é embutido com um bloco &js<> em um ZenMethod • Uma expressão JavaScript desde que como o valor de um atributo de XML tal

como o onclick • HTML que é embutido com um bloco &html<> block em um método server-side

• Os seguintes itens não podem aparecer dentro do # () # delimitadores de uma Zen

runtime expression:

• Chamada para macros, como $$$Text • Expressões JavaScript • Expressões ObjectScript, a menos que a expressão runtime aparecer dentro de

a método server-side ObjectScript ou ZenMethod

Page 235: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 234

Propriedades Zen no client e Server • No lado server, você pode ajustar valores de propriedades da classe diretamente,

usando a sintaxe normal do ponto. Por exemplo:

Method serverInstanceMethodCreate() [ ZenMethod ] { #; create Set group = %page.%GetComponentById("group") If '$IsObject(group) { &js<alert('Unable to find group.');> Quit } Set count = group.children.Count() Set cal = ##class(%ZEN.Component.calendar).%New() Set cal.id = "NewCal"_count Do group.%AddChild(cal) Set btn = ##class(%ZEN.Component.button).%New() Set btn.id = "NewBtn"_count Set btn.caption = "New Button" Do group.%AddChild(btn) Set btn = ##class(%ZEN.Component.text).%New() Set btn.label = "Hey" Do group.%AddChild(btn) }

• No lado cliente, você não pode acessar valores de propriedade diretamente. Você deve usar os métodos get e set fornecidos nas classes de componentes. Para propriedades single-valued, use os métodos getProperty e setProperty.

• Por exemplo: var index = table.getProperty('selectedIndex');

• Ou: var svg = zenPage.getComponentById('svgFrame'); svg.setProperty('layout',''); svg.setProperty('editMode','drag');

• Importante: • Não confunda o getProperty e o setProperty com os métodos getValue e

setValue, que manipulam valor de um componente do controle, e não os aplique a nenhuma outra propriedade do componente.

Page 236: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 235

ZENURL

• Para receber um parâmetro passado pela url, dentro da classe, use ZENURL.

• Depois, use em qualquer posição na página com a sintaxe #(%page.Propriedade)#.

• Se não desejar criar propriedades dentro da classe use: #(%url.Propriedade)# . Ex.: modelId="#(%url.ModelId)#“

Exemplo:

Property DataInicio As %String(ZENURL = “datainicio”);

Métodos Zen

• A seguinte tabela esboça as possibilidades para tipos diferentes de método em uma classe da página de Zen

Chamado de

Executa no

Tipo de Class Chamada Linguagem do

Código Keyword Nomemclatura

Cliente Cliente Instância — JavaScript Language

= JavaScript

meuMétodo

Cliente

Server

(Can send

back code

that runs

on the

client)

Instância Assíncrono

ObjectScript ou

Basic ZenMethod MeuMétodo

Sincrono

Classe

Assíncrono

Sincrono

Server Server Instância — ObjectScript or Basic — %MeuMétodo

Page 237: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 236

Métodos Zen – Métodos Server-Side Callback

Callback Method Descrição

%OnBeforeCreatePage Este método de classe é chamado imediatamente antes que o objeto da página do server-side seja criado.

%OnCreatePage Este método de instância é chamado imediatamente depois que o objeto da página do server-side é criado mas antes que alguns de seus componentes filhos sejam criados.

%OnAfterCreatePage

Este método de instância é chamado após o objeto da página server-side e todos seus componentes filhos predefinidos são criados. Uma sub-classe pode cancelar este método para adicionar, para remover, ou para modificar itens dentro da página de modelo, ou para fornecer valores para controles.

%OnDrawHTMLHead

Este método de Instância é chamado quando o HTML para a página está sendo redirecionado imediatamente antes da extremidade da seção HTML HEAD da página. Isto fornece uma maneira de adicionar componentes na seção PRINCIPAL de uma página se este for sempre necessário.

%OnDrawHTMLBody

Este método de Instância é chamado quando o redirecionamento HTML para a página é fechado para que inicie a seção HTML BODY (antes que seus filhos sejam redirecionados). Isto fornece uma maneira adicional na seção do BODY de uma página sempre que isto for necessário.

Page 238: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 237

Métodos Zen – Métodos Server-Only

Método Descrição

%GetComponent Encontra um objeto componente dado seu número de índice.

%GetComponentById Encontra um objeto componente dado seu valor de identificação de ID.

%GetComponentByName Encontra um objeto componente dado seu nome.

%GetValueById Encontra o valor de um objeto do controle dado seu ID

%GetValueByName Encontra o valor de um objeto de controle dado o seu nome.

%SetErrorById Atribui o valor de uma mensagem de erro a um componente dado o ID

%SetErrorByName Atribui o valor de uma mensagem de erro a um componente dado seu nome.

%SetValueById Atribui valor de um objeto do controle dado seu valor de ID

%SetValueByName Atribui o valor de um objeto de controle dado o seu nome.

%SetValuesByName Atribui os valores de um conjunto de objetos do controle dados uma disposição dos valores subscritos por nome.

Page 239: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 238

Métodos Zen – Método Callback de Página do Lado Cliente

Método Callback Descrição

onloadHandler Este método da página do lado cliente, se definido, é chamado quando a página do cliente termina seu carregamento (é chamada pelo evento onload do HTML da página).

onpopupAction Este método da página do lado cliente, se definido, é chamado quando uma janela popup, lançada para esta página, é terminada.

onresizeHandler Este método da página do lado cliente, se definido, é chamado quando a página do cliente é redimensionada (está chamada pelo evento HTML da página onresize).

onunloadHandler Este método da página do lado cliente, se definido, é chamado quando a página do cliente está a ponto de descarregar (é chamada pelo evento onunload do HTML da página).

Page 240: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 239

Métodos Zen – Métodos de Pagina do Lado Cliente

Método Descrição

cancelPopup (Popup somente windows). Feche a janela atual popup com nenhuma ação adicional.

createComponent Cria um novo componente na página (pelo nome do componente).

createComponentNS Cria um novo componente na página (pelo nome do componente e namespace).

endModal Esconda o modalGroup atual, se houver um.

getComponent Encontre um componente na página dada seu número de índice atribuido no sistema.

getComponentById Encontre um componente na página dada seu valor de ID.

startModal Coloca um modalGroup visível. Alternadamente, use o método show do modalGroup.

Page 241: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 240

Métodos Zen – Método de componente do Lado Cliente

Método Descrição

findElement Procura um elemento nomeado HTML associado com um componente específico

getEnclosingDiv Pega o elemento HTML div usado para incluir um componente específico

getHidden Retorne se um componente está escondido (ou exibido).

getProperty Retorna o nome da propriedade de um componente.

getSettings Recupera e atribuiGet nomes de propriedades que podem ser observadas e modificadas usando getProperty e setProperty.

getValue (Sub-classe somente para controles). Recupera o valor de um controle. É equivalente a chamada getProperty('valor').

invokeSuper Invoca a o método implementado da super classe do corrente componente.

isOfType Testa se o componente é uma sub-classe (é um tipo de) outro componente.

refreshContents Faz a request para o servidor regerar a definição HTML do componente. Para componentes tablePane, usa a instância de executeQuery.

setHidden Atribui se um componente está escondido (ou exibido).

setProperty Atribui o valor de uma propriedade para um componente.

setValue (Sub-classe somente para controles). Atribui um valor para um controle.

Page 242: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 241

Page 243: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 242

Respostas dos Exercícios

Respostas dos Exercícios

Page 244: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 243

Page 245: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 244

Respostas dos Exercícios Abaixo estão as classes completas criadas durante os exercícios em ordem alfabética. Aplicação Class ISCUser.Aplic.Aplicacao Extends %ZEN.application { /// Este é o nome desta aplicação. Parameter APPLICATIONNAME = "Minha Aplicacao"; /// Esta é a URL da página inicial principal desta aplicação. Parameter HOMEPAGE; /// Este bloco de estilos contém definições de estilo CSS válidas para toda a aplicação. XData Style { <style type="text/css"> *{ /* padrão texto geral */ padding-left:0px; padding-right:0px; margin:0; font-size:11px; font-family: Arial, Helvetica, sans-serif; color: #003082; } body{ /* fundo geral */ /*#E6E6FA*/ background-color: #D3E0EE; } .iframe{ } .textol{ /* texto página de login e dynaForm dos modelos de cadastro */ text-align: center; font-family: Arial, Helvetica, sans-serif; color: #003082; font-size: 10px; } .caixatextolU{ /* caixa de texto página de login UPPER */ border:solid 1px #7F9DB9; font-family: Arial; font-size: 10px; TEXT-TRANSFORM: uppercase; } .caixatexto{ /* caixa de texto padrão */ border:solid 1px #7F9DB9;

Page 246: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 245

font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-style: normal; color: #003082; background-color: #F5FAFC; } .botaol{ /* botão página de login */ color: #003082; width: 91px; background-color: #DAE4F1; font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-style: normal; line-height: normal; border: 1px solid #7F9DB9; text-transform: none; } p { /* estilo do parágrafo */ padding-bottom:5px; } a { /* estilo dos links */ color: #003082; } a:hover { /* em cima do link */ color: #003082; } a:visited { /*links já visitados*/ color: #003082; } .menu_fundo { /*estabelece a area fundo do menu */ width:auto; height:34px; background-color: #E9F4F8; border-top: 1px solid #C0C0C0; border-bottom: 1px solid #C0C0C0; border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0; } .tabelaMenu { /* classe do table do menu */ background-color:#DAECF3; border: 1px solid #CCCCCC; height: auto; font-family: Arial, Helvetica, sans-serif; font-size: 10px; color: #003082;

Page 247: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 246

font-style: normal; font-weight: bold; background-position: center; } .celulaMenu { /* classe do td do menu */ background-color: #E9F4F8; border-right: 1px solid white; border-left: 1px solid white; border-top: 1px solid #C0C0C0; border-bottom: 1px solid #C0C0C0; border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0; cursor:pointer; width:80px; text-align:center; vertical-align:middle; } .celulaFavoritos { /* classe do td do Favoritos */ background-color: #F5FAFC; cursor:pointer; width:80px; text-align:center; vertical-align:middle; border-right-width: 1px; border-left-width: 1px; border-right-style: solid; border-left-style: solid; border-right-color: #CCCCCC; border-left-color: #CCCCCC; } .tabelaSubMenu { /* classe do table dos submenus */ background-color:#E9F4F8; font-family: Arial, Helvetica, sans-serif; font-size: 12px; font-style: normal; font-weight: bold; color: #003082; background-position: left; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; } .tabelaSubMenuFavoritos { /* classe do table do submenu do Favoritos*/ background-color:#E9F4F8; font-family: Arial, Helvetica, sans-serif; font-size: 10px;

Page 248: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 247

font-style: normal; font-weight: normal; filter: Invert; cursor: auto; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; } .celulaSubMenu { /* classe do td dos submenus */ border-top: 1px solid white; padding-left:5px; padding-right:5px; padding-top:0px; padding-bottom:0px; cursor:pointer; } .usuario { /* descricao usuário logado */ width:193px; float:right; text-align:right; padding-top:3px; background-image:url(../imagens/fundo_usuario.gif); background-repeat:no-repeat; padding-right:10px; } .rodape { /* rodapé página principal */ font-size:10px; color:#666666; } .rodape a { /* link rodapé página principal */ font-size:10px; clear:both; } .titulo { /* para todos os títulos de janelas */ color: #003082; font-weight:bold; font-size: 12px; } .destaque{ color: #cc0000; font-weight:bold; font-size: 12px; text-align: left; } .titulodestaque{ color: #FF0000; font-size: 14px; font-family: Arial, Helvetica, sans-serif; font-weight: bold;

Page 249: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 248

} .textodestaque{ color: #FF0000; font-size: 12px; font-family: Arial, Helvetica, sans-serif; font-weight: bold; } .comboboxImgButton { /*imagem do botao do combobox */ background: white; vertical-align: middle; border-top: 1px solid #7F9DB9; border-bottom: 1px solid #7F9DB9; border-left: 1px solid #7F9DB9; border-right: 1px solid #7F9DB9; width: 1.3em; height: 1.4em; } .comboboxInput { /* caixa de texto do combobox */ vertical-align: middle; border-top: 1px solid #7F9DB9; border-bottom: 1px solid #7F9DB9; border-left: 1px solid #7F9DB9; border-right: none; font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-style: normal; font-weight: normal; background-color: #F5FAFC; color: #003082; } .text { /*campos de texto comum*/ vertical-align: middle; border-top: 1px solid #7F9DB9; border-bottom: 1px solid #7F9DB9; border-left: 1px solid #7F9DB9; border-right: 1px solid #7F9DB9; font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-style: normal; font-weight: normal; background-color: #F5FAFC; color: #003082; } .password { vertical-align: middle; border-top: 1px solid #7F9DB9; border-bottom: 1px solid #7F9DB9; border-left: 1px solid #7F9DB9; border-right: 1px solid #7F9DB9;

Page 250: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 249

font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-style: normal; font-weight: normal; background-color: #F5FAFC; color: #003082; } .controlStyle { vertical-align: middle; border-top: 1px solid #7F9DB9; border-bottom: 1px solid #7F9DB9; border-left: 1px solid #7F9DB9; border-right: 1px solid #7F9DB9; font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-style: normal; font-weight: normal; background-color: #F5FAFC; color: #003082; } .tabGroupBody { /* corpo do tabGroup (height de 100% para ajustar-se ao conteúdo, necessário no Firefox) */ background: white; border-right: 1px solid black; border-left: 1px solid black; border-bottom: 1px solid black; height: 100%; } .textonormal { font-family: Arial, Helvetica, sans-serif; font-size: 10px; color: #003082; font-style: normal; font-weight: normal; } .textobold { font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; color: #003082; font-style: normal; } .textoboldbranco { color: #FFFFFF; font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-weight: bold; } .celulatabelatitulo {

Page 251: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 250

font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-style: normal; font-weight: bold; color: #003082; background-color: #DAECF3; background-position: center center; } .celulatabelainterna { font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-style: normal; font-weight: normal; color: #003082; background-color: #F5FAFC; background-position: center center; } .celulatabelainternabold { font-family: Arial, Helvetica, sans-serif; font-size: 10px; font-style: normal; font-weight: bold; color: #003082; background-color: #F5FAFC; background-position: center center; } </style> } }

Page 252: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 251

Data Personalizada Class ISCUser.Componente.Data Extends %ZEN.Component.dateText { Parameter DOMAIN = "iscuser"; Parameter NAMESPACE = "http://www.iscuser.com/iscuser"; Method %DrawHTML() { #; do not add this to set of events Set tIgnore("onchange")="" Set disabled = $S(..disabled:"disabled",1:"") Set ro = $S(..readOnly:"readonly",1:"") Set bflag = $S(..readOnly:"readonly",1:"") #; if localized properties have not been set, set them Set:..dayList="" ..dayList = $$$Text("S,M,T,W,T,F,S") Set:..monthList="" ..monthList = $$$Text("January,February,March,April,May,June,July,August,September,October,November,December") Set:..timeCaption="" ..timeCaption = $$$Text("Time:") #; if there are expressions for these props, evaluate Set ..minDate = $$$ZENVAL(..minDate) Set ..maxDate = $$$ZENVAL(..maxDate) Set ..format = $$$ZENVAL(..format) Set ..separator = $$$ZENVAL(..separator) #; Get value Set tValue = $$$ZENVAL(..value) Set tDisplayValue = tValue &html<<table border="0" cellspacing="0" cellpadding="0">> #; render as one line as CR will mess up the display &html<<tr><td style="white-space: nowrap"> <input class="#(..controlClass)#" type="text" size="#(+..size)#" id="#(..%MakeId("control"))#" #(..%Attr("title",..title))# #(..%Name())# #(disabled)# #(ro)# #(..%Attr("value",tDisplayValue))# #(..%Attr("tabindex",..tabIndex))# #(..%GetEventHandlers(.tIgnore))# onchange="zenPage.getComponent(#(..index)#).ondatechangeHandler();" onkeyup="zenPage.getComponent(#(..index)#).mascara(event,this);" /> <img src="/csp/broker/images/datetext.gif" id="#(..%MakeId(""))#" onclick="zenPage.getComponent(#(..index)#).showDateSelector();" class="comboboxImgButton"/> </td></tr>> &html<</table>> }

Page 253: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 252

Method mascara(pE, pComponent) [ Language = javascript ] { var whichCode = (window.Event) ? pE.which : pE.keyCode; //cod. teclado: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 var strCheck ='48,49,50,51,52,53,54,55,56,57,96,97,98,99,100,101,102,103,104,105'; if (strCheck.indexOf(whichCode) == -1 || whichCode == 8) return; vr = new String(pComponent.value); tam = vr.length; if (tam == 2) { pComponent.value = vr + '/'; } if (tam == 5) { pComponent.value = vr +'/';} } }

Page 254: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 253

MVC Gráfico Prioridade Class ISCUser.MVC.GraficoPrioridade Extends %ZEN.DataModel.ObjectDataModel { Property Baixa As %Numeric; Property Normal As %Numeric; Property Alta As %Numeric; Method %OnLoadModel(pSource As %RegisteredObject) As %Status { set rs = ##class(%ResultSet).%New() set sql = "SELECT Paciente->Prioridade->Descricao As Nome, Count(Paciente->Prioridade) As Total "_ "FROM ISCUser_Dados.Exames "_ "Group By Paciente->Prioridade" do rs.Prepare(sql) do rs.Execute() while rs.Next() { set Nome=rs.GetData(1) if Nome="" Set Nome="Nada" set Total=rs.GetData(2) xecute "set .."_Nome_" = "_Total } Quit $$$OK } }

Page 255: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 254

MVC Paciente Class ISCUser.MVC.Paciente Extends %ZEN.DataModel.ObjectDataModel { Property Nome As %String; Property Endereco As %String(ZENLABEL = "Endereço"); Property Cidade As %String; Property Estado As %String; Property Sexo As %String(DISPLAYLIST = ",M,F", VALUELIST = ",1,2"); Property Adulto As %Boolean; Property Renda As %Numeric; Property Prioridade As ISCUser.Dados.Paciente(ZENSQL = "Select ID,Descricao From ISCUser_Dados.PacientePrioridade", ZENSQLLOOKUP = "Select Descricao From ISCUser_Dados.PacientePrioridade Where ID = ?"); Method %OnNewSource(Output pSC As %Status = {$$$OK}) As %RegisteredObject { Set status = ##class(ISCUser.Dados.Paciente).%New() Quit status } Method %OnOpenSource(pID As %String, pConcurrency As %Integer = -1, Output pSC As %Status = {$$$OK}) As %RegisteredObject { Quit ##class(ISCUser.Dados.Paciente).%OpenId(pID,pConcurrency,.pStatus) } Method %OnLoadModel(pSource As ISCUser.Dados.Paciente) As %Status { Set ..Nome = pSource.Nome Set ..Endereco = pSource.Endereco Set ..Cidade = pSource.Cidade Set ..Estado = pSource.Estado Set ..Sexo = pSource.Sexo Set ..Adulto = pSource.Adulto Set ..Renda = pSource.Renda Set ..Prioridade = pSource.Prioridade Quit $$$OK }

Page 256: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 255

Method %OnSaveSource(pSource As ISCUser.Dados.Paciente) As %Status { Set tSC = pSource.%Save() Set ..%id = pSource.%Id() Quit tSC } Method %OnStoreModel(pSource As ISCUser.Dados.Paciente) As %Status { Set pSource.Nome = ..Nome Set pSource.Endereco = ..Endereco Set pSource.Cidade = ..Cidade Set pSource.Estado = ..Estado Set pSource.Sexo = ..Sexo Set pSource.Adulto = ..Adulto Set pSource.Renda = ..Renda Set pSource.Prioridade = ..Prioridade Quit $$$OK } ClassMethod %OnDeleteSource(pID As %String) As %Status { Set status = ##class(ISCUser.Dados.Paciente).%DeleteId(pID) Quit status } }

Page 257: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 256

Boas Vindas Class ISCUser.Pag.BoasVindas Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Boas Vindas"; Parameter DOMAIN = "iscuser"; XData Style { <style type="text/css"> /* style for title bar */ #title { background: #C5D6D6; color: black; font-family: Verdana; font-size: 1.5em; font-weight: bold; padding: 5px; border-bottom: 1px solid black; text-align: center; } </style> } XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title="Boas Vindas"> <html id="title">Boas Vindas</html> <vgroup width="100%"> <!-- put page contents here --> <button caption="Método Cliente" onclick="zenPage.btnClique();"/> <button caption="Método Servidor" onclick="zenPage.BtnCliqueServ();"/> <hgroup> <vgroup width="30%"> <calendar align="center"/> </vgroup><vgroup width="40%"> <image align="center" src="images\LabExam.jpg"/> </vgroup> <vgroup width="30%"> <colorPicker align="center"/> </vgroup> </hgroup> </vgroup> </page> }

Page 258: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 257

Method btnClique() [ Language = javascript ] { alert('ok'); } Method BtnCliqueServ() [ ZenMethod ] { Set msg = $ZVersion &js<alert('#(msg)#');> Quit } }

Page 259: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 258

Estilos Relatório Class ISCUser.Pag.EstiloRelatorio Extends %ZEN.Component.page { Parameter PRIVATE = 0; Parameter CONTENTTYPE = "text/css"; Method %DrawHTMLPage() { // Nova definição de tamanhos de fontes write "th.TabMinima {",! write " font-size:8px;",! write " font-family:Verdana;",! write " vertical-align:top;",! write " }",! write "td.TabMinima {",! write " font-size:8px;",! write " font-family:Verdana;",! write " vertical-align:top;",! write " }",! write "th.TabMenor {",! write " font-size:9px;",! write " font-family:Verdana;",! write " vertical-align:top;",! write " }",! write "td.TabMenor {",! write " font-size:9px;",! write " font-family:Verdana;",! write " vertical-align:top;",! write " }",! write "th.TabMedia {",! write " font-size:10px;",! write " font-family:Verdana;",! write " vertical-align:top;",! write " }",! write "td.TabMedia {",! write " font-size:10px;",! write " font-family:Verdana;",! write " vertical-align:top;",! write " }",! write "th.TabMaior {",! write " font-size:12px;",! write " font-family:Verdana;",! write " vertical-align:top;",! write " }",! write "td.TabMaior {",! write " font-size:12px;",! write " font-family:Verdana;",! write " vertical-align:top;",!

Page 260: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 259

write " }",! write "th.TabMaxima {",! write " font-size:14px;",! write " font-family:Verdana;",! write " vertical-align:top;",! write " }",! write "td.TabMaxima {",! write " font-size:14px;",! write " font-family:Verdana;",! write " vertical-align:top;",! write " }",! write ".NomeEmpresa {",! //Nome da empresa write " font-size:12px;",! write " font-family:Verdana;",! write " float:left;",! write " }",! write ".Data {",! //Data do relatório write " font-size:10px;",! write " font-family:Verdana;",! write " float: right;",! write " }",! write ".DataSub {",! //Data do relatório write " font-size:10px;",! write " font-family:Verdana;",! write " float: left;",! write " }",! write ".Titulo {",! //Título do relatório write " font-size:16px;",! write " font-family:Verdana;",! write " font-weight:bold;",! write " }",! write ".SubTitulo {",! //Títulos 2 relatório write " font-size:12px;",! write " font-family:Verdana;",! write " text-decoration:underline;",! write " vertical-align:top;",! write " }",! write ".SubSubTitulo {",! //Títulos 3 relatório write " font-size:10px;",! write " font-family:Verdana;",! write " font-style:italic;",! write " vertical-align:top;",! write " }",! } }

Page 261: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 260

Exames Class ISCUser.Pag.Exames Extends ISCUser.Pag.Pagina { Parameter PAGENAME = "Exames"; Parameter CLASSEMODELO = "ISCUser.Dados.Exames"; XData Links [ XMLNamespace = "http://www.intersystems.com/zen" ] { <pane xmlns="http://www.intersystems.com/zen"> <link href="javascript: zenPage.pesquisa();" caption="Pesquisa Exames"/> <link href="javascript: zenPage.chamaItem();" caption="Cadastro de Itens"/> <link href="ISCUser.Pag.PreExame.cls" caption="Relatório por Datas"/> </pane> } Method pesquisa() [ Language = javascript ] { var link = 'ISCUser.Pag.PesquisaExames.cls'; zenPage.launchPopupWindow(link,'Página de Pesquisa - Exames','status,scrollbars,resizable,top=100,left=100,width=400,height=500'); } Method onPopupAction(popupName, action, value) [ Language = javascript ] { var controller = zenPage.getComponentById('controller'); controller.setModelId(value); } Method chamaItem() [ Language = javascript ] { var controller = zenPage.getComponentById('controller'); var id = controller.getModelId(); if (id=='') { alert('Pesquise um exame!'); return; } var link = "ISCUser.Pag.ExamesItem.cls?exame=" + id; location.href = link; } Method PropriedadeInfo(pIndex As %Integer, ByRef pInfo As %String, pModelId As %String) As %Status { Set pInfo("Paciente","sql") = "Select ID,Nome From ISCUser_Dados.Paciente Order By Nome" Set pInfo("Paciente","sqllookup") = "Select Nome From ISCUser_Dados.Paciente Where ID = ?" Set pInfo("DataExame","%type") = "ISCUser.Componente.Data" Set pInfo("DataExame","format") = "DMY" Set pInfo("DataExame","separator") = "/" Quit $System.Status.OK() } }

Page 262: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 261

Exames Itens Class ISCUser.Pag.ExamesItem Extends ISCUser.Pag.Pagina { Parameter PAGENAME = "Itens dos Exames"; Parameter CLASSEMODELO = "ISCUser.Dados.ExamesItem"; Property ExameId As %String(ZENURL = "exame"); XData Links [ XMLNamespace = "http://www.intersystems.com/zen" ] { <pane xmlns="http://www.intersystems.com/zen" > <link href="javascript: zenPage.pesquisa();" caption="Pesquisa Itens"/> </pane> } Method pesquisa() [ Language = javascript ] { var link = 'ISCUser.Pag.PesquisaItens.cls?'+"exame="+zenPage.ExameId; zenPage.launchPopupWindow(link,'Página de Pesquisa - Itens de Exames','status,scrollbars,resizable,top=100,left=100,width=400,height=500'); } Method onPopupAction(popupName, action, value) [ Language = javascript ] { var controller = zenPage.getComponentById('controller'); controller.setModelId(value); } Method atualiza() [ Language = javascript ] { var controller = zenPage.getComponentById('controller'); controller.setDataByName('Exame',zenPage.ExameId); // informa a tela para atualizar o campo... zenPage.getComponentById('form.Exame').setValue(zenPage.ExameId); zenPage.getComponentById('form.Exame').setProperty('disabled',"true"); } Method onloadHandler() [ Language = javascript ] { zenPage.atualiza(); } }

Page 263: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 262

Gráfico Class ISCUser.Pag.Grafico Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Grafico Prioridade"; Parameter DOMAIN = "iscuser"; XData Style { <style type="text/css"> </style> } XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title=""> <dataController id="origem" modelClass="ISCUser.MVC.GraficoPrioridade" modelId="1"/> <dynaGrid align="center" width="400" id="dynaGrid" gridLabel="dynaGrid" controllerId="origem"/> <svgFrame id="svgFrame" height="300" width="300" backgroundStyle="fill: black;" layout="horizontal"> <lineChart id="grf" controllerId="origem" width="300" height="300" /> </svgFrame> </page> } }

Page 264: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 263

Links /// Created using the page template: Página Título Class ISCUser.Pag.Links Extends %ZEN.Component.page { /// Nome da classe da aplicação à qual esta página pertence. Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; /// Nome de exibição desta página. Parameter PAGENAME; /// Domínio usado para localização. Parameter DOMAIN = "iscuser"; /// Este bloco de estilos contém definições de estilo CSS válidas especificamente para a página. XData Style { } /// Este bloco XML define o conteúdo desta página. XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title=""> <html id="title">Links</html> <vgroup width="100%"> <link caption="Boas Vindas" href="ISCUser.Pag.BoasVindas.cls"/> <link caption="Exames" href="ISCUser.Pag.Exames.cls"/> <link caption="Pacientes" href="ISCUser.Pag.Paciente.cls"/> <link caption="Mensagem" href="javascript: alert('Ok');"/> </vgroup> </page> } }

Page 265: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 264

Login Class ISCUser.Pag.Login Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Login"; Parameter DOMAIN = "iscuser"; XData Style { <style type="text/css"> /* style for title bar */ #title { background: #C5D6D6; color: black; font-family: Verdana; font-size: 1.5em; font-weight: bold; padding: 5px; border-bottom: 1px solid black; text-align: center; } </style> } XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title="Login"> <html id="title">Login</html> <vgroup width="100%"> <spacer height="50"/> <form name="formlogin" align="center" labelPosition="left"> <text id="txtusuario" name="txtusuario" label="Usuário: " /> <password id="txtsenha" name="txtsenha" label="Senha: " /> <submit id="btnEnviar" caption="ok"/> </form> </vgroup> </page> }

Page 266: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 265

ClassMethod %OnSubmit(pSubmit As %ZEN.Submit) As %Status { #; this is overridden by subclasses Set loginok = 1 Set vuser = pSubmit.%GetValue("txtusuario") Set vpass = pSubmit.%GetValue("txtsenha") Set rs = ##class(%ResultSet).%New() Set sql = "Select Senha From ISCUser_Dados.Usuarios Where Login = ?" Do rs.Prepare(sql) Do rs.Execute(vuser) If 'rs.Next() { Do pSubmit.%SetError("formlogin","Login inválido!") } Else { If rs.GetData(1) '= vpass { Do pSubmit.%SetError("formlogin","Senha inválida!") } Else { Set UserId = 1 Do %session.Set("UsuarioId",UserId) Do %session.Set("NomeUsuario",vuser) Set pSubmit.%NextPage = ..Link("ISCUser.Pag.Menu.cls") } } Quit $System.Status.OK() } }

Page 267: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 266

Logout /// Created using the page template: Default Class ISCUser.Pag.Logout Extends %ZEN.Component.page { /// Nome da classe da aplicação à qual esta página pertence. Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; /// Nome de exibição desta página. Parameter PAGENAME = "Logout"; /// Domínio usado para localização. Parameter DOMAIN = "iscuser"; /// Este bloco de estilos contém definições de estilo CSS válidas especificamente para a página. XData Style { <style type="text/css"> </style> } /// Este bloco XML define o conteúdo desta página. XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title=""> <label label="Sua sessão foi encerrada!" labelStyle="color: red;font: bold"/> <link href="ISCUser.Pag.Login.cls" caption="Clique aqui para o login!."/> </page> } ClassMethod FimSessao() As %Status [ ZenMethod ] { Set %session.EndSession = 1 Quit $System.Status.OK() } Method onloadHandler() [ Language = javascript ] { zenPage.FimSessao(); } }

Page 268: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 267

Menu Class ISCUser.Pag.Menu Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Menu"; Parameter DOMAIN = "iscuser"; Property Usuario As %String [ InitialExpression = {%session.Get("NomeUsuario")} ]; Property Sessao As %String [ InitialExpression = {%session.SessionId} ]; Property SessionLanguage As %String [ InitialExpression = {%session.Language} ]; XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title="Menu de Opções"> <hgroup width="100%"> <vgroup id="image" width="60%"> <image src="images\intersystems.jpg" width="982" height="60"/> </vgroup> <vgroup id="user" width="20%"> <label align="left" label='Usuário: #(%page.Usuario)#'/> <label align="left" labelStyle="bold;" label="Sessão: #(%page.Sessao)#"/> <link id="lnkSair" align="left" caption="Sair" href="ISCUser.Pag.Logout.cls"/> </vgroup> <vgroup id="flags" width="20%"> <label id="lan" align="center" label="Language: #(%page.SessionLanguage)#"/> <spacer width="100" /> <hgroup width="100%"><image id="flag1" src="images\BandeiraBrasil.jpg" width="30" height="15" onclick="zenPage.Modifica('pt-br');"/> <image id="flag2" src="images\BandeiraUsa.jpg" width="30" height="15" onclick="zenPage.Modifica('en');"/> <image id="flag3" src="images\BandeiraEspanha.jpg" width="30" height="15" onclick="zenPage.Modifica('es');"/> </hgroup> </vgroup> </hgroup>

Page 269: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 268

<vgroup id="menus" width="100%"> <hgroup width="100%"> <hgroup id="locator" width="60%" height="100%" containerStyle="background: #A0B088;background-image: url(images/locatorgradient.png);background-repeat:repeat-x;padding-top: 6px;"> <locatorBar> <locatorLink caption="Home" href="ISCUser.Pag.Menu.cls" /> <locatorLink caption="Login" href="ISCUser.Pag.Login.cls" /> <locatorLink caption="Logout" href="ISCUser.Pag.Logout.cls" /> <locatorLink caption="Grafico" href="ISCUser.Pag.Grafico.cls" /> <locatorLink caption="InterSystems" href="http://www.intersystems.com" /> </locatorBar> <label id="labelMenu" label="Opções de Menu: " labelStyle="font-size: 0.80em;"/> <select name="sel" id="OpMenu" valueList="1,2,3" displayList="DynaTree,Menu,LookOut" onchange="zenPage.mudaMenu();"/> </hgroup> </hgroup> </vgroup> <hgroup id="Principal" width="100%"> <vgroup id="menu" width="20%" valign="top"> <hgroup id="'hGroupDyna" enclosingClass="celulaMenu" width="100%"> <dynaTree id="dytMenu" OnGetTreeInfo="GetTreeInfo"/> </hgroup> <hgroup width="65%" id="'hGroupItem"> <menu id="menu1" layout="vertical" width="60%"> <menu caption="Cadastro" layout="vertical"> <menuItem caption="Paciente" link="javascript: zenPage.mostra('ISCUser.Pag.Paciente.cls')"/> <menuSeparator/> <menu caption="InterSystems" layout="vertical"> <menuItem caption="Site" link="http://www.intersystems.com"/> <menuItem caption="Downloads" link="http://www.intersystems.com/cache/downloads/index.html"/> </menu> </menu> </menu> </hgroup>

Page 270: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 269

<hgroup width="100%" id="'hGroupLook"> <lookoutMenu id="lookout" height="220"> <tab caption="Cadastro" enclosingClass="celulaMenu"> <menuItem caption="Pacientes" link="javascript: zenPage.mostra('ISCUser.Pag.Paciente.cls')" /> <menuItem caption="Exames" link="javascript: zenPage.mostra('ISCUser.Pag.Exames.cls')" /> </tab> <tab caption="Relatorio"> <menuItem caption="Por Data" link="javascript: zenPage.mostra('ISCUser.Pag.PreExame.cls')" /> </tab> <tab caption="Downloads"> <menuItem caption="Caché" link="http://www.intersystems.com/cache/downloads/index.html" /> </tab> </lookoutMenu> </hgroup> </vgroup> <vgroup id="frame" width="80%" valign="top"> <iframe frameBorder="false" id="framePrincipal" name="framePrincipal" align="center" width="100%" height="450" src="ISCUser.Pag.BoasVindas.cls" /> </vgroup> </hgroup> </page> }

Page 271: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 270

Method mostra(pLink) [ Language = javascript ] { framePrincipal.location = pLink; } Method Modifica(pFlag) [ ZenMethod ] { set (%session.Language,%page.SessionLanguage)= pFlag &js<zenPage.reloadPage();> Quit 1 } Method reloadPage() [ Language = javascript ] { document.location.reload(); } ClassMethod GetTreeInfo(pRoot As %String, Output pTree, ByRef pParms) As %Status { //Set userID = %session.Get("UserId") #; top-most nodes are children of 0 Set pTree(0,"ch",1) = "" Set pTree(0,"ch",2) = "" Set pTree(0,"ch",3) = "" #; each node supplies: $LB(caption, value, hasChildren, link, expanded, icon) Set pTree(1)=$LB(("Cadastros"),("Cadastros"),1,"",1,,"Cadastros Gerais") Set pTree(2)=$LB(("Relatórios"),("Relatórios"),1,"",1,,"Relatórios Gerais") Set pTree(3)=$LB(("Pesquisas"),("Pesquisas"),1,"",1,,"Pesquisas") Set pTree(4) = $LB(("Pacientes"),("Pacientes"),0,"javascript: zenPage.mostra('ISCUser.Pag.Paciente.cls')",1) Set pTree(1,"ch",4) = "" Set pTree(5) = $LB(("Exames"),("Exames"),0,"javascript: zenPage.mostra('ISCUser.Pag.Exames.cls')",1) Set pTree(1,"ch",5) = "" Set pTree(6) = $LB(("Prioridade"),("Prioridade"),0,"javascript: zenPage.mostra('ISCUser.Pag.Prioridade.cls')",1) Set pTree(1,"ch",6) = "" Set pTree(7) = $LB(("Exames por Data"),("Exames por Data"),0,"javascript: zenPage.mostra('ISCUser.Pag.PreExame.cls')",1) Set pTree(2,"ch",7) = "" Set pTree(8) = $LB(("Exames"),("Exames"),0,"javascript: zenPage.mostra('ISCUser.Pag.PesquisaExames.cls')",1) Set pTree(9) = $LB(("Exames Itens"),("Exames Itens"),0,"javascript: zenPage.mostra('ISCUser.Pag.PesquisaItens.cls')",1) Set pTree(10) = $LB(("Paciente"),("Paciente"),0,"javascript: zenPage.mostra('ISCUser.Pag.PesquisaPaciente.cls')",1) Set pTree(3,"ch",8) = "" Set pTree(3,"ch",9) = "" Set pTree(3,"ch",10) = "" Quit $System.Status.OK() }

Page 272: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 271

Method mudaMenu() [ Language = javascript ] { var opmenu = zenPage.getComponentById('OpMenu').getValue(); var dyna = zenPage.getComponentById('hGroupDyna'); var menu = zenPage.getComponentById('hGroupItem'); var look = zenPage.getComponentById('hGroupLook'); if ( opmenu== 1) { menu.setProperty('hidden',true); look.setProperty('hidden',true); } if (opmenu == 2) { dyna.setProperty('hidden',true); look.setProperty('hidden',true); } if (opmenu == 3) { dyna.setProperty('hidden',true); menu.setProperty('hidden',true); } else { dyna.setProperty('hidden',false); menu.setProperty('hidden',false); look.setProperty('hidden',false); } } Method %OnAfterCreatePage() As %Status { Set timer = ##class(%ZEN.Component.timer).%New() Set timer.id = "timer" Set timer.timeout = 30*1000 Set timer.ontimeout = "zenPage.atualizaTimer();zenPage.getComponentById('timer').startTimer()" Do %page.%AddChild(timer) Quit $$$OK } ClassMethod atualizaTimer() As %Status [ ZenMethod ] { Set valorAtual = %session.Get("ControleTimeout") Set valorAtual = valorAtual + 30 If %session.AppTimeout-valorAtual<60 { &js<zenPage.logout();>

Page 273: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 272

} Do %session.Set("ControleTimeout",valorAtual) Quit $system.Status.OK() } }

Page 274: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 273

Pacientes Class ISCUser.Pag.Paciente Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Pacientes"; Parameter DOMAIN = "iscuser"; XData Style { <style type="text/css"> /* style for title bar */ #title { background: #C5D6D6; color: black; font-family: Verdana; font-size: 1.5em; font-weight: bold; padding: 5px; border-bottom: 1px solid black; text-align: center; } </style> } XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title="Cadastro Paciente"> <html id="title">Cadastro de Pacientes</html> <vgroup width="100%"> <dataController id="origem" modelClass="ISCUser.MVC.Paciente" modelId="1"/> <dynaForm align="center" id="dyfPaciente" controllerId="origem" /> <hgroup align="center"> <button id="btnAnterior" caption="Anterior" onclick="zenPage.anterior();"/> <button id="btnProximo" caption="Proximo" onclick="zenPage.proximo();"/> <button id="btnSavar" caption="Salvar" onclick="zenPage.salva();"/> <button id="btnExcluir" caption="Excluir" onclick="zenPage.deleta();"/> <button id="btnCriar" caption="Criar" onclick="zenPage.novo();"/> </hgroup> <svgFrame width="300" height="300"> <fuelGauge id="medRenda" animate="true" height="300" width="300" controllerId="origem" dataBinding="Renda" thresholdLower="1000" thresholdUpper="9000" rangeLower="0" rangeUpper="10000"/> </svgFrame> </vgroup> </page> }

Page 275: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 274

Method proximo() [ Language = javascript ] { var controller = zenPage.getComponentById('origem'); var id = controller.getModelId(); id = parseInt(id) + 1; controller.setModelId(id); } Method anterior() [ Language = javascript ] { var controller = zenPage.getComponentById('origem'); var id = controller.getModelId(); id = parseInt(id) - 1; id = (id <= 1)? 1 :id; controller.setModelId(id); } Method novo() [ Language = javascript ] { var controller = zenPage.getComponentById('origem'); controller.createNewObject(); } Method salva() [ Language = javascript ] { var form = zenPage.getComponentById('dyfPaciente'); form.save(); } Method deleta() [ Language = javascript ] { var controller = zenPage.getComponentById('origem'); controller.deleteId(controller.getModelId()); } }

Page 276: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 275

Pacientes Controles Class ISCUser.Pag.PacienteControles Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Paciente Controles"; Parameter DOMAIN = "iscuser"; XData Style { <style type="text/css"> /* style for title bar */ #title { background: #C5D6D6; color: black; font-family: Verdana; font-size: 1.5em; font-weight: bold; padding: 5px; border-bottom: 1px solid black; text-align: center; } </style> } XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title="Paciente Controles"> <html id="title">Exercício - Controles Zen</html> <vgroup width="100%"> <!-- put page contents here --> <form align="center" invalidMessage="Falha na validação da página!"> <hgroup align="center"> <label label ="Cadastro de Pacientes" labelStyle="font-family: Verdana; font-size: 1.2em;" height="40" valign="middle"/> </hgroup> <hgroup align="center" > <label label ="Nome do Paciente" align="right" width="50%"/> <text id="txtPaciente" width="50%" required="true" requiredMessage="Informe o nome do Paciente" /> </hgroup> <hgroup align="center"> <label label ="Prioridade" align="right" width="50%"/> <radioSet id="rdsPrioridade" width="50%" sql="Select ID,Descricao From ISCUser_Dados.PacientePriori

Page 277: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 276

dade"/> </hgroup> <hgroup align="center"> <label label ="Adulto" align="right" width="50%"/> <checkbox id="chkAdulto" width="50%" /> </hgroup> <hgroup align="center"> <label label ="Sexo" align="right" width="50%"/> <select id="selSexo" width="50%" valueList="1,2" displayList="Masculino,Feminino"/> </hgroup> <hgroup align="center"> <label label ="Indicação" align="right" width="50%"/> <dataCombo id="dtcIndicacao" width="50%" sql="Select ID,Nome From ISCUser_Dados.Paciente Where Nome %Startswith ? Order By Nome" sqlLookup="Select Nome From ISCUser_Dados.Paciente Where ID = ?" editable="true" searchKeyLen="4" /> </hgroup> <hgroup align="center"> <label label ="Data Nascimento" align="right" width="50%"/> <calendar id="calNascimento" width="50%" dayList="D,S,T,Q,Q,S,S" monthList="Jan,Fev,Mar,Abr,Mai,Jun,Jul,Ago,Set,Out,Nov,Dez"/> </hgroup> <hgroup align="center"> <submit id="btnSalvar" caption="Salvar"/> <button id="btnLimpar" caption="Limpar"/> <button id="btnDeletar" caption="Deletar"/> </hgroup> </form> </vgroup> </page> } Method %OnAfterCreatePage() As %Status { Do ..%SetValueById("calNascimento",$ZDate($Horolog,3)) Do ..%SetValueById("chkAdulto",1) Quit $$$OK } }

Page 278: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 277

Página Class ISCUser.Pag.Pagina Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Super Página"; Parameter DOMAIN = "iscuser"; Parameter CLASSEMODELO As %String; Property ClasseModelo As %String [ InitialExpression = {..#CLASSEMODELO} ]; Property ModelId As %String(ZENURL = "ModelId"); Property SessionTimeout As %Integer [ InitialExpression = {..SessionControlerTimeout()} ]; XData Style { <style type="text/css"> </style> } /// Este bloco XML define o conteúdo desta página. XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title="Pagina"> <html id="title"></html> <vgroup width="100%"> <fieldSet width="95%" align="left"> <dataController id="controller" modelClass="#(%page.ClasseModelo)#" modelId="#(%page.ModelId)#"/> <dynaForm align="center" id="form" controllerId="controller" OnGetPropertyInfo="PropriedadeInfo" /> <hgroup align="center"> <button id="btnAnterior" caption="Anterior" onclick="zenPage.anterior();"/> <button id="btnProximo" caption="Proximo" onclick="zenPage.proximo();"/> <button id="btnSavar" caption="Salvar" onclick="zenPage.salva();"/> <button id="btnExcluir" caption="Excluir" onclick="zenPage.deleta();"/> <button id="btnCriar" caption="Criar" onclick="zenPage.novo();"/> </hgroup> </fieldSet> <vgroup width="30%"> <fieldSet width="95%" align="left"> <pane paneName="Links" width="100%"/> </fieldSet> </vgroup> </vgroup> </page> }

Page 279: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 278

Method proximo() [ Language = javascript ] { var controller = zenPage.getComponentById('controller'); var id = controller.getModelId(); id = parseInt(id) + 1; controller.setModelId(id); } Method anterior() [ Language = javascript ] { var controller = zenPage.getComponentById('controller'); var id = controller.getModelId(); id = parseInt(id) - 1; id = (id <= 1)? 1 :id; controller.setModelId(id); } Method novo() [ Language = javascript ] { var controller = zenPage.getComponentById('controller'); controller.createNewObject(); } Method salva() [ Language = javascript ] { var form = zenPage.getComponentById('form'); form.save(); } Method deleta() [ Language = javascript ] { var controller = zenPage.getComponentById('controller'); controller.deleteId(controller.getModelId()); } Method PropriedadeInfo(pIndex As %Integer, ByRef pInfo As %String, pModelId As %String) As %Status { Quit $System.Status.OK() } ClassMethod SessionControlerTimeout() As %Status [ Final, Private ] { // inicializa a propriedade ‘ControleTimeout‘ Do %session.Set("ControleTimeout",0) Quit $$$OK } }

Page 280: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 279

Pesquisa Exames Class ISCUser.Pag.PesquisaExames Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Pesquisa de Exames"; Parameter DOMAIN = "iscuser"; XData Style { <style type="text/css"> /* style for title bar */ #title { background: #C5D6D6; color: black; font-family: Verdana; font-size: 1.5em; font-weight: bold; padding: 5px; border-bottom: 1px solid black; text-align: center; } </style> } XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title="Pesquisa Exames"> <html id="title">Pesquisa Exames</html> <vgroup width="100%"> <tablePane id="tblExames" valueColumn="ID" onselectrow="zenPage.fire();" pageSize="10" useSnapshot="true" tableName="ISCUser_Dados.Exames"> <column colName="ID" hidden="true" /> <column colName="Paciente" colExpression="Paciente->Nome" filterType="text" filterOp="[" /> <column colName="Codigo" header="Código" /> <column colName="DataExame" header="Data do Exame" filterType="date" filterOp="=" /> <column colName="ValorExame" header="Valor do Exame" /> </tablePane> <tableNavigatorBar tablePaneId="tblExames"/> </vgroup> </page> } Method fire() [ Language = javascript ] { var idTabela = zenPage.getComponentById('tblExames').getValue(); zenPage.firePopupAction('Action', idTabela); } }

Page 281: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 280

Pesquisa Itens Class ISCUser.Pag.PesquisaItens Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Pesquisa de Itens de Exames"; Parameter DOMAIN = "iscuser"; Property ExameId As %String(ZENURL = "exame"); XData Style { <style type="text/css"> </style> } XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title="Itens dos Exames"> <tablePane id="tblItem" valueColumn="ID" onselectrow="zenPage.fire();" tableName="ISCUser_Dados.ExamesItem" useSnapshot="true" pageSize="16" whereClause="Exame = ?" > <parameter value="#(%page.ExameId)#"/> <column colName="ID"/> <column colName="Tipo->Descricao" header="Descrição"/> <column colName="Quantidade"/> </tablePane> <tableNavigatorBar tablePaneId="tblItem"/> </page> } Method fire() [ Language = javascript ] { var idTabela = zenPage.getComponentById('tblItem').getValue(); zenPage.firePopupAction('Action', idTabela); } }

Page 282: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 281

Pesquisa Pacientes Class ISCUser.Pag.PesquisaPaciente Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Pesquisa Paciente"; Parameter DOMAIN = "iscuser"; XData Style { <style type="text/css"> /* style for title bar */ #title { background: #C5D6D6; color: black; font-family: Verdana; font-size: 1.5em; font-weight: bold; padding: 5px; border-bottom: 1px solid black; text-align: center; } </style> } XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title="Pesquisa Paciente"> <html id="title">Pesquisa Pacientes</html> <vgroup width="100%"> <tablePane showRowNumbers="true" showZebra="true" id="tblPaciente" tableName="ISCUser_Dados.Paciente" whereClause="Adulto = 1" useSnapshot="true" pageSize="10"> <column colName="ID" hidden="true"/> <column colName="Nome" filterType="text" filterOp="%STARTSWITH" /> <column colName="Cidade" /> <column colName="Sexo" style="color: red;" /> <column colName="Adulto" /> <column colName="Prioridade" colExpression="Prioridade->Descricao" filterType="query" filterQuery="Select ID,Descricao From ISCUser_Dados.PacientePrioridade" /> <condition colName="Sexo" predicate="EQ" value="M" rowStyle="font: bold;"/> <column link="javascript: zenPage.mostraMsg('#(%query.Nome)#');" linkCaption="Mostrar Nome" linkConfirm="Deseja Realmente?"/> </tablePane> <tableNavigatorBar tablePaneId="tblPaciente"/> </vgroup> </page> }

Page 283: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 282

Method mostraMsg(pVal) [ Language = javascript ] { alert(pVal); } }

Page 284: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 283

Pré Exames Class ISCUser.Pag.PreExame Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Pre Exame"; Parameter DOMAIN = "iscuser"; XData Style { <style type="text/css"> </style> } XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title="Pre Exame"> <vgroup align="center"> <dateText id="txtDataInicial" label="Data Inicial" format="DMY" separator="/" /> <dateText id="txtDataFinal" label="Data Final" format="DMY" separator="/" /> <button id="btnEnviar" caption="Ok" onclick="zenPage.relatorio();" /> </vgroup> </page> } Method relatorio() [ Language = javascript ] { var inicio = zenPage.getComponentById('txtDataInicial').getValue(); var fim = zenPage.getComponentById('txtDataFinal').getValue(); if (inicio !='' && fim != '') { var link = 'ISCUser.Rel.Exames.cls?datainicial='+inicio+ '&datafinal='+fim; window.open(link,'','Relatório de Exames por Data','status,scrollbars,resizable,top=10,left=10,width=800,height=800'); } else {alert('Digite as datas!')} } }

Page 285: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 284

Prioridade Class ISCUser.Pag.Prioridade Extends %ZEN.Component.page { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter PAGENAME = "Prioridades Paciente"; Parameter DOMAIN = "iscuser"; XData Style { <style type="text/css"> /* style for title bar */ #title { background: #C5D6D6; color: black; font-family: Verdana; font-size: 1.5em; font-weight: bold; padding: 5px; border-bottom: 1px solid black; text-align: center; } </style> } XData Contents [ XMLNamespace = "http://www.intersystems.com/zen" ] { <page xmlns="http://www.intersystems.com/zen" title="Prioridades Paciente"> <html id="title">Prioridade do Paciente</html> <vgroup width="100%"> <dataController id="origem" modelClass="ISCUser.Dados.PacientePrioridade" modelId="1"/> <form id="frmPrioridade" controllerId="origem" align="center"> <text id="txtCodigo" label="Código" dataBinding="Codigo" /> <text id="txtDescricao" label="Descrição" dataBinding="Descricao" /> <hgroup> <button id="btnAnterior" caption="Anterior" onclick="zenPage.anterior();"/> <button id="btnProximo" caption="Proximo" onclick="zenPage.proximo();"/> </hgroup> </form> </vgroup> </page> }

Page 286: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 285

Method proximo() [ Language = javascript ] { var controller = zenPage.getComponentById('origem'); var id = controller.getModelId(); id = parseInt(id) + 1; //id = (id <= 1)? 1 :id; controller.setModelId(id); } Method anterior() [ Language = javascript ] { var controller = zenPage.getComponentById('origem'); var id = controller.getModelId(); id = parseInt(id) - 1; id = (id <= 1)? 1 :id; controller.setModelId(id); } }

Page 287: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 286

Relatório Exames Class ISCUser.Rel.Exames Extends %ZEN.Report.reportPage { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter DEFAULTMODE = "html"; Parameter REPORTXMLNAMESPACE; Parameter HOSPITAL = "Hospital"; Parameter TITULO = "Título do Relatório"; Property DataInicial As %String(ZENURL = "datainicial"); Property DataFinal As %String(ZENURL = "datafinal"); Property Formato As %Integer(ZENURL = "format") [ InitialExpression = 4 ]; Property Hospital As %String [ InitialExpression = {..#HOSPITAL} ]; Property Titulo As %String [ InitialExpression = {..#TITULO} ]; Method EditaData(pVal) { // converte para valor interno... Set pVal = $ZdateH(pVal,..Formato) Quit pVal }

Page 288: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 287

XData ReportDefinition [ XMLNamespace = "http://www.intersystems.com/zen/report/definition" ] { <report xmlns="http://www.intersystems.com/zen/report/definition" name="Exames" sql="Select ID,Codigo,DataExame,ValorExame,Paciente->Nome As Paciente From ISCUser_Dados.Exames Where %internal(DataExame) BETWEEN ? and ?"> <parameter expression="..EditaData(..DataInicial)"/> <parameter expression="..EditaData(..DataFinal)"/> <attribute name="Hospital" expression="..Hospital"/> <attribute name="Data" expression="$ZDateTime($horolog,4)"/> <attribute name="Titulo" expression="..Titulo"/> <attribute name="Inicio" expression="..DataInicial"/> <attribute name="Fim" expression="..DataFinal"/> <group name="Exames" breakOnField="ID"> <element name="Codigo" field="Codigo"/> <element name="Data" field="DataExame"/> <element name="Valor" field="ValorExame"/> <element name="Paciente" field="Paciente"/> </group> </report> }

Page 289: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 288

XData ReportDisplay [ XMLNamespace = "http://www.intersystems.com/zen/report/display" ] { <report xmlns="http://www.intersystems.com/zen/report/display" name="Exames" title="Exames de Pacientes"> <document width="210mm" height="297mm" headerHeight="25mm" marginLeft="15mm" marginRight="7mm" marginTop="7mm" marginBottom="7mm"> <cssinclude href="ISCUser.Pag.EstiloRelatorio.cls"/> </document> <pageheader> <item field="@Hospital" class="Empresa"/> <line pattern="empty"/> <item field="@Data" class="Data"/> <line pattern="empty"/> <item field="@Titulo" class="Titulo"/> <line pattern="empty"/> <item displayCaption="true" class="DataSub" caption="Data inicial: " field="@Inicio"/> <line pattern="empty"/> <item displayCaption="true" class="DataSub" caption="Data final: " field="@Fim"/> <line pattern="empty"/> <line pattern="dashed"/> </pageheader> <body> <table orient="col" group="Exames" altcolor="##ffbbaa" class="TabMaior"> <item field="Codigo" caption="Código" width="25%"/> <item field="Data" caption="Data" width="25%"/> <item field="Valor" caption="Valor" width="25%"/> <item field="Paciente" caption="Paciente" width="25%"/> </table> </body> </report> } }

Page 290: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 289

Relatório Paciente Class ISCUser.Rel.Paciente Extends %ZEN.Report.reportPage { Parameter APPLICATION = "ISCUser.Aplic.Aplicacao"; Parameter DEFAULTMODE = "html"; Parameter REPORTXMLNAMESPACE; XData ReportDefinition [ XMLNamespace = "http://www.intersystems.com/zen/report/definition" ] { <report xmlns="http://www.intersystems.com/zen/report/definition" name="Paciente" sql="SELECT ID,Nome,Cidade,Estado,Sexo,Adulto,Prioridade-> Descricao as Prioridade FROM ISCUser_Dados.Paciente ORDER BY Prioridade,Nome"> <group name="Prioridade" breakOnField="Prioridade"> <attribute name="nome" field="Prioridade"/> <aggregate name="qt" type="COUNT" field="ID"/> <group name="Paciente" breakOnField="ID"> <element name="Cidade" field="Cidade"/> <element name="Estado" field="Estado"/> <element name="Sexo" field="Sexo"/> <element name="Adulto" field="Adulto"/> <element name="Nome" field="Nome"/> </group> </group> </report> }

Page 291: ISB007 - ZEN.pdf

Caché ZEN

InterSystems do Brasil 290

XData ReportDisplay [ XMLNamespace = "http://www.intersystems.com/zen/report/display" ] { <report xmlns="http://www.intersystems.com/zen/report/display" name="Paciente"> <pageheader> <document> </document> </pageheader> <body> <p class="Banner1">Relatório de Pacientes por Prioridade</p> <barChart dataFields="!qt" dataGroup="Prioridade" width="4in" height="3in" title="Pacientes por Prioridade" /> <group name="Prioridade" line="1px"> <table orient="row" width="4in"> <item field="@nome" width="2in"><caption value="Prioridade:" width="2in"/></item> <item field="qt"><caption value="Qtd. Pacientes:"/></item> </table> <line pattern="empty"/> <table orient="col" group="Paciente" altcolor="#FFDFDF" width="3.8in"> <item field="Nome" ><caption value="Nome:"/></item> <item field="Cidade" ><caption value="Cidade:"/></item> <item field="Estado" ><caption value="Estado:"/></item> <item field="Sexo" ><caption value="Sexo:"/></item> <item field="Adulto" ><caption value="Adulto:"/></item> </table> </group> </body> </report> } }