Manual de Técnicas Interface para WEB -...

119
Manual de Técnicas Interface para WEB Setembro/1999 Versão 1.19 Não homologado

Transcript of Manual de Técnicas Interface para WEB -...

Manual de Técnicas

Interface para WEB

Setembro/1999 Versão 1.19

Não homologado

Copyright © 1998 DATASUL S.A. Todos os direitos reservados.

Nenhuma parte deste documento pode ser copiada, reproduzida, traduzida ou

transmitida por qualquer meio eletrônico ou mecânico, na sua totalidade ou em

parte, sem a prévia autorização escrita da DATASUL S.A., que reserva-se o

direito de efetuar alterações sem aviso prévio. A DATASUL S.A não assume

nenhuma responsabilidade pelas conseqüências de quaisquer erros ou

inexatidões que possam aparecer neste documento.

DATASUL S.A.

Av. Santos Dumont, 831, Joinville, SC, CEP 89.222-900

i

Índice

CAPÍTULO 1 Introdução ............................................................................... 1

CAPÍTULO 2 Templates para WEB .............................................................. 3

Como utilizar o SWG .................................................................................... 3

Estilo Cadastro e Consulta Simples ............................................................... 6

Como construir o Cadastro Simples .............................................................. 7

Especificação Técnica – Cadastro Simples.................................................... 8

Includes utilizadas no Cadastro e Consulta Simples / Complexo ................ 14

Estilo Cadastro Complexo ........................................................................... 15

Como construir o Cadastro Complexo ......................................................... 16

Especificação Técnica – Cadastro Complexo .............................................. 17

Estilo Pai x Filho ......................................................................................... 20

Especificação Técnica – Consulta PAI ........................................................ 21

Includes utilizadas no Consulta PAI ............................................................ 26

Especificação Técnica – Consulta Filho ...................................................... 26

Includes utilizadas no Consulta Filho .......................................................... 31

Especificação Técnica – Cadastro PAI SIMPLES/COMPLEXO................ 32

Especificação Técnica – Cadastro Filho SIMPLES/COMPLEXO.............. 38

Estilo Consulta Simples / Estilo Consulta Complexa .................................. 38

Estilo Vá Para .............................................................................................. 40

Especificação Técnica – Vá Para ................................................................. 41

Estilo Pesquisa / ZOOM .............................................................................. 45

Estilo Relatório ............................................................................................ 52

CAPÍTULO 3 Como usar uma BO .............................................................. 55

CAPÍTULO 4 Contexto de Sessão ............................................................. 57

Funcionamento ............................................................................................ 57

ii

CAPÍTULO 5 Contexto de Transação ........................................................ 61

Funcionamento ............................................................................................. 62

Recuperando o número da última seqüência ............................................... 64

CAPÍTULO 6 Perfil do Usuário ................................................................... 65

Funcionamento ............................................................................................. 65

CAPÍTULO 7 Consultas Relacionadas ...................................................... 67

CAPÍTULO 8 Uso de páginas de código ................................................... 69

Funcionamento ............................................................................................. 69

CAPÍTULO 9 Customização de arquivos WebSpeed ............................... 71

Funcionamento ............................................................................................. 71

CAPÍTULO 10 Utilitários ............................................................................ 73

WU-GRAF ................................................................................................... 73

CAPÍTULO 11 Tratamento de Erros ......................................................... 78

CAPÍTULO 12 Validações de Campos na WEB ...................................... 79

CAPÍTULO 13 API de BROWSE – wu-browse.p ...................................... 83

CAPÍTULO 14 Preferências do Usuário – wu-uspf.p .............................. 91

CAPÍTULO X... Considerações Gerais ...................................................... 95

Includes do EMS 2 GUI ............................................................................... 95

Label dos Campos no HTML´s.................................................................... 95

Controles para a não utilização de cache ..................................................... 96

Inclusão recursiva ........................................................................................ 96

Fechamento de janelas de inclusão de pai ................................................... 96

Validações em Geral .................................................................................... 96

Validação de Inicial e Final ......................................................................... 97

Validações em Relatórios ............................................................................ 97

Desenvolvimento Específico/Customizações .............................................. 97

Como fazer links para detalhe do registro ................................................... 98

Como habilitar/desabilitar campos nos HTML´s ......................................... 99

Utilizar a área do label do radio-set e check-box para click do mouse ........ 99

Botão de zoom para tabela estrangeira ...................................................... 100

Como selecionar um Texto via JavaScript ................................................. 100

CAPÍTULO 1 Introdução iii

Como definir nomes das FRAMES(Janelas): ............................................ 102

Blocos de Assign e funções do Webspeed ................................................. 104

Programa de filho chamando um outro programa de Pai x Filho .............. 105

Selecionar , Inverter e Desmarcar CHECKBOX via JavaScript ............... 109

Como trazer em relatórios o servidor default do usuário ........................... 110

Como acrescentar um botão “Implantar” no Zoom ................................... 112

Utilização de Help na WEB........................................................................113

1

CAPÍTULO 1

Introdução

Este manual tem por objetivo relacionar as técnicas para construção de

programas de interface para WEB (verifique também o manual de técnicas de

BO´s).

As principais características são:

Nomenclatura

o nome do programa deve ser “w” + nome do programa GUI

correspondente. Exemplo: wpd0501.w

o nome do HTML é o nome do programa “.w” correspondente + a

terminação “html”. Exemplo: wpd0501.html.

os programas criados para WEB devem estar em letras minúsculas.

Estrutura de Diretórios

A estrutura para diretórios deve ser desta forma:

1º Nível 2º Nível 3º Nível Finalidade

<Diretório Produto> web/ app/ Contém os programas dos módulos (.w, .html, .i).

ccp/

pdp/

ctp/

...

adzoom/ Programas de zoom separados por aplicativos.

unzoom/

Definição

Características

2

inzoom/

dizoom/

adgo/ Programas de VáPara (goto) separados por

aplicativo.

ungo/

ingo/

digo/

wimages/ Imagens utilizadas nos programas de interface da

web.

winclude/ Includes específicos para includes dos templates

web.

wutp/ Utilitários específicos para web.

Imagens

As imagens devem estar nos padrões .GIF OU .JPG.

Devem ser criadas sempre no diretório: WEB/wimages

A referência a imagens nos programas e htmls deve ser:

/ems20web/wimages/<nome-image>

/ems20web/ é um alias que deve ser configurado no webserver para que as

imagens possam ser localizadas. Este alias deve ser inicializado com <dir-

base>/web/ (dir-base é o diretório onde foi instalado as transações web).

Testes com Nestcape e Internet Explorer

Os programas para WEB são desenvolvidos utilizando como browsers padrão

o Nestcape e Internet Explorer.

Portanto, os programas devem ser testados nestes dois browsers, para garantir

o correto funcionamento dos programas nestes browsers padrão.

Se algum programa apresentar problema em um dos dois browsers, deve-se

procurar simplificar a interface de forma a solucionar o problema. Deve-se

procurar usar os recursos mais simples.

Observação:

3

CAPÍTULO 2

Templates para WEB

Os templates para WEB são gerados automaticamente usando a ferramenta

SWG. Após a geração inicial o programador passará então, a fazer as

implementações nos programas gerados.

Como utilizar o SWG

Basicamente, para utilizar o SWG, devem ser seguidos os seguintes passos:

Descrição

Descrição

4

definir o estilo de programa que vai ser construído: cadastro simples,

cadastro complexo, pai x filho, etc.;

selecionar os campos que aparecerão no HTML;

especificar as características dos campos selecionados;

especificar os parâmetros do programa (nome externo, etc.);

gerar o programa;

fazer os ajustes necessários no programa (de acordo com o estilo).

Definição do Estilo do Programa

O programador deve definir junto ao analista qual o estilo do programa a ser

construído. De acordo com o estilo, será necessário fazer mais ou menos

coisas no SWG. Neste manual, estão os passos necessários para cada estilo.

Seleção dos campos para o HTML

Através da função de seleção devem ser definidos os campos que aparecerão

no HTML. Estes campos podem ser definidos diretamente no SWG ou através

da importação de um programa escrito com SmartObjects.

O SWG reconhece automaticamente os bancos conectados e então o

programador pode selecionar um banco para escolha das tabelas e campos.

Especificar as características dos campos selecionados

Para cada campo pode ser especificado alguma característica, tipo formato

(view-as) e alinhamento.

CAPÍTULO 2 Templates para WEB 5

Especificação dos parâmetros do programa

Na parte de parâmetros o programador deve especificar qual o nome do

programa a ser gerado, qual o programa de pesquisa e ‘vá para’, etc.

Dependendo do estilo deverão ser informados, mais ou menos, os parâmetros.

Geração do Programa

Após selecionar os campos e informar os parâmetros, o SWG poderá gerar o

programa. Será mostrado o nome e diretório onde o programa foi gerado.

Ajustes no programa

Depois de gerado pelo SWG, o programador deve fazer novos ajustes

diretamente no programa, haja visto que, o SWG não faz engenharia reversa,

ou seja, se for gerado novamente serão perdidas as alterações.

6

Estilo Cadastro e Consulta Simples

A principal característica de um Cadastro Simples é que todos os campos são

visíveis na área de trabalho.

Definição

CAPÍTULO 2 Templates para WEB 7

Como construir o Cadastro Simples

Selecionar os campos

selecione os campos e insira as variáveis que serão utilizados no Cadastro

Simples;

faça os ajustes necessários nos atributos dos campos;

ajuste a ordem dos campos.

Informar Parâmetros

escolher o Estilo Cadastro Simples;

selecionar os Botões que serão utilizados;

preencher o nome do programa. (Para programas web: wprograma);

preencher o nome do programa de Vá para. Informando o Método, Altura

e Largura;

preencher o nome do programa Pesquisa. Informando o Campo, Altura e

Largura.

Gerar o programa

através da opção de geração de programas do SWG gerar o fonte do

programa.

Alterações necessárias após a geração

se o programa que acabou de ser gerado não faz nenhuma referência a

outras tabelas, então está pronto o Cadastro Simples;

se o programa utiliza campos de outras tabelas (chaves estrangeiras), então

veja a técnica de ‘Como construir ZOOM’;

se houver alguma regra de navegação (classificação diferente, por

exemplo), então deverá ser customizada a query do BO que o programa

utiliza;

8

Especificação Técnica – Cadastro Simples

Arquivo HTML

<html>

<head>

<link rel="StyleSheet" type="text/css" href="/ems20web/padrao.css">

Arquivo de Estilos para o produto . É neste arquivo que se encontra as

configurações de cor , bordas , links e etc

<meta http-equiv="Cache-Control" content="No-Cache">

<meta http-equiv="Pragma" content="No-Cache">

<meta http-equiv="Expires" content="0">

Estas três Meta Tags são para eliminar o cache , isto é , o navegador não irá

utilizar cache .

</head>

<script language="JavaScript">

function inicializa() {

parent.document.title = 'Template de Cadastro Simples';

parent.panel("NGSACMDUROLHE","WCADSIMP 2.00.00.000");

}

</script>

Função Inicializa atribui ao documento um Título e os Botões do Painel

O significado de cada letra é:

N Botões de Navegação

G Go to / Vá Para

S Search / Pesquisa

A Add / Adicionar

C Copy / Copiar

M Modify / Modificar

D Delete / Deletar

CAPÍTULO 2 Templates para WEB 9

U Undo / Desfazer

R Reset / Limpar

O OK (Submit/Submeter)

H Home

E Exit

<body topmargin="0" leftmargin="0" onload="inicializa()">

<form method="post">

<input type="hidden" name="hid_chave">

<input type="hidden" name="hid_oper">

Estas duas variáveis são de controle dos templates . Onde são

armazenados o ROWID do registro corrente e a operação . Nos cadastros

e consultas o uso destes dois elementos é obrigatório . Atenção : Devem

ser declarados com os dois primeiros elementos do formulário .

<div align="center"> <p><br></p>

<center>

<table align="center" border="0" cellpadding="0" cellspacing="3" width="90%"

class="tableForm">

<tr>

<td class="barratitulo">

<!--BXLS-->Template de Cadastro Simples<!--EXLS-->

</td>

</tr>

<!—BXLS Palavra <!—EXLS É utilizado para que o Datasul Translation

Kit possa traduzir os programas para outras línguas .

<tr>

<td class="linhaForm" nowrap align="center"><br><center>

<fieldset>

<table align="center" border="0" cellpadding="0" cellspacing="1"

width="100%">

<tr>

10

<th align="right" class="linhaForm" nowrap width="40%">

<!--BXLS-->Código <!--EXLS-->:

</th>

<td class="linhaForm" align="left" nowrap width="60%">

<input type="text" size="5" maxlength="5" name="w_cod">

</td>

Nas Tags para colunas na tabela , deve-se especificar na <th> um width

=”40%” e a <td> um width=”60%” . Este é o valor default , se houver

necessidade é perfeitamente configurável . Mas lembre-se a tag <th> deve sempre

Ter um valor menos que a tag <td>

</tr>

</table>

</fieldset>

No código acima deve-se declarar os campos chaves do programa. Assim

todos os campos chaves ficarão no primeiro <FieldSet> .

<fieldset>

<table align="center" border="0" cellpadding="0" cellspacing="1"

width="100%">

<tr>

<th align="right" class="linhaForm" nowrap width="40%">

<!--BXLS-->Nome <!--EXLS-->:

</th>

<td class="linhaForm" align="left" nowrap width="60%">

<input type="text" size="40" maxlength="40" name="w_nome">

</td>

</tr>

</table>

</fieldset>

<p><br></center></td> </tr></table></center></div>

</form>

</body>

</html>

Todos os nomes de elementos de formulários devem começar com w_

nomedocampo.

CAPÍTULO 2 Templates para WEB 11

Arquivo .W

Definitions

&GLOBAL-DEFINE ttTable1 tt-tabela

Definir o nome da Tabela temporária .

Exemplo :

&GLOBAL-DEFINE ttTable1 tt-customer

&GLOBAL-DEFINE hDBOTable1 boxx000

Definir o nome da DBO que será utilizada.

Exemplo:

&GLOBAL-DEFINE hDBOTable1 bosp001

&GLOBAL-DEFINE DBOTable1 tabela

Definir o nome da Tabela que a DBO utiliza .

Exemplo:

&GLOBAL-DEFINE DBOTable1 customer

&GLOBAL-DEFINE TableName tabela

Definir o nome da Tabela que será utilizada .

Exemplo :

&GLOBAL-DEFINE TableName customer

&GLOBAL-DEFINE PROGZO diretório/programa

Definir o nome do programa de Search que será chamado .

Exemplo :

&GLOBAL-DEFINE PROGZO adzoom/wz01ad001.p

&GLOBAL-DEFINE TAMZOOM "000" "000"

Definir a largura e altura (respectivamente) que a janela de Search terá .

Exemplo :

&GLOBAL-DEFINE TAMZOOM "500" "350"

12

&GLOBAL-DEFINE PROGGO diretório/programa

Definir o nome do programa de Go to / Vá para .

Exemplo :

&GLOBAL-DEFINE PROGGO templates/wgoto.w

&GLOBAL-DEFINE TAMGO "000" "000"

Definir a largura e altura (respectivamente) que a janela de Go to terá .

Exemplo :

&GLOBAL-DEFINE TAMGO "300" "250"

&GLOBAL-DEFINE THISNAME diretório/programa.w

Definir o nome deste programa .

Exemplo :

&GLOBAL-DEFINE THISNAME templates/wcadsimp.w

Procedure Process-web-request

RUN diretório/programa PERSISTENT SET {&hDBOTable1}.

Definir o diretório e nome da DBO que será utilizada .

Exemplo :

RUN dbo/bosp001.p PERSISTENT SET {&hDBOTable1}.

RUN openQueryStatic in {&hDBOTable1} (input "Main":u).

Definir as restrições (utilizando o Método de restrição) O Método de

restrição deve ser utilizado antes da abertura da Query.

Definir qual a Query será aberta .

Exemplo :

RUN openQueryStatic in {&hDBOTable1} (input "Main":u).

Procedure assignFields

Definir quais os campos que serão validados com wi-datatype.i .

Verificar no Capítulo de Validações o funcionamento da wi-datatype.i

Fazer a associação entre as variáveis de tela (HTML) com a tabela

temporária .

if request_method = "POST" then DO WITH FRAME {&FRAME-NAME} :

CAPÍTULO 2 Templates para WEB 13

create {&ttTable1} .

{web/winclude/wi-datatype.i &dst="{&ttTable1}.cust-num" &type="integer"

&org="w_cust_num:screen-value"}

ASSIGN {&ttTable1}.name = w_name:screen-value

{&ttTable1}.address = w_address:screen-value

{&ttTable1}.city = w_city:screen-value

{&ttTable1}.state = w_state:screen-value

{&ttTable1}.sales-rep = w_sales_rep:screen-value

.

{web/winclude/wi-assign.i}

end.

RUN SUPER.

END PROCEDURE.

Procedure displayFields

Fazer a associação entre a tabela temporária e as variáveis de tela.

FIND FIRST {&ttTable1} NO-LOCK NO-ERROR.

DO WITH FRAME {&FRAME-NAME}:

ASSIGN w_cust_num:screen-value = string({&ttTable1}.cust-num)

w_name:screen-value = {&ttTable1}.name

w_address:screen-value = {&ttTable1}.address

w_city:screen-value = {&ttTable1}.city

w_state:screen-value = {&ttTable1}.state

w_sales_rep:screen-value = {&ttTable1}.sales-rep

hid_chave:screen-value = string({&ttTable1}.rRowid)

.

END.

END PROCEDURE.

14

Includes utilizadas no Cadastro e Consulta Simples / Complexo

{dbo\boXX999.i {&ttTable1}}

Include que define o nome da tabela temporária na Interface .

{method\dbotterr.i}

Includes Utilizadas para a integração da Interface com a DBO .

{web/winclude/wi-datatype.i}

Includes para fazer a validação de Tipo de Dado .

{web/winclude/wi-assign.i}

Include que joga os valores da Interface para a DBO e recebe , se

houverem , os erros .

{web/winclude/wi-error.i}

Verifica se houveram erros na temp-table de erros e se houver gera o

código Javascript necessário para montar a tela de erro .

{web/winclude/wi-enafied.i}

Habilita e Desabilita os campos necessários para a navegação .

{web/winclude/wi-navega.i}

Include que controla a navegação . Chama os metodos corretos para a

navegação .

{web/winclude/wi-header.i}

Include que contem algumas regras para a navegação e controle de

chamadas de programas Filhos.

{web/winclude/wi-metpost.i}

Include que contem as chamadas para os metodos internos do Webspeed para

o Metodo POST

{web/winclude/wi-metget.i}

Include que contem as chamadas para os metodos internos do Webspeed para

o Metodo GET

CAPÍTULO 2 Templates para WEB 15

Estilo Cadastro Complexo

Se todos os campos não ficarem visíveis na área de trabalho, é necessário a

criação de folders. Assim, as informações ficarão reunidas, facilitando o

preenchimento dos dados.

Definição

16

Como construir o Cadastro Complexo

Selecionar os campos

selecione os campos e insira as variáveis que serão utilizados no Cadastro

Simples;

faça os ajustes necessários nos atributos dos campos;

ajuste a ordem dos campos;

utilizar o botão Folders para criar os folders necessários.

Informar Parâmetros

escolher o estilo Cadastro Complexo;

selecionar os Botões que serão utilizados;

preencher o nome do programa. (para programas web: wprograma);

preencher o nome do programa de Vá para. Informando o Método, Altura

e Largura;

preencher o nome do programa de Pesquisa. Informando o Campo, Altura

e Largura;

preencher o nome dos folders. Basta selecionar alguma opção, que será

aberta uma tela para que o nome seja alterado.

Gerar o programa

utilizar a opção de geração de programa;

Alterações necessárias após a geração

se o programa que acabou de ser gerado não faz nenhuma referência a

outras tabelas, então está pronto o Cadastro Complexo;

se o programa utiliza campos de outras tabelas (chaves estrangeiras), então

veja a técnica de ‘Como construir ZOOM’;

CAPÍTULO 2 Templates para WEB 17

se houver alguma regra de navegação (classificação diferente, por

exemplo), então deverá ser customizada a query do BO que o programa

utiliza.

Especificação Técnica – Cadastro Complexo

O inicio do HTML é o mesmo que no cadastro simples. Incluindo os dois elementos

do formulários : hid_chave e hid_oper.

O arquivo .w é exatamente igual ao de consulta/cadastro simples. A única

diferença é o arquivo HTML , que está com um formato diferente . (Uma tentativa de

simular o Client X Server) .

Segue o HTML que deve ser repetido para cada Folder . As alterações serão

explicadas abaixo .

<div align="center"><center>

Definir o nome do folder . Neste exemplo é folder1 <a name="folder1"></a>

<table align="center"border="0" cellpadding="0" cellspacing="3" width="90%"

class="tableForm">

<tr>

<td colspan="3" class="barratitulo"><!--BXLS-->Template de Cadastro

Complexo<!--EXLS--> </td>

</tr>

O Título do Programa deverá aparecer em todos os folders .

<tr>

<td class="linhaForm" nowrap><div align="center"><center>

<table align="center" border="1" cellpadding="0" cellspacing="1"

width="100%"

class="selectedFolder">

<tr>

<td class="linhaForm" nowrap align="center" width="100%">

<!--BXLS-->Principal<!--EXLS-->

</td>

O Folder selecionado não deverá conter o Link para ele mesmo .

18

</tr>

</table>

</center></div>

</td>

<td class="unselectedFolder" nowrap align="center" >

<a href="#folder2"><!--BXLS-->Secundário<!--EXLS--></a>

</td>

<td class="unselectedFolder" nowrap align="center" >

<a href="#folder3"><!--BXLS-->Terceiro<!--EXLS--></a>

</td>

</tr>

</table>

</center></div>

<div align="center"><center>

<table align="center" border="1" cellpadding="0" cellspacing="1" width="90%"

class="tableForm"

height="300">

<tr>

<td valign="top" class="linhaForm" nowrap align="center" colspan="5"

width="100%"><br>

<table align="center" border="0" cellpadding="0" cellspacing="1">

<tr>

<th align="right" class="linhaForm" nowrap><!--BXLS-->Código<!--EXLS-

->:</th>

<td class="linhaForm" align="left" nowrap>

<input type="text" size="5" maxlength="5" name="w_cust_num">

</td>

Sempre deve ser definido <th> contendo o Label e uma <td> contendo um

elemento de formulário

</tr>

<tr>

<th align="right" class="linhaForm" nowrap><!--BXLS-->Nome<!--EXLS--

>:</th>

<td class="linhaForm" align="left" nowrap>

<input type="text" size="40" maxlength="40" name="w_name">

</td>

</tr>

</table>

<p><br></p>

</td>

</tr>

</table>

</center></div>

CAPÍTULO 2 Templates para WEB 19

<p><br><br><br><br></p>

Estes <br> repetidos várias vezes deverão ser ajustados pelo

programador. Para que o folder fique corretamente ajustado na tela .

Lembrando que o padrão para o desenvolvimento é 800 x 600 .

20

Estilo Pai x Filho

Para construção do estilo Pai x Filho, são necessários gerar 2 programas.

Consulta Pai e Filho (<nome>.w, <nome>.htm)

a consulta Pai e Filho gerada é sempre Simples;

siga os mesmos passos do estilo Consulta Simples;

selecione o estilo Consulta Pai ;

utilizar opção de geração do programa.

Quando o programador selecionar a Consulta Pai , o SWG gera 2 arquivos:

HTML - por exemplo: wap0005a.htm;

W - por exemplo: wap0005a.w;

Editar o arquivo .w e incluir os campos do Filho.

Características

CAPÍTULO 2 Templates para WEB 21

Especificação Técnica – Consulta PAI

Arquivo HTML

O HTML do Consulta PAI não deve existir as TAGs de finalização

(</body> e </html> do HTML . Pois a consulta Pai irá chamar o consulta

Filho e este finalizará o HTML com uma include de finalização .

Existe um pequeno BUG no Webspeed e o arquivo HTML deve

conter duas linhas em branco no final do documento .

Existe um formulario para a consulta filho e outro formulário para a

consulta Pai . Sempre um (1) formulário é submetido de vez . E sempre com o

Botão de Submit que estiver em cada Formulário . Não é possível submeter 2

formulários HTML de uma só vez . Por isto não deve ser retirado a TAG

</form> do consulta filho .

<body topmargin="0" leftmargin="0" onload="inicializa()">

<script language="JavaScript">

Definir quais os Botões a Consulta Pai irá conter . Se houver os botões de

cadastro Pai , Modificar e Copiar , este será aberto em uma nova janela .

(Verificar Cadastro PAI) . O significado de cada letra está descrito no

Item Cadastro e Consulta Simples .

function inicializa() {

parent.panel("NGSACMDLHE","WCONPAI 2.00.00.000");

}

</script>

<form method="post">

<input type="hidden" name="hid_chave">

<input type="hidden" name="hid_oper">

<p><br></p>

<div align="center"><center>

<table align="center" border="0" cellpadding="0" cellspacing="3"

width="90%" class="tableForm">

<tr>

<td class="barratitulo">

ATENÇÃO :

22

<!--BXLS--> Template de Consulta PAI x FILHO <!--EXLS-->

</td>

</tr>

<tr>

<td class="linhaForm" nowrap align="center">

<div align="center"><center>

<table align="center" border="0" cellpadding="0" cellspacing="1">

<tr>

<th align="right" class="linhaForm" nowrap>

<!--BXLS-->Código <!--EXLS-->:

</th>

<td class="linhaForm" align="left" nowrap>

<input type="text" size="5" maxlength="5" name="w_cod">

</td>

</tr>

<tr>

<th align="right" class="linhaForm" nowrap>

<!--BXLS-->Nome <!--EXLS-->:</th>

<td class="linhaForm" align="left" nowrap>

<input type="text" size="30" maxlength="30"

name="w_nome">

</td>

</tr>

</table>

</center></div>

</td>

</tr>

</table>

</form>

</center></div>

Não esquecer de deixar 2 linhas em branco no final do documento HTML.

CAPÍTULO 2 Templates para WEB 23

Arquivo .W

Definitions

&GLOBAL-DEFINE ttTable1 tt-tabela

Definir o nome da tabela temporária .

Exemplo :

&GLOBAL-DEFINE ttTable1 tt-customer

&GLOBAL-DEFINE hDBOTable1 boXX999

Definir o nome da BO que será utilizada .

Exemplo :

&GLOBAL-DEFINE hDBOTable1 bosp001

&GLOBAL-DEFINE DBOTable1 tabela

Definir o nome da Tabela que a DBO irá utilizar .

Exemplo :

&GLOBAL-DEFINE DBOTable1 customer

&GLOBAL-DEFINE TableName tabela

Definir o nome da Tabela .

Exemplo :

&GLOBAL-DEFINE TableName customer

&GLOBAL-DEFINE PROGZO diretorio/wzoom.p

Definir o diretório e nome do programa de Zoom .

Exemplo :

&GLOBAL-DEFINE PROGZO adzoom/wz01ad001.p

&GLOBAL-DEFINE TAMZOOM "999" "999"

Definir Largura e Altura que o programa de Zoom irá utilizar .

Exemplo :

24

&GLOBAL-DEFINE TAMZOOM "500" "350"

&GLOBAL-DEFINE PROGGO diretorio/wgoto.w

Definir o Diretório e nome do programa de Vá Para (GoTo) .

Exemplo :

&GLOBAL-DEFINE PROGGO adgo/wg01ad012.w

&GLOBAL-DEFINE TAMGO "999" "999"

Definir Largura e Altura que o Programa de Vá Para (Goto) irá utilizar.

Exemplo:

&GLOBAL-DEFINE TAMGO "300" "250"

&GLOBAL-DEFINE THISNAME diretorio/thisprogram.w

Definir o nome deste programa .

Exemplo :

&GLOBAL-DEFINE THISNAME app/wap001.w

&GLOBAL-DEFINE CADFATHER diretorio/cadpai.w

Definir o nome do programa de Cadastro PAI .

Exemplo :

&GLOBAL-DEFINE CADFATHER app/wapp002.w

&GLOBAL-DEFINE CADFAWID 999

Definir a Largura que o programa de Cadastro PAI irá utilizar .

Exemplo :

&GLOBAL-DEFINE CADFAWID 600

&GLOBAL-DEFINE CADFAHEI 999

Definir a Altura que o programa de Cadastro PAI irá utilizar .

Exemplo:

&GLOBAL-DEFINE CADFAHEI 160

CAPÍTULO 2 Templates para WEB 25

&GLOBAL-DEFINE CADSON diretorio/cadfilho.w

Definir o nome do programa de Cadastro Filho .

Exemplo :

&GLOBAL-DEFINE CADSON app/wap0003.w

Procedure displayFields

Fazer a associação entre a tabela temporária e as variáveis de tela.

FIND FIRST {&ttTable1} NO-LOCK NO-ERROR.

DO WITH FRAME {&FRAME-NAME}:

ASSIGN w_cust_num:screen-value = string({&ttTable1}.cust-num)

w_name:screen-value = {&ttTable1}.name

hid_chave:screen-value = string({&ttTable1}.rRowid)

.

END.

Procedure process-web-request :

Executar a DBO.

Abrir a Query .

Executar a consulta Filho (Sempre será passado para o consulta Filho

a Tabela do PAI . Isto evita excutar a DBO do PAI novamente .)

RUN outputHeader.

RUN dbo/bosp001.p PERSISTENT SET {&hDBOTable1}.

RUN openQueryStatic in {&hDBOTable1} (input "Main":u).

{web/winclude/wi-getpai.i}

RUN displayError .

delete procedure {&hDBOTable1}.

RUN web/app /wap0004.p (input table {&ttTable1}) .

26

Includes utilizadas no Consulta PAI

{dbo\boXX999.i {&ttTable1}}

Include que define o nome da tabela temporária na Interface .

{method\dbotterr.i}

Includes Utilizadas para a integração da Interface com a DBO .

{web/winclude/wi-error.i}

Verifica se houveram erros na temp-table de erros e se houver gera o

código Javascript necessário para montar a tela de erro .

{web/winclude/wi-enafied.i}

Habilita e Desabilita os campos necessários para a navegação .

{web/winclude/wi-navega.i}

Include que controla a navegação . Chama os metodos corretos para a

navegação .

{web/winclude/wi-header.i}

Include que contem algumas regras para a navegação e controle de

chamadas de programas Filhos.

{web/winclude/wi-getpai.i}

Include que contem as chamadas para os metodos internos do Webspeed para

o Metodo GET .

Especificação Técnica – Consulta Filho

O Programa de Consulta Filho é um CGI-WRAPER .

Definitions :

&GLOBAL-DEFINE THISNAME diretorio/confilho.p

Definir o diretório e nome deste programa .

Exemplo:

CAPÍTULO 2 Templates para WEB 27

&GLOBAL-DEFINE THISNAME ricardo/wconson.p

&GLOBAL-DEFINE FATHERNAME conpai.w

Definir o nome do Programa PAI . (Somente o Nome)

Exemplo :

&GLOBAL-DEFINE FATHERNAME wconpai.w

&GLOBAL-DEFINE ttTableFather tt-tabela

Definir o nome da tabela temporária PAI .

Exemplo:

&GLOBAL-DEFINE ttTableFather tt-customer

&GLOBAL-DEFINE TableName tabela

Definir o nome da tabela PAI .

Exemplo:

&GLOBAL-DEFINE TableName customer

&GLOBAL-DEFINE ttTableSon tt-tabela-filho

Definir o nome da tabela temporária do Filho .

Exemplo:

&GLOBAL-DEFINE ttTableSon tt-order

&GLOBAL-DEFINE TableName tabela-filho

Definir o nome da Tabela do Filho .

Exemplo:

&GLOBAL-DEFINE TableName Order

&GLOBAL-DEFINE hDBOSon boXX999

Definir o nome da DBO do Filho .

Exemplo:

&GLOBAL-DEFINE hDBOSon bosp005

&GLOBAL-DEFINE sonNAME cadfilho.w

28

Definir o nome do Programa de Cadastro Filho .

Exemplo:

&GLOBAL-DEFINE sonNAME wcadsonc.w

&GLOBAL-DEFINE sonWIDTH 999

Definir a largura que o programa de Cadastro filho ocupará .

Exemplo:

&GLOBAL-DEFINE sonWIDTH 500

&GLOBAL-DEFINE sonHEIGHT 999

Definir a altura que o programa de Cadastro filho ocupará .

Exemplo:

&GLOBAL-DEFINE sonHEIGHT 215

&GLOBAL-DEFINE SONBUTTONS ADD,MOD,DEL

Definir os botões para Incluir , Modificar e Eliminar registros filhos.

O preprocessador deve ser definido apenas com os botões desejados.

Exemplo:

1) &GLOBAL-DEFINE SONBUTTONS ADD,MOD,DEL

2) &GLOBAL-DEFINE SONBUTTONS ADD,DEL

Procedure addCol :

Definir quais os campos que serão apresentados na Consulta Filho .

Utilizar os métodos da API de BROWSE .

Se o programa de Consulta chamar : Inclusão , Modificação e Exclusão,

deve-se definir um elemento de Radio chamado xradio .

CAPÍTULO 2 Templates para WEB 29

Exemplo :

RUN addInput in h-brwapi ("xradio" , "R" , "" , "center" , ?) .

RUN addField in h-brwapi ("Cust-Num", "I", "Customer", "center", ?).

RUN addField in h-brwapi ("Order-num", "I", "Order", "center", ?).

RUN addField in h-brwapi ("Order-Date", "D" , "Data", "center", ?).

Procedure addNav :

Definir se vai existir Navegação no Browse .

Definir qual o tamanho da Borda .

RUN setNavigation in h-brwapi (true).

RUN setBorder in h-brwapi (2).

Procedure generateHeaderSon :

Se houver mais botões além dos Default(Incluir , Modificar e Excluir) ,

deve utilizar a include abaixo .

def var auxFunction as char no-undo .

assign auxFunction = "marcar()" .

{web/winclude/wi-sonbut.i "Marcar" "btn_Marcar" auxFunction}

A função javascript marcar() deve ser declarada na output-header , depois da

include wi-header.i .

Os botões gerados são do tipo button , e este não submetem o formulário do

filho . Para submeter o formulário do filho , deve-se utilizar uma função

javascript :

function SubmeterSon() {

30

document.form[1].submit() ;

}

Deve-se prestar atenção para o número do formulário , que sempre será o

segundo . ( No JavaScript o primeiro número de um Array é sempre 0 (ZERO)

)

Definir o Título do Filho .

assign titleSon = "Relação Customer X Order" .

Procedure process-web-request :

Executar a DBO Filho .

RUN dbo/bosp005.p PERSISTENT SET {&hDBOSon}.

find first {&ttTableFather} no-lock no-error .

Executar a SetConstraint correspondente a restrição que será feita .

RUN setConstraintCust-Num in {&hDBOSon} (input {&ttTableFather}.Cust-

Num) .

Abrir a Query

RUN openQueryStatic in {&hDBOSon} (input "Cust-Num":u).

Definir o Número de Linhas do Browser .

{web/winclude/wi-sonnav.i &nrlinha=5}

Esta include instancia a API de Browser, por isso, é necessário que o

desenvolvedor elimine o handle (h-brwapi) desta API no final do

programa.

CAPÍTULO 2 Templates para WEB 31

Includes utilizadas no Consulta Filho

{dbo\boXX999.i tt-tabela}

Include que define o nome da tabela temporária na Interface . No

programa de Consulta Filho é necessário declarar duas vezes . A temp-

table da Pai e a Temp-table do Filho .

{method\dbotterr.i}

Includes Utilizadas para a integração da Interface com a DBO .

{web/winclude/wi-header.i}

Include que contem algumas regras para a navegação e controle de

chamadas de programas Filhos.

{web/winclude/wi-sonhei.i}

Gera as tags iniciais de tabela e formulário para a geração do codigo do

filho .

{web/winclude/wi-sonbdef.i}

Gera os botões (default) para inclusão , modificação e exclusão de

registros .

{web/winclude/wi-sonbut.i}

Gera botões customizados . Onde deve-se definir o nome do botão e a

chamada javascript (É aconselhado utilizar uma função Javascript.)

{web/winclude/wi-sonhef.i}

Geras as tags finais para os botões .

{web/winclude/wi-sontitle.i}

Gera o título para o programa filho .

{web/winclude/wi-sonnav.i}

Posiciona na DBO no registro desejado . Por exemplo : Navegação e na

exclusão de registros.

{web/winclude/wi-endson.i}

Gera os códigos finais para o HTML e deleta a handle da procedure de

API.

32

Cadastro PAI (Simples/Complexo) (<nome>.htm, <nome>.w)

independente de que se for um Cadastro Simples ou Complexo,

basta seguir os mesmos passos de construção do Cadastro Simples

ou Complexo;

selecionar o estilo Cadastro PAI Simples ou Cadastro PAI

Complexo;

utilizar opção de geração do programa.

Especificação Técnica – Cadastro PAI SIMPLES/COMPLEXO

Arquivo HTML

O diferencial dos HTML para os outros cadastro ,é que no Cadastro

Pai existe um botão de Submit e outro para limpar o formulário (Restaurar

para os valores originais.)

Segue um exemplo para o Cadastro Pai simples :

<html>

<head>

<title>Template Cadastro do Pai Simples</title>

<link rel="StyleSheet" type="text/css" href="/ems20web/padrao.css">

<meta http-equiv="Cache-Control" content="No-Cache">

<meta http-equiv="Pragma" content="No-Cache">

<meta http-equiv="Expires" content="0">

</head>

<body topmargin="0" leftmargin="0">

<form method="post">

<input type="hidden" name="hid_chave" value="?">

<input type="hidden" name="hid_oper" value="?">

<div align="center"><center>

CAPÍTULO 2 Templates para WEB 33

<table align="center" border="0" cellpadding="0" cellspacing="1"

width="100%" class="tableForm">

<tr>

<td class="linhaForm" nowrap align="center"><br>

<table align="center" border="0" cellpadding="0" cellspacing="1">

<tr>

<th align="right" class="linhaForm" nowrap>

<!--BXLS-->Código <!--EXLS-->:

</th>

<td class="linhaForm" align="left" nowrap>

<input type="text" size="5" maxlength="5" name="w_cod">

</td>

</tr>

</table>

<br>

</td>

<tr>

<td class="linhaForm" nowrap colspan="2" align="center">

<input type="submit" name="ok" value=" OK ">

<input type="button" name="cancel" value="Cancelar"

onclick="self.close()">

Os dois botões devem ser elementos de formulários . Não devem

ser utilizadas as imagens de OK e Cancel do Menu .

<p><br></p>

</td>

</tr>

</table>

</center></div>

</form></body></html>

Segue um exemplo para o Cadastro Pai Complexo :

<div align="center"><center>

Definir o nome do folder . Neste exemplo é folder1 <a name="folder1"></a>

<table align="center"border="0" cellpadding="0" cellspacing="3" width="90%"

class="tableForm">

<tr>

34

<td colspan="3" class="barratitulo"><!--BXLS-->Template de Cadastro

Complexo<!--EXLS--> </td>

</tr>

O Título do Programa deverá aparecer em todos os folders .

<tr>

<td class="linhaForm" nowrap><div align="center"><center>

<table align="center" border="1" cellpadding="0" cellspacing="1"

width="100%"

class="selectedFolder">

<tr>

<td class="linhaForm" nowrap align="center" width="100%">

<!--BXLS-->Principal<!--EXLS-->

</td>

O Folder selecionado não deverá conter o Link para ele mesmo .

</tr>

</table>

</center></div>

</td>

<td class="unselectedFolder" nowrap align="center" >

<a href="#folder2"><!--BXLS-->Secundário<!--EXLS--></a>

</td>

<td class="unselectedFolder" nowrap align="center" >

<a href="#folder3"><!--BXLS-->Terceiro<!--EXLS--></a>

</td>

</tr>

</table>

</center></div>

<div align="center"><center>

<table align="center" border="1" cellpadding="0" cellspacing="1" width="90%"

class="tableForm"

height="300">

<tr>

<td valign="top" class="linhaForm" nowrap align="center" colspan="5"

width="100%"><br>

<table align="center" border="0" cellpadding="0" cellspacing="1">

<tr>

<th align="right" class="linhaForm" nowrap><!--BXLS-->Código<!--EXLS-

->:</th>

<td class="linhaForm" align="left" nowrap>

<input type="text" size="5" maxlength="5" name="w_cust_num">

</td>

Sempre deve ser definido <th> contendo o Label e uma <td> contendo um

elemento de formulário

CAPÍTULO 2 Templates para WEB 35

</tr>

<tr>

<th align="right" class="linhaForm" nowrap><!--BXLS-->Nome<!--EXLS--

>:</th>

<td class="linhaForm" align="left" nowrap>

<input type="text" size="40" maxlength="40" name="w_name">

</td>

</tr>

<tr>

<td class="linhaForm" nowrap align="center" width="100%">

<center>

<input type="submit" name="ok" value=" OK ">

<input type="button" name="cancel" value="Cancelar"

onclick="self.close()">

</center>

</td>

</tr>

</table>

...

Os botões devem ficar sempre o último Folder . Nâo faz sentido

colocar em cada Folder os Botões de OK e Cancelar em cada Folder , se

todos os dados devem ser cadastrados . Assim obriga o usuário a passar

em todos os folders .

Arquivo .W

Definitions :

&GLOBAL-DEFINE ttTable1 tt-tabela

Definir o nome da tabela temporária .

Exemplo :

&GLOBAL-DEFINE ttTable1 tt-customer

36

&GLOBAL-DEFINE hDBOTable1 boXX999

Definir o nome da DBO .

Exemplo :

&GLOBAL-DEFINE hDBOTable1 bosp001

&GLOBAL-DEFINE DBOTable1 tabela

Definir o nome da tabela .

Exemplo :

&GLOBAL-DEFINE DBOTable1 customer

&GLOBAL-DEFINE TableName tabela

Definir o nome da Tabela que será utilizada na DBO .

Exemplo :

&GLOBAL-DEFINE TableName customer

&GLOBAL-DEFINE THISNAME diretorio/wcadpai.w

Definir o diretório e nome deste programa .

Exemplo :

&GLOBAL-DEFINE THISNAME app/wap0006.w

&GLOBAL-DEFINE NFACON diretorio/wconpai.w

Definir o diretório e nome do programa de consulta pai .

Exemplo :

&GLOBAL-DEFINE NFACON ricardo/wconpai.w

Procedure assignFields :

Definir quais os campos que serão validados com wi-datatype.i .

Verificar no Capítulo de Validações o funcionamento da wi-datatype.i

Fazer a associação entre as variáveis de tela (HTML) com a tabela

temporária .

if request_method = "POST" then DO WITH FRAME {&FRAME-NAME} :

CAPÍTULO 2 Templates para WEB 37

create {&ttTable1} .

ASSIGN {&ttTable1}.cust-num = int(w_cod:screen-value)

{&ttTable1}.name = w_nome:screen-value

{&ttTable1}.address = w_end:screen-value

{&ttTable1}.city = w_cid:screen-value

{&ttTable1}.state = w_est:screen-value

{&ttTable1}.sales-rep = w_sal:screen-value

.

{web/winclude/wi-assign.i}

end.

Procedure displayFields

Fazer a associação entre a tabela temporária e as variáveis de tela.

FIND FIRST {&ttTable1} NO-LOCK NO-ERROR.

DO WITH FRAME {&FRAME-NAME}:

ASSIGN w_cod:screen-value = string({&ttTable1}.cust-num)

w_nome:screen-value = {&ttTable1}.name

w_end:screen-value = {&ttTable1}.address

w_cid:screen-value = {&ttTable1}.city

w_est:screen-value = {&ttTable1}.state

w_sal:screen-value = {&ttTable1}.sales-rep

hid_chave:screen-value = string({&ttTable1}.rRowid)

.

{web/winclude/wi-disp.i}

END.

Procedure process-web-request :

38

Executar a DBO persistente .

Abrir a Query (Se houver no programa , antes abrir a SetConstraint) .

RUN dbo/bosp001.p PERSISTENT SET {&hDBOTable1}.

RUN openQueryStatic in {&hDBOTable1} (input "Main":u).

Consulta Filho (<nome>d.w, <nome>d.htm)

seguir os mesmos passos do estilo Cadastro Simples/Complexo;

selecionar o Estilho Cadastro FILHO Simples ou Cadastro FILHO

Complexo;

utilizar opção de geração do Programa.

Especificação Técnica – Cadastro Filho SIMPLES/COMPLEXO

Para construir o HTML para Cadastro Filho deve-se seguir o padrão

Cadastro Pai Simples (Especificação Técnica – Cadastro Pai

Simples/Complexo) .

Estilo Consulta Simples / Estilo Consulta Complexa

Para a construção deste estilo, seguir os mesmos passos dos Estilos Cadastro

Simples/Complexa. O template, internamente, é muito semelhante. A única

diferença da Consulta para o Cadastro são os parâmetros da função JavaScript

inicializa (). Que se encontra, sempre, no HTML:

<bodytopmargin=”0”leftmargin=”0”onload=”inicializa()” >

CAPÍTULO 2 Templates para WEB 39

Os parâmetros do Cadastro são:

function inicializa() {parent.panel(“NGSACMDUROHE”,”wap0005

2.00.00.000”);}

E os parâmetros da Consulta são:

function inicializa(){parent.panel(“NGSROHE”,”wap00051

2.00.00.000”);}

O significado de cada letra é:

N - Botões de Navegação

G - Go to

S - Search

A - Add

C - Copy

M - Modify

D - Delete

U - Undo

L – Consulta Relacionada

R - Reset (Formulário)

O - OK (Função de Submit)

H - Home

E - Exit

40

Estilo Vá Para

Seleção:

selecionar os Campos;

ajustar os Campos/Variáveis.

Parâmetros:

selecionar Estilo Vá Para;

escolher o Método da BO (para fazer a busca);

utilizar a opção para gerar o programa.

CAPÍTULO 2 Templates para WEB 41

Especificação Técnica – Vá Para

Arquivo HTML

O início (cabeçalho) do HTML é exatamente igual ao HTML de

Consulta.

Definir na TAG <title> o título do Programa.

<table align="center" border="0" cellpadding="0"

cellspacing="1" width="90%">

<tr>

<td class="linhaForm" nowrap align="center">

<p align="center"><br></p>

<div align="center"><center>

<table align="center" border="0" cellpadding="0"

cellspacing="1">

Definir quais são os campos chaves que farão a busca.

<tr>

<th align="right" class="linhaForm" nowrap>

<!--BXLS-->Código<!--EXLS-->:</th>

<td class="linhaForm" align="left" nowrap>

<input type="text" size="5" maxlength="5"

name="w_cod">

</td>

</tr>

Não esquecer de deixar uma linha da tabela em branco .

<tr>

<td class="linhaForm" nowrap>&nbsp;</td>

<td class="linhaForm" nowrap>&nbsp;</td>

42

</tr>

<tr>

Depois da linha da tabela em branco , definir os botões de

Submit e Reset .

<td class="linhaForm" nowrap align="center" colspan="2">

<input type="submit" name="button" value=" Ok

">&nbsp;

<input type="button" name="button" value=" Cancel "

onclick="self.close()">

</td>

</tr>

</table>

</center></div><p><br></p>

</td>

</tr>

</table>

</center></div>

<p>&nbsp;</p>

</form></body></html>.

Arquivo .W

Definitions

&GLOBAL-DEFINE ttTable1 tt-tabela

Definir o nome da tabela .

Por Exemplo :

&GLOBAL-DEFINE ttTable1 tt-customer

&GLOBAL-DEFINE hDBOTable1 boaa000

Definir o nome da BO que será utilizada .

Por Exemplo :

&GLOBAL-DEFINE hDBOTable1 bosp001

CAPÍTULO 2 Templates para WEB 43

&GLOBAL-DEFINE DBOTable1 tabela

Definir o nome da tabela que a BO utilizará .

Por Exemplo :

&GLOBAL-DEFINE DBOTable1 customer

&GLOBAL-DEFINE TableName tabela

Definir o nome da tabela que o programa utilizará .

Por Exemplo :

&GLOBAL-DEFINE TableName customer

Procedure displayFields

Definir o nome variável de tela que será atribuida a ela mesmo . Assim , quando

o programa entrar no método POST não irá perder o valor que o usuário digitou

no campo .

Exemplo :

IF request_method = "post" then do WITH FRAME {&FRAME-NAME} :

assign w_cod:screen-value = get-value("w_cod") .

end.

else do :

RUN SUPER .

end.

Procedure displayFields

Executar a BO em Persistente .

Abrir a Query.

Resgatar o valor da variável (pesquisa) HTML .

Executar a Procedure goToKey passando como parâmetro o valor da

variável HTML .

def var cod_num as integer no-undo .

def var wRowid as rowid no-undo .

44

def var c-nome-prog-requis as char no-undo .

assign c-nome-prog-requis = get-value("prog").

RUN dbo/bosp001.p PERSISTENT SET {&hDBOTable1}.

RUN openQueryStatic in {&hDBOTable1} (input "Main":u).

assign cod_num = int(get-value("w_cod")) .

RUN goToKey in {&hDBOTable1} (input cod_num) .

{web/winclude/wi-retgoto.i}

delete procedure {&hDBOTable1}.

CAPÍTULO 2 Templates para WEB 45

Estilo Pesquisa / ZOOM

Seleção:

Como construir um Programa de Zoom/Pesquisa utilizando o template

wmazoom.p.

Passos :

Copie do diretório wmasters (x:\ems20por\web\wmasters) o arquivo

wmazoom.p e renomeie .

A seguir altere nas seguinte procedures :

Definitions

46

- Utilizar a include da BO para configurar o nome da tabela temporária .

- Utilizar a include da Tabela de Error

{xx/bo/boXX999.i tt-tabela}

{include/boerrtab.i}

- Definir os nome da HANDLE

def var h-boXX999 as handle no-undo.

- Definir as variaveis de Faixa

def var ini_var as char no-undo .

def var fim_var as char no-undo .

- Definir a Variável que Guarda o número da Query a ser executada. (Isto se

o seu programa de Zoom/Pesquisa tiver várias Ordenações )

def var ordena as char no-undo .

PROCEDURE process-web-request

- Se o seu programa tiver Faixas de Pesquisa , Várias Ordenações , deverá ser

executado a procedure setVariablesRange

run setVariablesRange.

- Executar a BO .

run XXbo/boXX999.p persistent set h-boad018.

- Definir qual a setConstraint a ser utilizada

Por Exemplo : run setConstraint1 in h-boad018 (input ini_nome , input

fim_nome) .

- Dependendo a Ordenaçao a ser utilizada ,

definir qual a openQuery que deverá ser utilizada.

Por Exemplo :

if ordena = "1" then

run openQuery in h-boad018 (4).

if ordena = "2" then

run openQuery in h-boad018 (2) .

CAPÍTULO 2 Templates para WEB 47

run openquery in h-boXX999 (1).

-Definir o nome da handle da BO utilizada

-Deninir o Número de Linhas do Browse

{web/winclude/wi-inibrz.i &bohandle="h-boXX999" &nrlinha=10}

- Para adicionar uma coluna com campo , execute o método da API de BROWSE-

addField . Por Exemplo :

run addField in h-brwapi ("cod-banco", "I", "Banco", "right", ?).

run addField in h-brwapi ("campo", "I", "Label", "right", ?).

- Para adicionar um link para o Retorno das Variáveis deve-se :

- Definir o nome do campo utilizado

- Definir o tipo

- Definir o Label

- Definir o alinhamento

Por exemplo :

{web/app/wi-rtnbrz.i &nome-campo="nome-banco" &tipo="C" &label="Nome"

&align="right"}

{web/winclude/wi-rtnbrz.i &nome-campo="campo" &tipo="C" &label="Label"

&align="right"}

- Executar o método addField para adicionar outras colunas

48

- Definir o nome do programa de ZOOM/PESQUISA

Obs.: Não deve ser colocado APPURL . O WEB SERVER ASSUME O

CAMINHO .

Por exemplo :

{web/winclude/wi-likbrz.i &nomeprog="wg01ad001.p"}

{web/winclude/wi-likbrz.i &nomeprog="wg99XX999.p"}

run setNavigation in h-brwapi (true).

run setBorder in h-brwapi (2).

Run output-header.

{&OUT}

"<HTML>":U SKIP

"<HEAD>":U SKIP

"<TITLE> {&FILE-NAME} </TITLE>":U SKIP

'<link rel="stylesheet" href="/ems20web/padrao.css">'

.

-Definir o número de Campos utilizados no Browser .

Por Exemplo :

{web/app/wi-jscbrz.i &num_campos_browse=3}

{web/app/wi-jscbrz.i &num_campos_browse=10}

- Na TAG FORM , deve ser colocado o nome do programa de zoom .

Por exemplo :

'<form method="post" action="wg01ad001.p?funcao=' get-value("funcao")

'&prog_requis=' get-value("prog_requis") '&retorno=' get-value("retorno") '">'

{&out}

"</HEAD>":U SKIP

"<BODY>":U SKIP

'<form method="post" action="wg99XX999.p?funcao=' get-value("funcao")

'&prog_requis=' get-value("prog_requis") '&retorno=' get-value("retorno") '">' .

- O Método generateRange deve ser executado se o seu programa conter faixa ,

multipla ordenação e botão para parâmetro.

run generateRange.

CAPÍTULO 2 Templates para WEB 49

run generateBrowse in h-brwapi.

{&out} return-value.

{&OUT}

'</form>'

"</BODY>":U SKIP

"</HTML>":U SKIP

.

delete procedure h-brwapi.

delete procedure h-boad018.

PROCEDURE retornaJavaScript :

- Esta Procedure é executada pelo método addFunction da Api de Browse .

define input parameter r-rowid as rowid no-undo.

define output parameter c-char as char no-undo.

- Executar o getCurrent e encontrar o primeiro registro da Temp-Table

Por exemplo :

RUN getCurrent in h-boad018 (output table tt-banco).

find first tt-banco where tt-banco.r-rowid = r-rowid no-lock no-error.

RUN getCurrent in h-boXX999 (output table tt-tabela).

find first tt-tabela where tt-tabela.r-rowid = r-rowid no-lock no-error.

- Definir o número de Campos no Browser nas variáveis Extent

Por Exemplo :

define variable aux-nome as char extent 3 init "".

define variable aux-valor as char extent 3 init "".

define variable aux-campo as char extent 3 init "".

define variable aux-nome as char extent 10 init "".

define variable aux-valor as char extent 10 init "".

define variable aux-campo as char extent 10 init "".

- Definir o nome da variável e o valor de cada campo

Por Exemplo :

assign aux-nome[1] = "tt-banco.cod-banco"

aux-valor[1] = string(tt-banco.cod-banco)

50

aux-nome[2] = "tt-banco.nome-banco"

aux-valor[2] = tt-banco.nome-banco

aux-nome[3] = "tt-banco.ag-padrao"

aux-valor[3] = tt-banco.ag-padrao .

assign aux-nome[99] = "tt-tabela.campo"

aux-valor[99] = string(tt-tabela.campo)

.

{web/app/wi-shlbrz.i}

- Definir qual o campo que será mostrado no Link

Por exemplo :

assign c-char = beginLink + tt-banco.nome-banco + endLink.

assign c-char = beginLink + tt-tabela.campo + endLink.

END PROCEDURE.

PROCEDURE generateRange :

Esta procedure Gera o HTML para a Faixa , Ordenação e para Botões de Parâmetro

Segue abaixo uma lógica default para mostrar uma faixa e ordenação .

Obs.: Na inclusão de Novas faixas , o programador deve inserir a lógica

para mostrar as outras faixas.

- Deve ser definido as variável chamadas LabelN e que vai conter as Labels das

faixas , Labels dos Radio e Labels do Botão

Por Exemplo :

def var label1 as char no-undo.

assign label1 = "Banco Inicial".

.

PROCEDURE setVariablesRange :

- Segue uma lógica default para gravar no Contexto de Sessão um campo de

ordenação e de dois Campos de Faixa . 1 Inicial e ou Campo Final .

def var h-prog as handle no-undo.

CAPÍTULO 2 Templates para WEB 51

def var c-token as char no-undo.

assign c-token = get-cookie("SessionContextToken":u).

run web/wutp/wu-sessao.p persistent set h-prog.

run setToken in h-prog (c-token).

if request_method <> "POST" then do :

- Verificar se existe Contexto de sessao gravado .

- Se nao existir colocar valores iniciais

- Se existir colocar os valores que estao no contexto de sessao

run getContext in h-prog ("ini_nome":u , output ini_nome) .

run getContext in h-prog ("fim_nome":u , output fim_nome) .

run getContext in h-prog ("ordena":u , output ordena).

if ini_nome = "" then

assign ini_nome = "" .

if fim_nome = "" then

assign fim_nome = "ZZZZZZZZZZZ".

if ordena="" then

assign ordena = "1".

end.

else do:

assign ini_nome = get-value("ini_nome")

fim_nome = get-value("fim_nome")

ordena = get-value("ordena") .

run setContext in h-prog ("ini_nome":u, ini_nome ) .

run setContext in h-prog ("fim_nome":u, fim_nome ) .

run setContext in h-prog ("ordena":u, ordena).

end.

delete procedure h-prog.

ZOOM

O Zoom utiliza o mesmo template de pesquisa. (Seguir os mesmos passos para

a geração do programa). O que diferencia é que o programa de Zoom utiliza a

função JavaScript abreZoom().

Exemplo:

52

...

<input type=”text”size=”5” name=”w_gb_codigo”>

<a

href=”javascript:abreZoom(‘web/<modulo>zoom/<nomezoom>.p’,400,40

0,’tt-grupo-bem.gb-codigo,w_gb_codigo,tt-grupo-

bem.descrcao,w_c_desc_gb’)”>

<img src=”/ems20web/wimages/ii-zoom.gif” align=”absmiddle”

border=”0” width=”23” height=”23”></a>

<input type=”text” size=”37” name=”w_c_desc_gb”>

...

Atenção :

Nas chamadas dos programas de zoom/pesquisa , é passado

como parâmetro uma variável chamada primeira e o valor é

sempre yes . Assim , é possível fazer um teste e saber que

aquele programa está sendo executado pela primeira vez .

Isto é o usuário clicou nos botões de zoom e pesquisa .

Por exemplo :

If get-value(“primeira”) = “yes” then do:

ValorInicial = “AAAAA”

ValorFinal = “ZZZZZ”

End.

Else do:

/* Recupera do contexto de sessão */

End.

Este procedimento é necessário , pois toda a vez que o

usuário especificar uma faixa e selecionar um campo ou

fechar o Zoom/Pesquisa . E na mesma sessão este usuário

reabrir o programa os valores devem ser os iniciais e não

os valores que ele colocou na faixa .

Estilo Relatório

Os programas de relatório na WEB não serão executados de modo on-line, e

sim em batch. O programador, após entrar com os parâmetros e seleções,

deverá agendar a execução do relatório via RPW, este que após realizado

poderá ser consultado e visualizado via seu monitor.

CAPÍTULO 2 Templates para WEB 53

Para criar um programa de relatório na WEB, deve-se seguir os seguintes

passos:

1. Copiar o programa temprel.w e temprel.htm para o diretório, onde ficará o

novo programa.

2. Renomeie estes arquivos para o nome do programa.

3. Mude na seguinte linha, o nome do arquivo .htm

&Scoped-define WEB-FILE wmasters/temprel.htm

4. Alterar via um editor de HTML os folders seleção e parâmetros de acordo

com a especificação do programa, podendo ser criados novos folders caso

necessário.

5. Abrir o programa no Workshop para que ele faça o mapeamento dos

campos.

6. Alterar a definição da temp-table “tt_param”, na sessão “Definitions”, para

ficar de acordo com a temp-table utilizada no programa RP.

7. Associar os campos da temp-table tt_param aos campos de tela, na sessão

pi-executar.

8. Alterar o valor do campo tta_cod_modul_dtsul_corren da temp-table

tt_param_segur para o módulo a qual este programa pertence.

9. Alterar o valor do campo tta_cod_prog_dtsul da temp-table tt_ped_exec

para o nome do programa original no EMS 2.0.

10. Alterar o valor do campo tta_cod_prog_dtsul_rp da temp-table

tt_ped_exec para o nome do programa RP a ser executado pelo RPW.

11. Alterar o valor do campo tta_cod_dwb_file da temp-table

tt_ped_exec_param para o nome do programa original no EMS 2.0.

12. (EMS 2.02) Alterar o nome do programa nas procedures internas

uspfLoadParameters e uspfSaveParameters

Para maiores informações sobre estas tabelas temporárias, consulte a

documentação da api btb912zb.p.

55

CAPÍTULO 3

Como usar uma BO

Para usarmos uma BO devemos:

1. Declarar a variável que irá conter o handle da BO.

2. Instanciar a BO, ou seja, rodar a BO deixando-a disponível na memória.

3. Chamar os métodos.

3.1. A abertura da query pode ser feita através da chamada do método

openQuery passando como parâmetro o número da query que deve ser

aberta. É importante atentarmos para o fato de que é necessário rodar

o método setConstraint correspondente, ou seja, ao abrirmos a query 2

devemos rodar o método setConstraint2 anteriormente.

3.2. Se não for aberta uma query a BO usará o comando find para realizar

pesquisas nos métodos padrões, usa-se esta característica em especial

para o método findRowid onde neste caso há ganhos de performance.

4. Eliminar a instância da BO.

Exemplo:

def var w-cd-banco as integer no-undo.

def var h-boad018 as handle no-undo. // passo 1

def var h-DataObject as handle no-undo.

RUN adbo/boad018.p persistent set h-boad018. // passo 2

RUN findRowid in h-boad018(input r_chave). // passo 3

RUN getIntField ind h-boad018(input “cod-banco”, output w-

cd-banco).

delete procedure h-boad018.

RUN adbo/boad002.p persistent set h-DataObject.

56

RUN setConstraint2 in h-DataObject(input w-cd-banco). //

item 3.1

RUN openQuery in h-DataObject(2). // item 3.1

Os retornos de erro da BO são realizados via tt-bo-erro que não pode ser

customizada pelos desenvolvedores.Observação:

57

CAPÍTULO 4

Contexto de Sessão

O contexto de sessão (CS), tem por objetivo fornecer ao desenvolvedor WEB,

um mecanismo para guardar valores para uso posterior nos programas. Seria o

equivalente a variáveis globais no ambiente Cliente/Servidor.

Alguns destes valores podem ser utilizados: usuário corrente, idioma do

usuário, rowid de registros correntes, etc.

Através do CS, o programador vai poder trocar informações entre dois

programas, já que as informações vão ficar disponíveis para outros programas.

O uso do CS deve ser exclusivamente na parte de interface. Os BO´s não

devem acessar a API de contexto de sessão. O motivo é que o CS usa

mecanismos que são específicos da interface WEB (cookie) que não estão

disponíveis na parte do BO.

método setContext para indicar que este quando o valor passado como

parâmetro para ser setado não existir na tabela de contexto este será

criado;

método getTransacao quando não encontra o registro que o usuário tenta

recuperar retorna branco. Para verificar se o registro está em branco na

base de dados ou não existe pode-se usar o método getContextStatus que

irá retornar false quando a informação não existir.

Funcionamento

O contexto de sessão se baseia no fato de que cada usuário conectado vai ter

um token que identifica a sessão do mesmo. Este token identifica os valores do

contexto da sessão do usuário.

Descrição

Métodos

58

Para usar o contexto de sessão, deve ser usado o programa WU-SESSION.P. A

seguir estão descritos os processos disponíveis.

Gerando o token da sessão

O token da sessão é gerado pelo programa de login (web/btp/wbtb910.w).

Normalmente, o programador não vai gerar novos tokens. O que o

programador precisa é buscar o token da sessão, quando precisar salvar ou

recuperar valores.

O programa de login gera o token para a sessão e o deixa disponível em um

cookie (‘SessionContextToken). Para obter o valor deste token use a função

get-cookie, conforme demonstrado a seguir.

Obtendo o token da sessão

Para obter o token gerado pelo programa de login, use a função get-cookie e

salve numa variável do tipo char. Depois o programador usará este token para

salvar e recuperar valores.

def var c-token as char no-undo.

assign c-token = get-cookie(“SessionContextToken”:u).

Armazenando um valor para uso futuro

De posse do token da sessão, o programador poderá guardar valores usando a

função createNewContext da api de contexto (wu-sessao.p). Por exemplo, o

programador quer guardar a empresa e idioma do usuário corrente.

def var h-prog as handle no-undo.

def var c-token as char no-undo.

assign c-token = get-cookie(“SessionContextToken”:u).

run web/wutp/wu-sessao.p persistent set h-prog.

run setToken in h-prog (c-token).

run createNewContext in h-prog (“meuprog-empresa”:u, “1”).

run createNewContext in h-prog (“meuprog-idioma”:u,

“portugues”:u ).

delete procedure h-prog.

Observação O desenvolvedor define os nomes de variáveis (no exemplo:

meuprog-empresa, meuprog-idioma) para os valores de contexto que desejar

guardar. O padrão para este nome de variável é o nome do programa, o

caracter “-“ e uma sequência de caracteres para identificar a variável. É

importante usar o nome do programa como parte do nome da variável para

CAPÍTULO 4 Contexto de Sessão 59

garantir que programas com nomes de variáveis idênticos não acabem

recuperando contextos trocados.

Recuperando um valor armazenado

Para obter um valor armazenado previamente use a função getContext da API.

def var h-prog as handle no-undo.

def var c-token as char no-undo.

Def var c-emp as char no-undo.

Def var c-idioma as char no-undo.

Assign c-token = get-cookie(“SessionContextToken”:U).

run web/wutp/wu-sessao.p persistent set h-prog.

Run set Token (c-token) in h-prog.

run getContext in h-prog (‘meuprog-empresa’:U, output c-

emp).

run getContext in h-prog (‘meuprog-idioma’:U, ouput c-

idioma).

Delete procedure h-prog.

os valores para createNewContext e getContext são do tipo character. O

programador precisa fazer as conversões necessárias quando trabalhar com

variáveis inteiro, decimal, date, etc.;

os nomes de variáveis são definidos pelo desenvolvedor dentro do padrão

estabelecido. É importante apenas colocar após o nome da variável o

identificador: U para evitar a tradução destes nomes;

o login deixa disponível alguns valores padrões para a sessão. Verificar no

include “web/winclude/wivglob.i”;

se não for executado o login, não haverá token definido para a sessão e o

contexto de sessão não funcionará;

sempre que usar strings e for possível use a propriedade :u para as

informações;

quando executamos o método createNewContext ele cria um novo

registro, caso o registro já exista e o programador deseje alterá-lo, basta

usar o método setContext que recebe dois input parameter que são

respectivamente o nome a ser alterado e o novo valor.

Observações:

61

CAPÍTULO 5

Contexto de Transação

O contexto de transação (CT), tem por objetivo fornecer ao desenvolvedor

WEB, um mecanismo para guardar grandes quantidades de valores para uso

posterior nos programas. Seria o equivalente a passar temp-tables como

parâmetros de um programa para outro em programas que trabalham por

etapas como wizards no ambiente Cliente/Servidor. Esta solução foi criada

para que pudéssemos permitir para Web Browsers manterem conjuntos

grandes de informações temporárias em processos que exijam várias etapas

para serem executados. Precisamos de um mecanismo que permita o nosso

programa CGI (.w) receba dados de um web-browser e realize algum processo

sobre estes dados guardando-os para uso futuro e possa devolver uma resposta

ficando no aguardo por uma confirmação do usuário ou outro conjunto de

dados. No momento em que esta confirmação for feita, os dados que foram

guardados de forma temporária são transferidos para as devidas tabelas do

produto. Exemplo:

desmembramento de bens (usa um wizard e pede um conjunto de dados

que só são gravados no banco de dados do produto quando todo o processo

está completo, ou seja, o usuário usa vários formulários HTML e só

confirma a gravação no último deles);

entra de lote e capa de lote, onde a capa de lote não pode existir sem os

itens do lote.

Normalmente, usado para guardar valores de temp-tables entre etapas de um

processo interativo.

O uso do CT deve ser exclusivamente na parte de interface. Os BO´s não

devem acessar a API de contexto de transação. O motivo é que o CT usa

Descrição

62

mecanismos que são específicos. O acesso a tabela de CT deve ser feito

exclusivamente pela API wu-transacao.

o método setTransacao para indicar que este quando o valor passado como

parâmetro para ser setado não existir na tabela de transação este será

criado;

o método getTransacao quando não encontra o registro que o usuário tenta

recuperar retorna branco. Para verificar se o registro está em branco na

base de dados ou não existe pode-se usar o método getTransacaoStatus

que irá retornar false quando a informação não existir.

Funcionamento

Para possibilitar o processo de controle de transação e manter informações

persistentes, mesmo após o .w ter encerrado e devolvido dados para o cliente

(Web Browser) optou-se por manter do lado server uma tabela que mantém as

informações temporariamente.

Como as informações referentes a transação estão localizadas em tabelas do

banco de dados o programa .w precisa instanciar a API wu-contexttrn.p para

poder acessar os valores, evitamos desta forma que haja embutido no.w

acessos ao banco. Para que a API possa gravar informações de contexto é

necessário definir um TOKEN que irá indicar a transação e a qual tabela a

transação se refere. Observando que um token (transação) pode ser usado para

várias tabelas. O token da transação deve ser gravado no Contexto de Sessão.

Guardando uma transação para uso futuro

O programa .w que irá precisar que a transação seja persistente deve

armazenar no contexto um token que identifique a transação.

Quando o cliente vai usar ou criar dados de transação ele deve antes de mais

nada definir o token da transação chamando o método setToken e logo em

seguida definir a tabela/processo setNomTabela que irá ser usado.

Devemos observar no entanto que se o cliente .w ainda não possuir um token

para tratamento de transação ele deve requisitar um fazendo uma chamada a

getToken. Gravação de novas informações é feita através de chamadas ao

método createNewTransacao que recebe como parâmetro o campo a ser

gravado, um indicador de seqüência e um valor, notamos que o campo

seqüência é extremamente útil quando gravamos campos extent ou quando

Métodos

CAPÍTULO 5 Contexto de Transação 63

estamos gravando relacionamentos de uma tabela, por exemplo pedido e itens

do pedido, onde cada item do pedido possuiria sua própria seqüência.

Usando uma transação

O processo de busca a partir de um .w é extremamente simples, sendo

constituído apenas pelas tarefas de:

1. O .w recuperar o token.

2. É instanciada a API de transação.

3. O método setToken da API é chamado recebendo o token que foi

recuperado.

4. A tabela deve ser setada.

O método getTransacao da API é chamado.

Gravando a transação

RUN settoken IN h-transacao (input v-token).

RUN setNomtabela IN h-transacao (input “meuprog-bem”).

RUN createNewTransacao IN h-transacao (input “bm-codigo”,

input i-seq, input (W_bm_codigo: screen-value)).

RUN createNewTransacao IN h-transacao (input “bm-indice”,

input i-seq, input (w_bm_indice:screen-value)).

RUN createNewTransacao IN h-transacao (input “descricao”,

input i-seq, input (w_descricao:screen-value)).

RUN createNewTransacao IN h-transacao (input “gb-codigo”,

input i-seq, input (w_gb_codigo:screen-value)).

RUN createNewTransacao IN h-transacao (input “di-codigo”,

input i-seq, input (w_di_codigo:screen-value)).

RUN createNewTransacao IN h-transacao (input “sc-codigo”,

input i-seq, input (w_sc_codigo:screen-value)).

Recuperando a transação

RUN settoken IN h-transacao (input v-token).

RUN setNomtabela In h-transacao (input “meuprog-bem”).

Exemplo:

64

DO i-cont-ini = 2 TO i-contador:

create tt-bem.

RUN gettransacao IN h-transacao (input “bm-codigo”,

i-cont-ini, c-retorno).

assign tt-bem.bm-codigo = dec(c-retorno).

RUN gettransacao IN h-transacao (input “bm-indice”,

i-cont-ini, c-retorno).

assign tt-bem.bm-indice = dec(c-retorno).

end.

delete procedure h-transacao.

Recuperando o número da última seqüência

Quando o programa por alguma razão precisar que seja retornardo o número

da última seqüência usada, ele deve fazer isto usando o procedimento de

contexto procedendo conforme especificado a seguir:

1. Criar o primeiro registro no contexto com o nome “lastSequence”.

2. Gravar neste registro o número 1 (um) indicando que um valor já foi

usado.

3. Para cada novo registro criado no contexto incrementar em um o valor de

“lastSequence”.

Sempre que o programador precisar saber qual foi a última seqüência usada ele

pode recuperar “lastSequence”.

65

CAPÍTULO 6

Perfil do Usuário

A função de perfil do usuário, permite determinar se o usuário conectado ao

produto é interno ou externo. Em caso de usuários externos, podemos ainda

verificar se este é Cliente, Representante ou Fornecedor, e temos condições de

saber o seu número de cadastro dentro das tabelas do produto. Caso seja

necessário incluir mais um tipo é necessário que seja aberta FO para ADF.

Funcionamento

Para possibilitar o processo de definição do perfil do usuário (interno /

externo) foi desenvolvido um programa cliente servidor para cadastro do perfil

do usuário, este programa é executado a partir do programa de cadastro do

usuário (sec000aa.w). O usuário pode ser indicado como sendo do tipo

“Nenhum, Cliente, Fornecedor, Representante”, estes itens correspondem aos

valores 1, 2, 3, 4 que, estão definidos no include uninc/i01un178.i que pode ser

usado conforme técnicas de desenvolvimento cliente servidor.

Uso do perfil em programas WEB

Para usarmos o perfil nos programas WEB temos disponível no include wi-

vglob as variáveis:

v_ind_perfil_usuario - variavel char que contém um número informando o

número do perfil do usuário;

v_cod_ext_perfil_usuario - contém o código que relaciona o usuário com a

entidade que ele representa.

Se o v_ind_perfil_usuario contém 2, o usuário é um cliente e o código deste na

tabela de cliente está gravado na variável (v_cod_ext_perfil_usuario).

Descrição

66

Incluindo novos tipos no perfil

Novos tipos podem ser incluídos alterando-se o include uninc/i01un178.i esta

alteração deve ser feita pelo ADF, ou seja, é necessário abrir FO para o grupo

ADF.

Informações Gerais

Para verificar os valores já disponíveis e a que número eles estão associados

pode-se verificar o conteúdo do include uninc/i01un178.i.

Onde usar

Deve ser usado na interface e nunca nas BO´s que devem receber esta

informação como um parâmetro e processá-la conforme necessário,

normalmente, definindo restrições de navegação ou de operações que alterem

o conteúdo da base de dados.

Um exemplo de uso do perfil de usuários é a consulta de pedidos. Dentro da

empresa um usuário pode consultar todos os pedidos, mas um representante

(usuário externo), somente pode ver os pedidos que pertencem a ele. Neste

caso deveremos ter a seguinte situação:

programa de interface apenas identifica se o usuário externo ou interno

(através das informações do perfil de usuário). Se for externo deve

identificar qual é o representante;

BO de consulta pedidos deve estar preparado para navegar em todos

registros de pedidos (quando for usuário interno) ou navegar apenas numa

faixa de pedidos (quando for o representante). O BO deve receber de

parâmetro o código do representante para então fazer a seleção e abrir a

query específica.

Exemplo

67

CAPÍTULO 7

Consultas Relacionadas

Esta técnica descreve os procedimento para que os programas sempre

mantenham contexto nos registros acessados. Por exemplo: ao consultar uma

nota-fiscal, o usuário poderá ter necessidade de acessar a consulta de clientes.

Ao chamar a consulta relacionada, o programa de consulta de clientes já deve

se posicionar naquele registro de cliente da nota-fiscal que o usuário estava

consultando. Para tanto deve ser aplicada esta técnica descrita aqui.

Esta técnica deve ser usada em conjunto com a técnica de Contexto de Sessão.

Basicamente, teremos o ‘Programa Origem’ que define o contexto do registro

(rowid do registro corrente) e o ‘Programa Destino’ que, ao ser executado

procura um contexto de registro (rowid) e se posiciona neste registro. Um

programa deverá implementar estes dois comportamentos (origem e destino).

não há uma dependência direta entre estes dois programas, os dois

funcionam de forma independente. Ou seja, o programa de consulta de

clientes, independentemente de que o chamou, sempre procura o rowid do

cliente para posicionar-se nele;

o programa origem sempre grava no contexto de sessão, o rowid da tabela

principal do programa e outras que forem necessárias. Por exemplo: o

programa de consulta nota-fiscal grava no contexto de sessão o rowid da

nota-fiscal e do cliente (principal entidade ligada a nota-fiscal);

o programa destino sempre procura no contexto de sessão o rowid de sua

tabela principal e posiciona-se no mesmo. Se algum programa

anteriormente gravou um contexto de sessão o mesmo estará sendo usado

neste momento;

o padrão para o nome da variável de contexto de sessão contendo o rowid

da tabela é:

Definição

Descrição

Considerações Gerais

68

rg-<tabela>

69

CAPÍTULO 8

Uso de páginas de código

Os sistemas da Datasul são desenvolvidos usando a página de códigos ibm850

para fluxos de saída (-cpstream), e também para os caracteres escritos nos

códigos fontes. Optou-se por este padrão por ser a página default do Progress

nas versões anteriores a 8 e a utilizada pelos ambientes em modo caracter. O

padrão adotado pelos navegadores da Web é página iso8859-1, para manter a

compatibilidade com os demais sistemas da Datasul a versão Web deverá estar

com o parâmetro –cpstream ibm850.

A solução encontrada foi a otimização do arquivo web-disp.p do Webspeed,

configurando a saída web para converter a página de códigos para iso8859-1.

OUTPUT {&WEBSTREAM} TO "WEB":U CONVERT TARGET "iso8859-1":U.

Funcionamento

Para perfeito funcionamento da exibição de caracteres acentuados, deve-se

atentar as seguintes regras:

literais em HTML, devem estar em ibm850, verificar via editor do

Progress se esta correto, pois o FrontPage utiliza iso8859-1 ou UTF-8;

todas as literais dentro de fontes, devem estar em ibm850.

Observação : Problemas com código de Página no Combo-box

Descrição

70

Na web a saída é iso8859-1 e os programas e includes estão em IBM-850.

Quando selecionar algum valor no combo e enviar para o servidor poderá

ocorrer algum erro . Em resumo , quando os valores forem jogados para a

WEB deverá ser convertido para iso8859-1 e quando forem dados enviados ao

servidor deverá ser convertido para IBM-850. Os dados que estão na base de

dados estão no formato IBM-850. Para que não ocorra o erro , é necessário

utilizar o codepage-convert .

Segue o código de exemplo :

procedure display-fields:

...

w_ind_tipo_desconto_01 = codepage-convert(string({diinc/i01di272.i 04 tt-

param-bonif.ind-tipo-desconto[01]}),"ibm850","iso8859-1")

...

procedure assign-fields:

...

tt-param-bonif.ind-tipo-desconto[01] = lookup(codepage-convert(get-

value("w_ind_tipo_desconto_01"),session:charset,"ibm850"),{diinc/i01di272.i

03})

...

BUG NO IE 5 :

Quando for feito um get-value de um combo-box , exemplo abaixo , e

aparecer um conjunto de caracteres , em vez de aparecer o ç ou qualquer

caracter especial , a solução é migrar para o IE 5.01 .

Por Exemplo :

{&out} '<script> alert("Teste : ' string(codepage-convert(get-value("w_cb_tipo_nota"),session:charset,"ibm850")) '")</script>'.

Resultado : Diferen&#8225o de Pre&#8225o (Diferença de Preço)

CAPÍTULO 9 Customização de arquivos WebSpeed 71

CAPÍTULO 9

Customização de arquivos WebSpeed

Com a utilização dos templates Web, surgiu a necessidade da criação e

alteração de utilitários customizados no webspeed.

Funcionamento

ARQUIVO LOCALIZAÇÃO TECNOLOGIA CARACTERÍSTICAS

tagmap.dat raiz Webspeed Alterado para incluir as referências as

tag´s criadas pela Datasul (literal, label,

titulo).

web-disp.p web/objects Webspeed Alterado para suportar a conversão entre

as páginas de código imb850 para

iso8859-1

webedit.p web/support Webspeed Alterado para suportar a opção de

desabilitação do campo de acordo com a

especificação da versão 4.0 do HTML.

webinput.p web/support Webspeed Alterado para suportar a opção de

desabilitação do campo de acordo com a

versão 4.0 do HTML

weblist.p web/support Webspeed Alterado para suportar a opção de

desabilitação do campo de acordo com a

versão 4.0 do HTML.

webradio.p web/support Webspeed Alterado para suportar a opção de

desabilitação do campo de acordo com a

versão 4.0 do HTML.

webtog.p web/support Webspeed Alterado para suportar a opção de

desabilitação do campo de acordo com a

versão 4.0 do HTML.

weblabel.p web/support Datasul Criado para suportar tradução de label´s

Descrição

72

de campos através da tag <!--Label -->

que utiliza o utilitário ut-liter.

webliter.p web/support Datasul Criado para suportar tradução de literais

através da tag <!--Literal -->que utiliza o

utilitário ut-liter.

webtitul.p web/support Datasul Criado para recuperar o título cadastrado

no sistema de menus através da tag <!--

Titulo -->.

webtitu2.p web/support Datasul Chamado pelo programa webtitul.p

73

CAPÍTULO 10

Utilitários

WU-GRAF

A API de Gráficos tem como função gerar gráficos para o ambiente WEB.

Para isto, ela utiliza um componente de terceiros KavaChart

(http://www.ve.com/kavachart/) da Visual Engineering Inc.. Este componente

foi construído na forma de um applet Java (programa Java que é executado por

navegadores Java-enabled) que de acordo com os parâmetros recebidos gera o

gráfico desejado.

1. Instancia-se a api em modo persistente.

Ex.: run web/wutp/wu-graf.p persistent set h-graf.

2. Cria-se as seqüências necessárias.

Ex.: run addSequence in h-graf(1, "seq1").

3. Adiciona-se os valores na quantidade necessária.

Ex.: run addValue in h-graf(1, 10.0).

4. Adiciona-se as labels.

Ex.: run addLabel in h-graf(1, "Label 1").

5. Adiciona-se parâmetros desejáveis (opcional).

Ex.: run addParam in h-graf("titleString", "Teste de Gráfico").

6. Executa-se a geração e exibe-se o gráfico.

7. Elimina-se a instância da API.

Definição:

Funcionamento:

74

addSequence (integer seqüência, char descrição): adiciona uma nova

seqüência de valores;

seqüência: número ordinal da seqüência;

descrição: descrição a ser apresentada no gráfico.

addValue(integer seqüência, decimal valor): adiciona um valor a uma

seqüência existente;

seqüência: número de seqüência, na qual, será acrescentado o valor;

valor: valor a ser acrescentado;

addLabel(integer coluna, char label): adiciona uma label para a

coluna/valor;

coluna: numero seqüência1 da coluna;

label: nome da label da coluna correspondente;

addParam(char param, char valor): adiciona um parâmetro qualquer ao

Applet KavaChart;

param: nome do parâmetro a ser passado;

valor: valor a ser setado no parâmetro;

deleteAll(): limpa todos os dados do gráfico;

generate(char tipo, integer width, integer height);

tipo: tipo do gráfico (bar, column, hiLoBar, indBar, stackBar,

stackColumn, area, labelLine, disLine, pie, polar. (Obs.: este

parâmetro é case sensitivo.)

width: largura utilizada pelo applet;

height: altura utilizada pelo applet;

return-value: possui a tag preparada para a geração do gráfico;

Exemplo:

run web/wutp/wu-graf.p persistent set h-graf.

RUN output-header.

{&OUT}

"<HTML>":U SKIP

"<HEAD>":U SKIP

"<TITLE> Teste de Graficos </TITLE>":U SKIP

Métodos Internos:

CAPÍTULO 10 Utilitários 75

"</HEAD>":U SKIP

"<BODY>":U SKIP

.

/* cria as seqüências */

run addSequence in h-graf (1, "seq1").

run addSequence in h-graf (2, "seq2").

/* adiciona os valores */

run addValue in h-graf (1, 10.0).

run addValue in h-graf (1, 7.0).

run addValue in h-graf (1, 2.0).

run addValue in h-graf (1, 15.0).

run addValue in h-graf (1, 10.0).

run addValue in h-graf (2, 11.0).

run addValue in h-graf (2, 2.0).

run addValue in h-graf (2, 6.0).

run addValue in h-graf (2, 2.0).

run addValue in h-graf (2, 12.0).

/* adiciona as labels */

run addLabel in h-graf (1, "11").

run addLabel in h-graf (2, "12").

run addLabel in h-graf (3, "13").

run addLabel in h-graf (4, "14").

run addLabel in h-graf (5, "15").

/* adiciona parâmetros */

run addParam in h-graf ("3D", "").

run addParam in h-graf ("titleString", "Teste de

Grafico").

run addParam in h-graf ("legendlly", "0").

run addParam in h-graf ("titleFont", "Times New

Roman,20,2").

run addParam in h-graf ("xAxisOptions", "gridOn").

run addParam in h-graf ("yaxisOptions", "gridOn").

/* gera a tag e apresenta a saída */

run generate in h-graf ("labelLine", 600, 400).

{&out} return-value.

{&out} "<br><br>".

{&OUT}

"</BODY>":U SKIP

"</HTML>":U SKIP

delete procedure h-graf.

Saída:

76

Principais parâmetros:

Parâmetro Tipo Efeito

titleString String Título do gráfico

titleFont font nome, tamanho e estilo do fonte (default TimesRoman, plain, 12 pt)

titleColor color cor do texto na legenda (default black)

legendOn anything torna a legenda visível

legendOff anything torna a legenda invisível (default)

legendColor color seta a cor de fundo da legenda

legendVertical anything ícones da legenda em lista vertical (default)

legendHorizontal anything ícones da legenda em lista horizontal

legendLabelFont font nome, tamanho e estilo da legenda (default TimesRoman, plain, 12 pt)

legendLabelColor color cor de texto na legenda (default black)

legendllX double posição X do canto inferior esquerdo da legenda (default 0.2)

legendllY double posição Y do canto inferior esquerdo da legenda (default 0.2)

iconWidth double largura do ícone da legenda (default 0.07)

iconHeight double altura do íconde da legenda (default 0.05)

iconGap double espaço entre o ícone e a próxima entrada da legenda (default 0.01)

Applet KavaChart:

CAPÍTULO 10 Utilitários 77

plotAreaTop double topo da área plotável

plotAreaBottom double base da área plotável

plotAreaRight double lado direito da área plotável

plotAreaLeft double lado esquerdo da área plotável

plotAreaColor color cor de fundo da área plotável (default white)

backgroundColor color cor de fundo do gráfico (default white)

3D anything liga o efeito 3D no gráfico

2D anything liga o efeito 2D no gráfico (default)

xDepth integer número de pixels na direção X para efeitos 3D (default 15)

yDepth integer número de pixels na direção Y para efeitos 3D (default 15)

dwellLabelsOn false desabilita labels no popup (default habilitado)

dwellUseLabelString true Usa labels de dados no popup (default off)

dwellUseXValue false Usa valores X no popup (default on)

dwellUseYValue false Usa valores Y no popup (default on)

dwellXString String A string que contém o caracter "#", que será substituída pelo ponto X

(default: "X:#")

dwellYString String A string que contém o caracter "#", que será substituída pelo valor Y

(default: "Y:#")

dwellLabelPrecision integer Número máximo de dígitos significantes para exibir número não

inteiros. (default 2)

dwellLabelFormat 0,1,2 Tipo de formato numérico para as labels popup (0 - nenhum, 1 -

vírgula, 2 - formato europeu, default 1)

78

CAPÍTULO 11

Tratamento de Erros

A tt-bo-erro deve ser usado para passar toda e qualquer informação referente a

ocorrência de erros dentro de BOs ela possui como campos:

i-sequen seqüência em que o erro ocorreu;

cd-erro código do erro;

mensagem mensagem associada ao código;

parâmetro parâmetros que devem ser substituídos na mensagem (este

campo esta em branco quando a mensagem não possui parâmetros).

A criação de erros com parâmetro pode ser feita conforme o exemplo a seguir:

Exemplo (na BO):

{utp/ut-table.i mgadm {&TABLE-NAME} 1}

run utp/ut-msgs.p( input “msg”,

input 146,

input return-value).

create tt-bo-erro.

assign tt-bo-erro.i-sequen = i-seq-erro

tt-bo-erro.cd-erro = 146

tt-bo-erro.mensagem = return-value.

tt-bo-erro.parametro = rowObject.nome-banco.

Para passar mais de 1 parâmetro utilize assim;

tt-bo-erro.parametro = repres.cod-repres + “~~” +

regiao.cod-regiao + “~~” + string(regiao.val-minimo)).

79

CAPÍTULO 12

Validações de Campos na WEB

Em geral, as validações de entrada de dados devem ser feitas no método

'validateFields' da BO. Desta forma, estas validações podem ser aproveitadas

pelo 'validateCreate' e 'validateUpdate' da BO, e também por outros programas

de interface. Observamos que as chamadas das validações devem ser feitas na

local-assign-fields da interface.

A seguir são relacionados os procedimentos para tratar as validações:

Validações de valores obrigatórios

Validações do tipo: campo não por ser zero ou espaços, campo precisa ser

informado devem estar no validateFields do BO, pois são validações

independentes de interface, são regras de negócio.

Validações de campos mandatórios

Estas validações (campo <> ?) devem estar no validateFields nos DBO´s.

Também, são regras de negócio.

Validações de Faixa de Dados

Por exemplo: Campo deve estar entre 1 e 10, campo deve ser "A", "B" ou "C",

também devem estar no validateFields do BO. Em alguns casos implica na

leitura de tabelas do banco de dados.

80

Validações de Integridade Referencial

Validações do tipo can-find, ou seja, o campo deve estar em outra tabela,

devem ser feitas no validateFields dos DBO´s, por motivo claro da

necessidade de leitura de registros.

Validações de Tipo de Dado (wi-datatype.i)

Esta validação deve ser feita diretamente no programa da WEB, pois outras

interfaces (GUI, por exemplo) já fazem esta validação automaticamente. Isto

pode ser feito com o uso do ASSIGN NO-ERROR conforme exemplo abaixo:

assign i-val = integer(x:screen-value) no-error.

if error-status:error then

/* aconteceu algum erro na conversão do tipo de dado */

Isto evita mensagens de erro do Progress referente a tipo de dado inválido (por

exemplo: letras em campos inteiros e decimais, datas inválidas, estouro de

formato).

Para fazer este tipo de validação foi criado o include "wi-datatype.i".

Os tipos de Dados que serão validados são Inteiro, Data, Decimal e Character.

Para isto, deve-se utilizar a include wi-datatype.i. As Validações devem ser

feitas na local-assign-fields.

No wi-datatype.i também são feitas as validações de formato e tamanho do

campo. Se acontecer algum erro este é retornado na tt-bo-erro e ao campo

valido será atribuído o valor "?".

Se não houver erro o campo destino receberá o valor informado.

A seguir um código que demonstra o uso do wi-datatype.i.

Na Definitions:

def var i-seq-erro as integer no-undo.

PROCEDURE local-assign-fields :

IF REQUEST_METHOD="POST":U THEN DO:

DO TRANSACTION NO ERROR UNDO, LEAVE WITH FRAME {&FRAME-NAME}:

create tt-banco.

/* É preciso definir qual é a variável destino, o tipo de dado e

a Origem (variável HTML)

{web/winclude/wi-datatype.i &dst="temp-table.campo"

&type="integer" &org="w_variavel:screen-value"}

*/

CAPÍTULO 12 Validações de Campos na WEB 81

{web/winclude/wi-datatype.i &dst="tt-banco.cod-banco"

&type="integer" &org="w_cod_banco:screen-value"}

{web/winclude/wi-datatype.i &dst="tt-banco.data-1" &type="date"

&org="w_data_1:screen-value"}

{web/winclude/wi-datatype.i &dst="tt-banco.dec-2"

&type="decimal" &org="w_dec_2:screen-value"}

assign

tt-banco.char-1 = w_char_1:screen-value

tt-banco.char-2 = w_char_2:screen-value

/** Fim do Assign **/

/* Se houver algum assign com dados incompatíveis, será criado

registros na tt-bo-erro */

find first tt-bo-erro no-error.

if not avail tt-bo-erro then

case c-param:

when "add" or when "cop" then do:

run validateCreate in h-boad018 (input table tt-

banco, output table tt-bo-erro, output r-chave).

end.

when "mod" then do:

run validateUpdate in h-boad018 (input table tt-

banco, input r-chave, output table tt-bo-erro).

end.

end case.

find first tt-bo-erro

no-lock no-error.

if avail tt-bo-erro then do:

{web/winclude/wi-erapi.i "tt-bo-erro"}

assign hid_oper = c-param

hid_chave:screen-value = string(tt-banco.r-rowid).

RUN dispatch IN THIS-PROCEDURE ('enable-fields':U).

end.

else do:

RUN findRowid in h-boad018 (input r-chave).

RUN getCurrent in h-boad018 (output table tt-

banco).

end.

END./* DO TRANSACTION */

END.

ELSE DO:

END.

/*RUN dispatch IN THIS-PROCEDURE ( INPUT 'assign-fields':U )

*/.

END PROCEDURE.

É utilizado a validação (wi-datatype.i) em caracter. O maxlenght é usado

somente em caracter, pois os outros tipos a include consegue gerar o erro. E

com o Caracter, a include apenas "trunca" a string.

Observação:

82

Em programa de Vá Para , o SWG só gera variáveis do tipo caracter

(Validações) . Por exemplo: c-teste (caracter) . Quando for outro tipo de dado

deverá ser declarada a variável . Seguindo este padrão : Dec-test – decimal

,Dat-test – DATA, Int-test – Inteiros

Atenção : As validações devem ser feitas numa mesma procedure. Pois as

variaveis internas da include não são globais. E depois de executado a

primeira vez , a include não define as variáveis. É aconselhado colocar todas

as validações na assign-local-fields.

CAPÍTULO 13 API de BROWSE – wu-browse.p 83

CAPÍTULO 13

API de BROWSE – wu-browse.p

A API de Browse tem como função gerar tabelas no formato browse para o

ambiente WEB.

8. Instancia-se a api em modo persistente.

Ex.: run web/wutp/wu-browse.p persistent set h-browse.

9. Instancia-se a BO em modo persistente.

Ex.: run adbo/boad018.p persistent set h-boad018.

10. Informa-se a api qual a BO que irá fornecer os dados.

Ex.: run setDataset in h-browse (h-boad018).

11. Adiciona-se os campos a serem apresentados.

Ex.: run addField in h-browse ("nome-banco", "C", "Nome", "left", ?).

12. Configura-se a bo, posiciona-se o registro e define-se a query.

13. Executa-se a geração e exibe-se o browse.

Ex.: run generateBrowse in h-browse.

14. Elimina-se a instância da API.

addEditableField (char chField, char chType, char chTitle, char chAlin, int

iTam) – insere um campo cujo valor pode ser editado.

chField – nome do campo

chType – tipo do campo (C – char, E – decimal, I – integer, D – date,

L – logical)

chTitle – título da coluna

Definição:

Funcionamento:

Métodos Internos:

84

chAlin – alinhamento do campo (Right, Left, Center)

iTam – tamanho do campo de entrada a ser gerado

addField (char chField, char chType, char chTitle, char chAlin, char

chLink) – insere um campo a ser apresentado

chField – nome do campo

chType – tipo do campo (C – char, E – decimal, I – integer, D – date,

L – logical)

chTitle – título da coluna

chAlin – alinhamento do campo (Right, Left, Center)

chLink – link a ser gerado no campo. Utilizar a string &1 no local

onde será substituido pelo rowid do registro corrente.

addFunction (handle hProg, char chFunction, char chTitle, char chAlin) –

insere uma chamada à uma procedure interna cuja assinatura é (input

rowid, output saida) e o resultado do parâmetro saida é inserido na tabela.

hProg – handle do programa que possui a procedure interna

chFunction – nome da procedure interna a ser executada

chTitle – título da coluna

chAlin – alinhamento do campo (Right, Left, Center)

addFunctionTT (handle hProg, char chFunction, char chTitle, char chAlin,

table TEMP-TABLE)

hProg – handle do programa que possui a procedure interna

chFunction – nome da procedure interna a ser executada

chTitle – título da coluna

chAlin – alinhamento do campo (Right, Left, Center)

Temp-Table – Tabela com os campos que vão ser trabalhados . (Segue

exemplo abaixo.

Exemplo :

Definir Temp-Table com os campos que serão utilizados (Campos chaves

da tabela temporária) .

Definitions :

CAPÍTULO 13 API de BROWSE – wu-browse.p 85

def temp-table tt-nome-campos field nomecampo as char

field tipocampo as char .

def var contador as integer no-undo initial 1 .

Na Process-web-request :

run addFunction in h-brwapi

(this-procedure, "geraRow":U, "", "right":U).

create tt-nome-campos .

assign tt-nome-campos.nomecampo = "numero-ordem"

tt-nome-campos.tipocampo = "I" .

create tt-nome-campos.

assign tt-nome-campos.nomecampo = "it-codigo"

tt-nome-campos.tipocampo = "I" .

create tt-nome-campos.

assign tt-nome-campos.nomecampo = "seq-cotac"

tt-nome-campos.tipocampo = "I" .

create tt-nome-campos.

assign tt-nome-campos.nomecampo = "un"

tt-nome-campos.tipocampo = "C" .

run addFunctionTT in h-brwapi

(this-procedure , "geraCheck" , "" , "center", input table

tt-nome-campos ) .

...

PROCEDURE geraCheck:

86

define input parameter c-char2 as char no-undo.

define output parameter c-char as char no-undo.

assign c-char = '<input type="checkbox" name="cbchave' +

string(contador) + '" value="' + string(c-char2) + '">' .

assign contador = contador + 1 .

END PROCEDURE.

PROCEDURE geraRow:

define input parameter r-rowid as row no-undo.

define output parameter c-char as char no-undo.

assign c-char = '<input type="hidden" name="row' + string(contador) +

'" value="' + string(r-rowid) + '">' .

END PROCEDURE.

addInput (char chField, char chType, char chTitle, char chAlin, int iTam)

– insere um campo editável para fins de digitação.

chField – nome do campo, será concatenado com o rowid exeto no

radio

chType – tipo do campo (T – text, C – checkbox, R – radio)

chTitle – título da coluna

chAlin – alinhamento do campo (Right, Left, Center)

iTam – tamanho do campo de entrada a ser gerado

generateBrowse – gera o browse e retorna-o via return-value.

setBorder (int iBorder) – seta a espessura das bordas do browse. Default: 1

iBorder – espessura da borda

setDataset (handle hBO) – seta o handle da bo que será a fonte de dados.

hBO – handle da bo instanciada

CAPÍTULO 13 API de BROWSE – wu-browse.p 87

setForm (logical lOp) – define se a api irá gerar um form ou não. Default:

false

lOp – true ou false se deseja form

setLines (int iLines) – define a quantidade de linhas geradas, 0 – gera

todas as linhas. Default: 10

iLines – número de linhas geradas

setLinkNavigation (char chLink) – define o link a ser utilizado caso haja

navegação

chLink – link para a navegação

setNavigation (logical lOp) – define se a api irá gerar os botões de

navegação. Default: false

lOp – true ou false se deseja navegação

Exemplo:

run adbo/boad018.p persistent set h-boad018.

run web/brwapi/brwapi.p persistent set h-brwapi.

run setDataset in h-brwapi (h-boad018).

run findFirst in h-boad018.

run addField in h-brwapi ("cod-banco", "I", "Banco", "right",

"prog2?param=mod").

run addEditableField in h-brwapi ("cod-febraban", "I", "Febraban",

"right", 2).

run addEditableField in h-brwapi ("nome-abrev", "C", "Abrev",

"left", 10).

run addField in h-brwapi ("nome-banco", "C", "Nome", "left", ?).

run addInput in h-brwapi ("t", "T", "Entrada", "left", 5).

run addInput in h-brwapi ("c", "C", "Quais?", "center", ?).

run addInput in h-brwapi ("r", "R", "Qual?", "center", ?).

run addFunction in h-brwapi (this-procedure, "valorMethod",

"Calculado", "center").

run setNavigation in h-brwapi (true).

88

run setLinkNavigation in h-brwapi ("teste.p?x=x").

run setBorder in h-brwapi (2).

RUN output-header.

{&OUT}

"<HTML>":U SKIP

"<HEAD>":U SKIP

"<TITLE> {&FILE-NAME} </TITLE>":U SKIP

'<link rel="stylesheet" href="/ems20web/padrao.css">'

"</HEAD>":U SKIP

"<BODY>":U SKIP

'<form><input type="submit">'

.

run generateBrowse in h-brwapi.

{&out} return-value.

{&OUT}

'</form>'

"</BODY>":U SKIP

"</HTML>":U SKIP

.

Banco Febraban Abrev Nome Entrada Quais? Qual? Calcula

do

0

Banco de

Teste

teste0x0006584

5

1

Banco do

Brasil

teste0x0012ac0

1

2

Banco de

Teste

teste0x0010948

9

3

Banco da

Gente

teste0x0018ac6

3

Saída:

CAPÍTULO 13 API de BROWSE – wu-browse.p 89

4

Banco do

Nordeste

teste0x00013b2

3

5

Teste Banco

Adriana

teste0x00013b2

4

6

Teste do

Ricardo

teste0x0013ccc

3

7

LCS Banks

teste0x00013c0

1

8

Banco

General

Motors

teste0x00132f0

0

9

1010101010

1010101

teste0x00084e8

5

Exemplo de Recuperação de Variáveis no BROWSE . (SEM O USO DE

JAVASCRIPT). Continuando o exemplo do AddFuntionTT .

No Método POST :

def var conta2 as integer no-undo.

def var conta as integer no-undo .

def var aux-row as char no-undo .

def var aux-un as char no-undo .

assign conta2 = integer(get-value("contador")) .

do conta = 1 to conta2 :

if get-value("cbchave" + string(conta)) <> "" then do :

aux-row = get-value("row" + string(conta)) .

aux-un = get-value("un" + aux-row) .

{&out} "<big><big>" get-value("cbchave" + string(conta))

"</big></big>" .

{&out} ",<big><big>" aux-un "</big></big>" .

aux-un = get-value("preco-fornec" + aux-row) .

{&out} ",<big><big>" aux-un "</big></big><br>" .

end.

90

end.

CAPÍTULO 14 Preferências do Usuário – wu-uspf.p 91

CAPÍTULO 14

Preferências do Usuário – wu-uspf.p

A definição de preferências do usuário consiste em salvar os valores das

opções que o usuário utilizou em determinado programa (normalmente

relatórios). Assim o usuário pode retornar a este mesmo programa e

recuperar estas informações sem precisar digitar tudo novamente (Folders

de Seleção, Parâmetros, Classificação, Digitação, etc. Disponível a partir

do EMS 2.02.

1. Inserir os botões de Salva, Carrega e Elimina as preferências do

usuário no HTML:

parent.panel("NGSACMDUROLHEPWX","WCADSIMP 2.00.00.000");

2. Inserir os campos uspf_pref e uspf_defualt no HTML:

<form method="post"><center>

<INPUT TYPE="HIDDEN" NAME="uspf_pref" VALUE="">

<INPUT TYPE="HIDDEN" NAME="uspf_default" VALUE="">

3. Definir variáveis utilizadas pelas preferências do usuário:

define variable i-pref as integer no-undo.

define variable c-defa as character no-undo.

define variable l-defa as logical no-undo.

4. No início da WEB-REQUEST, incluir a seguinte linha de comando:

run outputHeader.

run output-javascript.

{web/ winclude/wi-rpini.i}

{web/winclude/wi-jscrp.i '' '' '' '' '' '' {&THISNAME}}

assign c-pref = get-value("uspfseq":U).

Definição:

Utilização:

92

5. No método POST, depois da inputFields e da assignFields, incluir a

seguinte lógica:

assign c-pref = get-value("uspf_pref":U).

IF c-pref <> "" THEN DO:

assign c-defa = get-value("uspf_default":U).

if c-defa = "true":U then assign l-defa = true.

run uspfSaveParameters.

assign ab_unmap.uspf_pref = ""

ab_unmap.uspf_default = "".

END.

ELSE DO:

/* Lógica padrão do método POST */

END.

6. Na WEB-REQUEST, antes da enableFields e da outputFields, incluir,

caso não exista, a seguinte lógica:

IF REQUEST_METHOD = "POST":U OR c-pref = "" THEN DO:

RUN displayFields.

END.

7. No método GET, após a displayFields, incluir a seguinte lógica:

RUN displayFields.

if c-pref <> "" then run uspfLoadParameters (false).

else run uspfLoadParameters (true).

8. Criar uma procedure interna com o nome de uspfLoadParameters com

o seguinte código:

{web/winclude/wi-uspfl.i <nome do programa>}

Ex.:

{web/winclude/wi-uspfl.i cd0101}

9. Criar uma procedure interna com o nome de uspfSaveParameters com

o seguinte código:

{web/winclude/wi-uspfs.i <nome do programa>}

Ex.:

{web/winclude/wi-uspfs.i cd0101}

É possível definir que também o conteúdo de um programa de

digitação seja salvo e recuperado a partir das preferências de usuário. Esta

CAPÍTULO 14 Preferências do Usuário – wu-uspf.p 93

implementação consiste em definir alguns pré-processadores. Existem hoje

duas tecnologias para construir programas que se comportem como BOs de

temp-table que são usados nos programas de digitação: Transbo e Virtual

DBO. Parte do procedimento que descreve como fazer para salvar a digitação

nas preferências do usuário se aplica apenas quando se usa Virtual DBO. Os

passos genéricos são os seguintes:

a) Definir no programa que implementa a técnica de preferência o pré-

processador RECUPERADIGITACAO: A este pré-processador deve

estar associado o nome da temp-table de comunicação com o

programa que implementa a BO de tabela temporária (Transbo ou

Virtual DBO). É possível indicar a própria temp-table que já está

sendo usada no programa para recuperar a digitação ( geralmente tt-

digita ), porém, para garantir que esta operação não vá interferir na

lógica do programa, pode-se definir uma outra temp-table igual a já

existente e indicar esta outra no pré-processador.

Ex:

DEFINE TEMP-TABLE tt-digita

/* Temp-table de comunicação */

FIELD it-codigo as CHARACTER

FIELD nrVias as INTEGER

FIELD r-Rowid as ROWID.

DEF TEMP-TABLE tt-digita-rec LIKE tt-digita.

&SCOPED-DEFINE RECUPERADIGITACAO tt-digita-rec

/* Usa outra tabela. Não interfere na lógica do programa */

ou DEFINE TEMP-TABLE tt-digita

/* Temp-table de comunicação */

FIELD it-codigo as CHARACTER

FIELD nrVias as INTEGER

FIELD r-Rowid as ROWID.

&SCOPED-DEFINE RECUPERADIGITACAO tt-digita

/* Usa a mesma tabela. Pode interferir na lógica do programa */

b) Definir o pré-processador TABELADIGITACAO com um nome

para a tabela da BO de temp-table: Este pré-processador somente

precisa ser definido se não for utilizado o nome padrão para esta

temp-table que é tt-digita. Caso tenha sido usado um outro nome, aí

sim é necessário definir este pré-processador com este nome.

Ex: run setTableName in h-handleboTT ("tt-digita":U).

/* Usado nome padrão. Não precisa do pré-processador. */

ou &SCOPED-DEFINE TABELADIGITACAO tt-mydigita

run setTableName in h-handleboTT ("tt-mydigita":U).

94

/* Não usado nome padrão. Pré-processador é necessário. */

Caso se esteja utilizando Virtual DBO no programa de digitação, além

dos passos acima, os seguintes itens também devem ser observados:

Definir o pré-processador DIGITACAOVDBO: A definição deste

pré-processador indica que o programa de digitação trabalha com

a tecnologia de Virtual DBO. Se ele não for definido, se assumirá

que a tecnologia utilizada foi Transbo.

Ex:

&SCOPED-DEFINE DIGITACAOVDBO

Definir os pré-processadores DIGITACAOVDBOINDTIPO,

DIGITACAOVDBOINDCOMP e

DIGITACAOVDBOINDHAND: Estes pré-processadores servem

para indicar como foi definido o comportamento da Virtual DBO

com relação a índices no programa de digitação. Em

DIGITACAOVDBOINDTIPO deve ser indicado o tipo de índice,

em DIGITACAOVDBOINDCOMP o complemento e em

DIGITACAOVDBOINDHAND o handle ou o valor nulo (?).

Estes pré-processadores apenas precisam ser definidos se no

programa de digitação se usou o comando setIndexType.

Ex:

run setIndexType in h-data (input 1,input "nrVias",input ?).

&SCOPED-DEFINE DIGITACAOVDBOINDTIPO 1

&SCOPED-DEFINE DIGITACAOVDBOINDCOMP "nrVias"

&SCOPED-DEFINE DIGITACAOVDBOINDHAND ?

Definir o pré-processador DIGITACAOVDBOORDEM: Este pré-

processador deve ser definido se no programa de digitação foi

informada uma ordem para a recuperação dos registros. Seu valor

deve ser o mesmo utilizado no método setQuerySort.

Ex:

run setQuerySort in h-data (input 2).

&SCOPED-DEFINE DIGITACAOVDBOORDEM 2

A documentação sobre o uso de Virtual DBO pode ser encontrda em

X:\ferramentas\ddk2000\Manual\ManualUsoDBO.doc

CAPÍTULO X... Considerações Gerais 95

CAPÍTULO X...

Considerações Gerais

Includes do EMS 2 GUI

Sempre que possível usar includes do EMS 2 GUI no produto Web, isto é,

extremamente recomendável por gerar reaproveitamento, como pode haver

casos onde seja necessário verificar dentro do include se o produto rodando

está na sua versão Web ou não deve-se usar a função Proversion do Progress

conforme a seguir:

if INDEX(proversion, "WebSpeed") = 0 then

/* comandos gui */

else

/* comandos para web */

Como esta decisão é tomada em tempo de execução, o usuário deve atentar

para que dentro do bloco de lógica não existam comandos específicos do

WebSpeed.

Label dos Campos no HTML´s

O label dos campos deve estar sempre no formato:

LABEL:<ESPAÇO>CAMPO

96

Controles para a não utilização de cache

Para que os programas não utilizem o cache do browser, o que pode acarretar

inconsistência dos dados, deve ser verificado se nos .HTML, existem as

seguintes TAGS entre o <HEAD> e o </HEAD>:

<meta http-equiv="Cache-Control" content="No-Cache">

<meta http-equiv="Pragma" content="No-Cache">

<meta http-equiv="Expires" content="0">

Inclusão recursiva

Para implementar a inclusão recursiva nos programas WEB (somente para as

novas templates) deve-se incluir o seguinte pré-processador:

&GLOBAL-DEFINE RECURSIVE_ADD YES

Fechamento de janelas de inclusão de pai

Para que os programas que utilizam a template de cadastro de pai simples ou

complexo, fechem corretamente após a inclusão, deve-se atentar para os

seguintes pré-requisitos:

Deve conter o pré-processador &ttTableFather;

Deve conter o pré-processador &NFACON;

Não deve conter o pré-propcessador &CADSON.

Validações em Geral

As validações em HTML se resumem a tipo de dado, tamanho de campo,

formato de data. Ou seja, validações simples que não dependam de regras de

negócio.

CAPÍTULO X... Considerações Gerais 97

Validação de Inicial e Final

Estas validações devem seguir o mesmo padrão do ambiente cliente/servidor

que não valida isto. Caso o usuário informe o inicial maior que o final, o

desenvolvedor pode fazer esta validação na BO e retornar o erro, ou

simplesmente não fazer nada (é claro que, a faixa não vai encontrar registros).

Desta forma não é preciso fazer o controle na interface que fica mais simples.

Validações em Relatórios

Após solicitar os dados e antes de gerar o pedido RPW, se houver necessidade

deve-se fazer validações. Estas validações devem ser feitas no programa

Progress. Se forem validações específicas da tabela deve-se usar o BO.

A regra geral é não gravar erros no pedido de execução do RPW.

Lembrando que o recurso muito comum nos relatórios GUI de habilitar e

desabilitar campos na interface não deve ser usado, ou seja, devemos deixar

tudo habilitado e fazer a validação depois.

Desenvolvimento Específico/Customizações

Para o desenvolvimento de aplicações específicas e/ou customizações (AEC)

na WEB, deve-se procurar observar algumas regras para isto:

deve-se colocar as tabelas AEC em um banco de dados separado ao

produto EMS;

os programas do AEC devem ser criados em diretório separado do

produto;

programas que referenciam somente tabelas AEC devem ficar no diretório

específico da customização;

programas que existem no EMS e são necessários para a AEC, mas que

ainda não foram convertidos para WEB, devem ser convertidos e devem

ficar como parte do produto EMS. O motivo é que estes programas

98

deverão ser convertidos futuramente para WEB. Fica a cargo das equipes

de desenvolvimento definir qual das duas equipes (EMS ou AEC) deve

fazer esta conversão;

novos programas necessários para AEC que referenciam tabelas do

produto EMS devem ser criados e devem ficar no diretório do AEC, já que

os mesmos não serão utilizados no EMS.

Como fazer links para detalhe do registro

os links devem ser criados logo abaixo do Título do Programa;

a sintaxe do link é a seguinte:<a

href=”javascript:funcaoJavaScript()”>Nome do Detalhe</a>

A função JavaScript abrirá uma outra página com o detalhe do registro.

function funcaoJavaScript () {

window.open(“wcr0703b.p?chave=” + document.forms[0] Exemplo:

CAPÍTULO X... Considerações Gerais 99

.elements[0].value, “NomedaFrame”,

“top=0,left=0,width=500,height=450,scrollbars=no,toolbar=no,loca

tion=no, directories=no,status=no,resizable=yes”);

Como habilitar/desabilitar campos nos HTML´s

Não deve ser habilitado e desabilitado campos 'on line'. Ou todo HTML está

habilitado ou está desabilitado. O objetivo disto é facilitar a programação.

Utilizar a área do label do radio-set e check-box para click do mouse

Para Radio-Sets:

<label for=”valor1”><input type=”radio” name=”campo”

value=”valor” id=”valor1”>

Descrição </label>

Para CheckBox:

<label for=”valor1”><input type=”checkbox” name=”campo”

value=”valor” id=”valor1”>

Descrição </label>

<html>

<body topmargin=”0” leftmargin=”0”>

<form method=”post”>

<center>

<label for=”opcao1”><input type=”radio” name=”campo0”

value=”1” id=”opcao1”> Valor1</label>

<label for=”opcao2”><input type=”radio” name=”campo0”

value=”2” id=”opcao2”> Valor2</label>

<br>

<label for=”opcao3”><input type=”checkbox” name=”campo1”

value=”ON” id=”opcao3”> CheckBox </label>

<label for=”opcao4”><input type=”checkbox” name=”campo2”

value”ON” id=”opcao4”> CheckBox </label>

</center>

Sintaxe

Exemplo:

100

</form>

</body>

</html>

Botão de zoom para tabela estrangeira

O botão de zoom padrão deve ter a imagem wimages/ii-zoom.gif.

Como selecionar um Texto via JavaScript

Um exemplo clássico da utilização de seleção é a cópia de um registro.

Quando um registro é copiado, geralmente, é modificado algum valor. E para

facilitar ao usuário, deve-se implementar a seleção. Assim, o usuário não

precisa selecionar o texto e pressionar a tecla DEL. O texto já vem selecionado

e assim o usuário ganha mais agilidade no preenchimento do formulário.

Basta utilizar a função select(). Exemplo:

document.forms[0].nome.select().

Para maiores detalhes, observe o exemplo a seguir:

Onde utilizar

Como utilizar

CAPÍTULO X... Considerações Gerais 101

Exemplo em HTML:

<html>

<script>

function ChamaFunção() {

document.form[0].elements[0].select();

}

</script>

<body>

<form>

<input type=”text” name=”ricardo” value=”Seleção de Texto”

size=”20”>

<input type=”button” name=”acao” value=”Teste”

onClick=”javascript:ChamaFuncao()”>

</form>

</body>

</html>

102

Como definir nomes das FRAMES(Janelas):

A definição de uma regra para nomes de frames é necessária para que não

ocorra erros de JavaScript no IE (Internet Explorer). Por exemplo: Se um

usuário abrir uma consulta Pai X Filho e abre a tela de cadastro Pai e por

algum motivo, ele clica no menu principal (deixando a janela do cadastro

aberta). O usuário entra em outro programa Pai X Filho e clica no cadastro do

Pai. Acontecerá um erro de JavaScript no IE, pois o IE não consegue mudar o

tamanho da janela (pois, os nomes das Janelas são iguais). A solução para este

problema é criar frames com nomes diferentes.

Consulta Pai X Filho filho

Função ChamaInclusao - Nome do programa + i

Por exemplo: wap0005i

Função ChamaModificação - Nome do programa + m

Por exemplo: wap0005m

Consulta Pai X Filho pai

Quando o parâmetro for ADD, MOD, COP, a consulta abre outra janela.

É o nome desta janela (Frame) deve ser:

Nome do Programa + p Por exemplo: wap0005p

Para outros casos deve-se utilizar assim:

Nome do Programa + N

Por exemplo: wap00051

Como mapear variáveis entre o HTML e o programa Progress manualmente (sem utilizar o Appbuilder)

O primeiro passo, deve-se apagar o <arquivo>.off

Neste exemplo, estaremos acrescentando mais uma Variável (ou Campo) no

programa WebSpeed. O processo para eliminar alguma variável é semelhante

(deve-se trocar acrescentar por eliminar).

CAPÍTULO X... Considerações Gerais 103

No arquivo HTML - Acrescentar um elemento do formulário.

Exemplo

...

<tr>

<th align=”right” class=”linhaForm” nowrap><!--label

name=”mgadm#banco#cod-banco#1” -->:</th>

<td class=”linhaForm” align=”left” nowrap>

<input type=”text” size=”3” name=”w_cod_banco”>

<!--label name=”mgadm#banco#nome-banco#1” -->

<input type=”text” size=”20” name=”w_nome_banco”>

</td>

</tr>

...

No arquivo .W

Exemplo

...

&Scoped-Define ENABLED-OBJECTS ~

w_cod_banco ~

ww_nome_banco ~

w_nome_banco

...

&Scoped_Define DISPLAYED-OBJECTS ~

w_cod_banco ~

ww_nome_banco ~

w_nome_banco

...

DEFINE VARIABLE w_cod_banco AS CHARACTER FORMAT “X(256)”

VIEW-AS FILL-IN

SIZE 3 BY 1 NO-UNDO.

DEFINE VARIABLE ww_nome_banco AS CHARACTER FORMAT “X(256)”

VIEW-AS FILL-IN

SIZE 20 BY 1 NO-UNDO.

DEFINE VARIABLE w_nome_banco AS CHARACTER FORMAT “X(256)”

VIEW-AS FILL-IN

SIZE 20 BY 1 NO-UNDO.

DEFINE FRAME Web-Frame

104

w_cod_banco SKIP

ww_nome_banco SKIP

w_nome_banco SKIP

WITH NO-LABELS.

PROCEDURE htm-offsets:

...

RUN htm-associate IN THIS-PROCEDURE

(“w_cod_banco”:U,”w_cod_banco”:U,w_cod_banco:HANDLE

IN FRAME{&FRAME-NAME}).

RUN htm-associate IN THIS-PROCEDURE

(“mgadm#banco#nome-

banco#1”:U,”ww_nome_banco”:U,ww_nome_banco:HANDLE IN FRAME

{&FRAME-NAME}).

RUN htm-associate IN THIS-PROCEDURE

(“w_nome_banco”:U,”w_nome_banco”:U,

w_nome_banco:HANDLE IN FRAME{&FRAME-NAME}).

... End Procedure.

Note na Procedure htm-offsets que o nome do campo (literal) deve ser sempre

associada com um ‘w’ a mais. No nosso exemplo, estamos mapeando o nome

do banco. Então, o nome da variável associada a literal deve ser

ww_nome_banco.

Literais, Títulos e Labels de Banco (<!--label name=”mgadm#banco#nome-banco#1” -->,<!--literal name=”Teste_de_literal#*” e <!--

titulo name=”ap0000”-->) também, são mapeados. O não mapeamento

destas literais e Títulos aplicarão em erro de off.

Blocos de Assign e funções do Webspeed

Os "blocos de assign", utilizados para ganharmos performance, estão

apresentando problemas quando neles se econtram comandos "get-value" e

"get-cookie". Resumindo, cada "get-" deve ter seu único "assign", ex:

assing c-rep = repres:screen-value

c-cli = emitente.cod-emitente

c-nome = emitente.nome-abrev.

Atenção

CAPÍTULO X... Considerações Gerais 105

assing c-emp = get-value("c-empresa-ramo").

assing c-user = get-cookie("ck-usuario").

O exemplo acima representa o modo correto para programação dos assign,

caso contrário pode ocorrer o seguinte erro:

Compiling xxx0010e.w...

Attempt to reference an user defined function 'get-value' in an

ASSIGN

type statement after an assignment to key field

'tt-cotacao-item-cex.cod-emitente-desp'. (7955)

** Could not understand line 667. (196)

Lembramos o uso de cookie não faz parte da nossa metodologia de

desenvolvimento. Favor ler sobre a técnica de manutenção de contexto.

Como faço para retornar o nome do Banco, se a minha tabela é de Conta

corrente e só tenho o Código do Banco?

(para programas de Zoom, Pesquisa, Filho)

Definitions

/*

Criar função para retornar um String e passando como parâmetro o

código do Banco.

/*

&global-define conteudo2 fn-nome-banco(string(tt-cta-corrente.cod-

banco))

--------

FUNCTION fn-nome-banco RETURNS CHARACTER (INPUT p-cod-banco AS CHAR):

RUN adbo/boad018.p PERSISTENT SET h-boad018.

RUN FindNomeBanco in h-boad018(input p-cod-banco, output w-c-

nome-banco).

DELETE PROCEDURE h-boad018.

RETURN (w-c-nome-banco).

END FUNCTION.

Programa de filho chamando um outro programa de Pai x Filho

106

O único problema de um programa Filho chamar um outro programa

Pai x Filho é se o programa 1 passar um ROWID ou até mesmo algumas

chaves . Pois não é possível fazer isto através da passagem de parâmetros .

http://localhost/scripts/cgiip.exe/WService=ems20web/web/men/wrun.w?prog

ram=web/XXp/wXX000.w?rowid=0x032445 (Isto Não é Válido)

Infelizmente não é possivel utilizar o exemplo acima . Pois a passagem

de parâmetro na WEB não é recursivo . O Browser entende tudo como um

único parâmetro .

Para isto , é necessário criar um terceiro programa . A estrutura de navegação

ficaria assim :

WXXFilho.w -> wXXgrava.p -> OutroPaixFilho.w .

O programa Filho deverá chamar um programa que irá gravar no

contexto as chaves e depois de feito chamará o outro programa de Pai x Filho .

Quando a nomeclatura do programa , deverá ser adicionado um sufixo

. Este sufixo deverá ser uma letra .

Segue exemplo do Programa que Grava o Contexto (Poderá ser utilizado este

código para fazer o programa. Lembrando apenas que o Programador deverá

fazer os ajustes necessário para a criação do contexto e declarar o nome do

programa que será chamado ) :

&ANALYZE-SUSPEND _VERSION-NUMBER WDT_v2r1 Web-Object

&ANALYZE-RESUME

&ANALYZE-SUSPEND _CODE-BLOCK _CUSTOM Definitions

/*------------------------------------------------------------------

Author :

Created :

---------------------------------------------------------------------*/

def var h-prog as handle.

def var c-token as char no-undo.

&ANALYZE-RESUME

&ANALYZE-SUSPEND _PREPROCESSOR-BLOCK

&Scoped-define PROCEDURE-TYPE Web-Object

&ANALYZE-RESUME

CAPÍTULO X... Considerações Gerais 107

&ANALYZE-SUSPEND _PROCEDURE-SETTINGS

&ANALYZE-RESUME _END-PROCEDURE-SETTINGS

&ANALYZE-SUSPEND _INCLUDED-LIBRARIES

{src/web/method/wrap-cgi.i}

&ANALYZE-RESUME _END-INCLUDED-LIBRARIES

&ANALYZE-SUSPEND _CODE-BLOCK _CUSTOM "Main Code Block"

ON CLOSE OF THIS-PROCEDURE

RUN dispatch ('destroy':U).

RUN process-web-request.

IF NOT THIS-PROCEDURE:PERSISTENT THEN RUN dispatch ('destroy':U).

&ANALYZE-RESUME

&ANALYZE-SUSPEND _CODE-BLOCK _PROCEDURE output-header

PROCEDURE output-header :

output-content-type ("text/html":U).

END PROCEDURE.

&ANALYZE-RESUME

&ANALYZE-SUSPEND _CODE-BLOCK _PROCEDURE process-web-request

PROCEDURE process-web-request :

{web/winclude/wi-vglob.i}

RUN output-header.

def var h-prog as handle no-undo.

def var c-token as char no-undo.

assign c-token = get-cookie("SessionContextToken":u).

run web/wutp/wu-sessao.p persistent set h-prog.

run setToken in h-prog (c-token).

108

run createNewContext in h-prog ("empresa":u, get-value("empresa")

) .

run createNewContext in h-prog ("idioma":u, get-value("idioma")

).

delete procedure h-prog.

assign irpara="wXX000.w" .

{&out}

'<HTML>':u SKIP

'<body>':u Skip

'<big><center>':u skip

'Salvando Contexto ...'

'</center></big>':u skip

'</body>':u skip

.

{&out}

'<script language=javascript>':u skip

' ~{':u skip

' window.open("' + appurl + '/web/wrun.w?program=' irpara ',

"prgWindow","top=0,left=0,width=" + lar + ",height=" + alt +

",scrollbars=no,toolbar=no,location=no,directories=no,status=no,resizabl

e=no")~; ':u skip

' ~}':u skip

'</script>':u skip

'</HTML>':U SKIP

{&end}

END PROCEDURE.

&ANALYZE-RESUME

CAPÍTULO X... Considerações Gerais 109

Selecionar , Inverter e Desmarcar CHECKBOX via JavaScript

O exemplo abaixo é um documento HTML com código Javascript ,

feito para marcar , inverter e desmarcar qualquer checkbox do formulário

selecionado .

Inserir no seu programa a função javascript (Em Azul) . Esta

função é genérica .

A chamada da função JavaScript (Geralmente utiliza-se botões)

encontra-se neste exemplo nos botões (Em Vermelho) .

Analisando a função seleciona(formulário, opção) .

* Formulário (Valor Inteiro) – Corresponde ao número do

formulário que deve ser utilizado . Lembre-se : No

JavaScript o valor 0 (zero) significa o primeiro

formulário

* Opção (Valor Inteiro)

Opção = 1 – Seleciona Todos

Opção = 2 – Desmarca Todos

Opção = 3 – Inverte

<html>

<head>Exemplo - Selecionar CHECKBOX </head>

<script language="JavaScript">

function seleciona(formulario,numero) {

for (var i=0;i<document.forms[formulario].elements.length;i++) {

var e = document.forms[formulario].elements[i];

if (numero == 1) {

e.checked = true ;

}

if (numero == 2) {

e.checked = false ;

}

if (numero == 3) {

e.checked = !e.checked;

}

}

}

110

</script>

<body>

<form>

<input type="button" name="todos" onClick="seleciona(0,1)"

value="Todos">

<input type="button" name="nenhum" onClick="seleciona(0,2)"

value="Nenhum">

<input type="button" name="inverte" onClick="seleciona(0,3)"

value="Inverte">

<br><br>

<input type="checkbox" name="item1"> 1. Item <br>

<input type="checkbox" name="item2"> 2. Item <br>

<input type="checkbox" name="item3"> 3. Item <br>

<input type="checkbox" name="item4"> 4. Item <br>

<input type="checkbox" name="item5"> 5. Item <br>

<input type="checkbox" name="item6"> 6. Item <br>

<input type="checkbox" name="item7"> 7. Item <br>

<input type="checkbox" name="item8"> 8. Item <br>

<br>

</form>

</body>

</html>

Como trazer em relatórios o servidor default do usuário

Programas de relatório construídos com uma template mais antiga não

trazem automaticamente no campo Servidor de Execução o servidor default

para o usuário corrente. Para implementar esta funcionalidade basta seguir

estes passos:

Definir um handle para a BO unbo/boun135.p se ele ainda não estiver sido

definido;

Definir uma variável char que receberá o código do servidor de execução

padrão do usuário;

CAPÍTULO X... Considerações Gerais 111

Definir uma varável char que receberá a descrição do servidor de execução

padrão do usuário se esta informação for desejada;

Rodar a BO unbo/boun135.p persistentemente se isto ainda não estiver

sido feito;

Rodar dentro da procedure display-fields o método getServidUsuarDefault

na BO unbo/boun135.p e testar o retorno.

Se o rotorno for igual a OK, rodar o método getCharField na BO passando

como parâmetro o valor “cod_servid_exec” e a variável que irá conter o

código do servidor de execução padrão do usuário. Em seguida, associar

ao campo de tela Servidor de Execução o valor que a variável recebeu no

método anterior.

Sendo o retorno de getServidUsuarDefault igual OK, caso se deseje

também a descrição do servidor, rodar o método getCharField na BO

passando como parâmetro o valor “des_servid_exec” e a variável que irá

conter a descrição do servidor de execução padrão do usuário. Em seguida,

associar ao campo de tela relativo a descrição do servidor de execução o

valor que a variável recebeu no método anterior.

Caso tenha-se incluído uma instância da BO unbo/boun135.p, removê-la.

def var h-boun135 as handle no-undo.

def var c-cod-servid-exec as char no-undo.

def var c-desc-servid-exec as char no-undo.

RUN unbo/boun135.p persistent set h-boun135.

RUN getServidUsuarDefault IN h-boun135.

if return-value = "OK" then do:

RUN getCharField IN h-boun135

("cod_servid_exec":U, output c-cod-servid-exec).

assign w_cod_servid_exec:screen-value

in frame {&frame-name} = c-cod-servid-exec.

RUN getCharField IN h-boun135

("des_servid_exec":U, output c-desc-servid-exec).

assign w_desc_servid_exec:screen-value

in frame {&frame-name} = c-desc-servid-exec.

end.

Exemplo:

112

DELETE PROCEDURE h-boun135.

Como acrescentar um botão “Implantar” no Zoom

O Botão “Implantar” não existe por padrão nos programas Web. Isso

se deve principalmente ao fato de que não existem programas de cadastros

correspondentes para Web. Quando necessário o uso deste botão, os seguintes

passos devem ser seguidos:

Alterar a procedure “process-web-request”, colocando a geração do botão

“Implantar”. O botão deverá executar o programa de manutenção

correspondente, em uma janela separada. O código deve estar logo depois

da chamada a procedure “generateBrowse”. Deve ser parecido com o

listado abaixo:

RUN generateBrowse IN h-brwapi.

{&OUT} return-value.

/* Início da codificação do botão Implantar */

{&OUT}

'<table align="center">':U SKIP

' <tr>':U SKIP

' <td align="center">':U SKIP

' <input type="button" name="implanta" value="Implantar"

OnClick="javascript:window.open(~'':U

HostURL + AppURL +

'/web/men/wrun.w?program=web/wCustomer01.w~', ~'_blank~')">':U

SKIP

' </td>':U SKIP

' </tr>':U SKIP

'</tabble>':U SKIP

'</form>':U SKIP

'</body>':U SKIP

'</html>':U SKIP

.

/* Fim da codificação do botão “Implantar” */

delete procedure h-brwapi.

CAPÍTULO X... Considerações Gerais 113

Utilizando Help na WEB

Nos programas Web não se faz necessário definir qualquer

código para fazer a exibição de help. A tarefa de exibir o help nos

programas Web é realizada pela include wi-jscrp.i,que já faz parte do

padrão de todos os templates.