Mini tutorial mod_harbour

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

Pessoal, estou estudando mod_harbour e vou postar algumas observações que fiz aqui.

Pré-requisitos :
* Baixar e instalar o mod_harbour no xampp windows
* Um pouco de HTML (CSS Bootstrap é recomendável, mas zipei todos os exemplos, de modo que dá pra entender)

O Itamar postou um material aqui tb https://pctoledo.org/forum/viewto ... =5&t=24242

O site mod_harbour tem um wiki : https://github.com/FiveTechSoft/mod_harbour/wiki

O tutorial é bem básico, para quem não está familiarizado com linguagens web.
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

O objetivo desse tutorial é ensinar a construir
um grid simples usando :

(1) HTML5
(2) CSS (Bootstrap)
(3) ADO (MSAccess)

Pré-requisitos:

(1) Conhecimentos básicos (bem básicos) de HTML5
(2) mod-harbour instalado em um servidor local (usei o xampp)
(2.1) Para instalar o mod-harbour no windows acesse as instruções no link oficial :

https://github.com/FiveTechSoft/mod_har ... dows-Xampp

Em anexo um zip com o nosso ponto de partida. Ele tem uma página HTML simples com a biblioteca bootstrap.

PS: A ideia inicial era criar com exemplos em SQLMIX + SQLite, mas não foi incluída na compilação.
ex01.zip
(49.65 KiB) Baixado 413 vezes
2020-08-12_212926.png
2020-08-12_212926.png (11.3 KiB) Exibido 50944 vezes
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

O objetivo dessa etapa é colocar o código HTML do passo anterior
em um arquivo prg. Só isso.

Apenas coloquei o conteúdo do HTML dentro do comando TEMPLATE ... ENDTEXT

Código: Selecionar todos

function main

TEMPLATE  // <-------------------------

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="Vlademiro">
    <title>Sistema </title>

    <!-- Bootstrap core CSS -->
	<link href="css/bootstrap.min.css" rel="stylesheet">

  </head>
  <body>

<main role="main" class="container">

  
  <h1>Tutorial de Mod-Harbour + Grid</h1>
  <p class="lead">Ponto de partida</p>
  

</main><!-- /.container -->
</body>
</html>

ENDTEXT  // <----------------------------------

return nil
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

O objetivo dessa etapa é enviar argumentos para o seu HTML

Como passar argumentos para o TEMPLATE ?

Use PARAMS :

Código: Selecionar todos

function main

local cMsg := "Mensagem para o usuário"
local cMsg2 := "Mensagem para o usuário (modelo 2)"


TEMPLATE PARAMS cMsg, cMsg2

<!doctype html>
<html lang="en">
Para exibir esses comandos faça assim :

Código: Selecionar todos


<?prg return cMsg?>

Não adianta fazer como nos scripts PHP ou ASP. O exemplo abaixo não vai funcionar.

Código: Selecionar todos


   <div class="alert alert-warning" role="alert"><?prg Qout( cMsg ) ?></div>
    <div class="alert alert-primary" role="alert"><?prg ?? cMsg2 ?></div>
  
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

Exemplo de erro!!


Essa etapa mostra uma diferenças básicas entre o mod_harbour e os scripts php ou asp.

O código abaixo vai gerar um erro.

Código: Selecionar todos

<?prg if nFlag == 1 ?>  
   <div class="alert alert-warning" role="alert"><?prg return cMsg?></div>
<?prg else ?>   
    <div class="alert alert-primary" role="alert"><?prg return cMsg2?></div>
<?prg end ?>    
  
Erro gerado :

Código: Selecionar todos


Error: Unclosed control structure 'IF*'
operation: line:3
called from: HB_COMPILEFROMBUF, line: 0
called from: ..\source\exec.prg, EXECUTE, line: 60
called from: ..\source\exec.prg, EXECINLINE, line: 115
called from: ..\source\exec.prg, INLINEPRG, line: 95
called from: pcode.hrb, MAIN, line: 43
called from: HB_HRBDO, line: 0
called from: ..\source\exec.prg, EXECUTE, line: 62

Ou seja, não "quebre" um IF.
E nem qualquer outra estrutura.

Todo trecho entre <?prg ... ?> funcionam como uma função anônima.
Blocos de código extendidos, creio eu.

Ex:
<?prg local a := 10
return a*a ?>


**
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

O objetivo dessa etapa é abrir um arquivo.

Se vc nunca trabalhou com CGI ou extensões do apache (mod_perl, por exemplo)
vc deve achar essa etapa esquisita. Mas esse é um problema comum nesses ambientes.

Quando vc "está" no diretório C:\myapp e deseja abrir um arquivo em C:\myapp\data
Basta referenciar ele do ponto onde você está (path relativo)

USE ( "data\meuarquivo.dbf" ) por exemplo

Mas no nosso caso será necessário especificar o caminho completo.

USE ( "c:\myapp\data\meuarquivo.dbf" )

*

O mod_harbour facilita para você através da função PathBase(), ela retorna o caminho até o local onde o script está.
Note que vc pode passar parâmetros para a PathBase(), assim :

PathBase( "/data" ) --> Caminho até o script + "/data"

As barras de separação são assim mesmo, no padrão *Nix.

Código: Selecionar todos

function main

local cArq := PathBase("/data") + "/clientes.dbf"

    ?? "Abrindo em : " , cArq
    
    USE ( cArq ) SHARED // Use shared por causa do ambiente compartilhado
    DO WHILE .NOT. EOF()
       ? field->nome
       skip
    ENDDO

return nil
*
Nota para usuários *Nix

O Apache2 cria o usuário www-data no grupo www-data.
O arquivo que vc vai abrir precisa ser visível para esse usuário.

chown -R www-data.www-data <pasta dos meus dbfs ou textos>
2020-08-14_124039.png
2020-08-14_124039.png (5.93 KiB) Exibido 50944 vezes
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

O objetivo dessa etapa é criar uma conexão via ADO/ODBC com um banco de dados MSAccess

Caso você esteja usando um windows 7 e não tiver instalado o cliente para MsAccess (64bits),
o exemplo não vai funcionar.

Isso porque esse harbour, distribuido junto com a mod-harbour é um harbour
compilado para arquiteturas 64 bits e o seu ODBC também será o de 64bits.

A Microsoft disponibiliza dois ODBCs, um para cada arquitetura.

No meu caso, o meu windows é o 7 (64bits)

O ODBC 64 bits está em painel de controle, etc.
%systemdrive%\Windows\System32\odbcad32

O ODBC 32 está em %systemdrive%\Windows\SysWoW64\odbcad32 <-- Usado pelo harbour 32 bits (não é esse o caso)

É estranho. Deveria ser odbcad32 e odbcad64, mas não é.

Caso não tenha o cliente ODBC instalado vc deve baixar ele de :
https://www.microsoft.com/en-us/downloa ... x?id=54920

Se não tiver os exemplos não vão funcionar.

**

Essa versão do mod-harbour compilada pode acessar DBF, ADO (todos os bancos, via ODBC) e SQLite.
As demais versões de acesso nativo aos bancos não estão inclusas.
Para vc ter isso (PostgreSQL nativo, MySQL nativo, Firebird nativo, Oracle nativo) você precisa compilar o seu
próprio mod_harbour com um harbour que tenha esses acessos devidamente configurados.

**

Código: Selecionar todos

#define adOpenForwardOnly 0
#define adOpenKeyset 1
#define adOpenDynamic 2
#define adOpenStatic 3
#define adLockReadOnly 1
#define adLockPessimistic 2
#define adLockOptimistic 3
#define adLockBatchOptimistic 4
#define adUseNone 1
#define adUseServer 2
#define adUseClient 3
#define adStateClose 		0

function main

   LOCAL oRs , oCn, cSql
   LOCAL cString := "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=" + PathBase() + "/scott.mdb"
   LOCAL i


   for i = 0 to 25
      ?? hb_Version( i )
   endfor

   oCn := win_oleCreateObject( "ADODB.Connection" ) 
   oCn:ConnectionString := cString
   oCn:Open()
   

	oRs := win_oleCreateObject( "ADODB.Recordset" ) 
	oRs:CursorLocation = adUseClient
	oRs:Open( "SELECT * FROM emp", oCn , adOpenDynamic, adLockOptimistic )
	if oCn:State = adStateClose
		? ('Failed open table EMP')
		Return
	Endif
	if oRs:recordcount > 0
		oRs:Movefirst()
		do while !oRs:eof()
			? oRs:fields("ename"):value
			oRs:movenext()
		enddo
		oRs:Movefirst() // Opcional, retorna para o primeiro registro
	endif

return nil
2020-08-14_124011.png
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

O objetivo dessa etapa é criar um grid em bootstrap e colocar os dados da tabela
no grid

Confesso que fiquei um pouco decepcionado. Eu imaginava um grid no estilo PHP/ASP,
do tipo que fica o código HTML e o da linguagem "convivendo" sem ter que ficar "printando"
comandos HTML com o código PHP ou ASP, mas como as minhas expectativas foram frustradas na etapa 3
(exemplo do if/endif) a unica solução (até que não ficou ruim) foi criar uma função FData() para retornar
os dados e evitar ao máximo ficar "printando" códigos htmls. Mas é o que tem para hoje.
Dá pra fazer muita coisa com o mod_harbour. É se adaptar e ir criando as soluções com o que está disponível.

Para quem não entendeu o que eu quis dizer, veja um exemplo em PHP :

Código: Selecionar todos

 <body> 
      <table border="1"> 
        <tr> 
          <td>Código</td> 
          <td>Nome</td> 
          <td>E-mail</td> 
          <td>Data de Cadastro</td> 
          <td>Ação</td> 
        </tr> 
        <?php while($dado = $con->fetch_array()) { ?> 
        <tr> 
          <td><?php echo $dado['usu_codigo']; ?></td>
          <td><?php echo $dado['usu_nome']; ?></td> 
          <td><?php echo $dado['usu_email']; ?></td> 
          <td><?php echo date('d/m/Y', strtotime($dado['usu_datadecadastro'])); ?></td> 
          <td> 
            <a href="usu_editar.php?codigo=<?php echo $dado['usu_codigo']; ?>">Editar</a> 
            <a href="usu_excluir.php?codigo=<?php echo $dado['usu_codigo']; ?>">Excluir</a> 
          </td> 
        </tr> 
        <?php } ?> 
      </table> 
O nosso código ficou assim :

Código: Selecionar todos

#define adOpenForwardOnly 0
#define adOpenKeyset 1
#define adOpenDynamic 2
#define adOpenStatic 3
#define adLockReadOnly 1
#define adLockPessimistic 2
#define adLockOptimistic 3
#define adLockBatchOptimistic 4
#define adUseNone 1
#define adUseServer 2
#define adUseClient 3
#define adStateClose 		0

function main

   LOCAL oRs , oCn, cSql
   LOCAL cString := "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=" + PathBase() + "/scott.mdb"

   oCn := win_oleCreateObject( "ADODB.Connection" ) 
   oCn:ConnectionString := cString
   oCn:Open()
   
   oRs := win_oleCreateObject( "ADODB.Recordset" ) 
   oRs:CursorLocation = adUseClient
   oRs:Open( "SELECT * FROM emp", oCn , adOpenDynamic, adLockOptimistic )
   if oCn:State = adStateClose
		? "<script>alert('Failed open table EMP')</script>"
		Return
	Endif

TEMPLATE PARAMS oRs

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="Vlademiro">
    <title>Sistema </title>

    <!-- Bootstrap core CSS -->
	<link href="css/bootstrap.min.css" rel="stylesheet">

  </head>
  <body>

<main role="main" class="container">

  
  <h1>Tutorial de Mod-Harbour + Grid</h1>
  <p class="lead">Grid versão inicial</p>
    <div class="row">
      <table id="registros" class="table table-striped">
              <thead><tr><th>EMPNO</th><th>ENAME</th></tr></thead>
              <!-- Dados -->
              <tbody>
              <!-- Dados -->
              <?prg
              return FData( oRs )
              ?>
              </tbody>
                      
      </table>
      </div>
  
  

</main><!-- /.container -->
</body>
</html>

 
ENDTEXT  

return nil

FUNCTION FData( oRs )

    LOCAL cData := ""

    if oRs:recordcount > 0
        oRs:Movefirst()
        do while !oRs:eof()
            cData += "<tr>"
            
            cData += "<td>" + hb_ntos( oRs:fields("empno"):value ) + "</td>"
            cData += "<td>" + oRs:fields("ename"):value + "</td>"
            
            cData += "</tr>"
            oRs:movenext()
        enddo
        oRs:Movefirst() // Opcional, retorna para o primeiro registro
    endif

    RETURN cData
    
Nada mal.
Anexos
2020-08-14_123802.png
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

ex01_07.zip
(359.75 KiB) Baixado 573 vezes
Zip do tutorial
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Mini tutorial mod_harbour

Mensagem por JoséQuintas »

Não pra atrapalhar, mas pra talvez inspirar alterações no mod_harbour.

No ASP é misturado fonte com HTML de forma talvez diferente.

Uma tabela:

a b c d
1 2 3 4
1 2 3 4

Vou ter que eliminar os sinais de maior/menor no html pra aceitar aqui
Vai de table até /table, tr /tr pra indicar inicio e fim de linha da tabela, td /td pra indicar cada coluna
table
tr td a /td td b /td td c /td td d /td /tr
tr td 1 /td td 2 /td td 3 /td td 4 /td /tr
/table

A página em ASP, misturando html com fonte

html
script language=VBScript
table
tr td a /td td b /td td c /td td d /td /tr
FOR nCont = 1 TO 2
tr
FOR nCont2 = 1 TO 4
td nCont2 /td
NEXT
/tr
NEXT
/table

É só pra dar uma idéia.
Misturar html e fonte.... não é fácil.

É aí que entram rotinas prontas/frameworks.
Por exemplo, passar o array multidimensional pra rotina, e ela se vira.
Toda essa complicação continua existindo, mas no "nosso" fonte, isso não aparece.

Se a rotina for em javascript ou outra coisa, tanto faz, porque o html permite misturar tudo.

Mas.... precisa entender de tudo pra misturar, não é porque vai usar VB ou Harbour, que só precisa conhecer VB ou Harbour.
Se está pensando em algo mágico... melhor esquecer.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Mini tutorial mod_harbour

Mensagem por JoséQuintas »

A propósito..... a Vlademiro já chamou a atenção justamente pra uma diferença nisso do mod_harbour

No asp daria pra misturar HTML / ASP no meio do fonte, sem precisar ser um ou outro de cada vez

Código: Selecionar todos

< tr >
<% FOR nCont = 1 TO 10 %>
   < td >
   <% nCont %>
   < /td >
<% NEXT %>
< /td >
Já no mod_harbour não, o fonte Harbour precisa gerar todo bloco de html

Código: Selecionar todos

<?prg >
? "< tr >"
FOR nCont = 1 TO 10
   ? "< td >" + Str( ncont, 6 ) + "<  /td >"
NEXT
? "< /tr >"
?>
No asp basta que a parte que se refere a fonte esteja entre "<% >", o fonte tem precedência

Numa explicação simples:
No mod_harbour o bloco do fonte PRG é compilado e executado, então ele precisa conter tudo.
no asp o fonte vai sendo executado conforme aparece no html.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Mini tutorial mod_harbour

Mensagem por JoséQuintas »

Ou de outra forma:

é como ter um texto assim:

< html > [rotina1()] <table> [rotina2()] </table> </html >

o Harbour recebe o texto como parâmetro, e substitui:

cHtml := StrTran( "[rotina1()]", Rotina1() )
cHtml := StrTran( "[rotina2()]", Rotina2() )

Para a substituição, são retirados os blocos [], e o conteúdo é compilado.

Ou seja, uma coisa bem básica mesmo, que a maioria aqui já fez.

O único diferencial, é configurar isso no apache, pro programa Harbour receber o HTML primeiro e substituir tudo, antes do HTML ser executado. Isso é feito pela extensão PRG.

Na verdade outro diferencial: foi alterada a saída padrão, do ? "x", pra gravar direto no html, sem precisar ficar concatenando texto.
Ao invés de ir pra console, vai para o html resultado final.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

É verdade, Quintas

Na realidade da pra fazer muita coisa do jeito que está, inclusive o padrão de projeto MVC , bastante usado, diz que os dados tem que ficar separados da view. Ponto para o mod_harbour.

Quando eu comecei a programar para web era ASP antigo, depois PHP. Para quem está iniciando a mistura de código com HTML é normal e, na minha opinião, faz parte do aprendizado. Nem sempre a gente quer fazer um sistema completo, quer só uma página para abrir no celular do cliente para ele ver os pedidos do dia. Coisa simples mesmo. Nesse caso o PHP facilita por deixar misturar tudo em uma página.
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

Segunda Parte

Chegamos a parte dois do nosso mini-tutorial.

Os pré-requisitos para essa parte são :

(1) Ter acompanhado os exemplos da parte 1
(2) Saber o que é JSON e as funções do Harbour para manipulação (encode/decode)
(3) Entender os métodos POST/GET do protocolo HTTP
(4) Básico de JQuery (Básico mesmo)


Se vc não souber, mesmo assim dá para acompanhar, eu acho...

O objetivo dessa etapa é criar um grid usando AJAX e com paginação.

Nada de mod_harbour será usado nessa primeira etapa. Iremos somente criar um modelo para as etapas posteriores.

**

A ideia é essa :

Código: Selecionar todos

HTML5 + JQuery  ------AJAX--------> arquivo.json
(VIEW)                              (DATA)
São dois arquivos, o principal (contendo a view) e o segundo só com o json.
Nas etapas seguintes nós iremos gerar o arquivo json com mod_harbour.

A equipe do mod_harbour (indiretamente) indica uma biblioteca para
geração de grids que pode ser baixada gratuitamente em https://datatables.net/

Nós não iremos usar essa biblioteca. As vezes baixamos coisa demais que não vamos usar.
Nesses exemplos a seguir, com pouco código, já dá para ter um ótimo resultado.

**

O código json estático é bem simples :

Código: Selecionar todos


[
   { "id":9, "nome":"João Marcelo" },
   { "id":1, "nome":"Jefferson" },
   { "id":2, "nome":"Daniel" }
]

A leitura desse arquivo é bem simples, primeiro vamos criar um "id" no html para informar
o ponto onde os dados serão escritos. Vou chamar esse "id" de "registros"

Código: Selecionar todos

<table id="registros" class="table table-striped">
Agora o código Javascript (JQuery) que vai pegar o JSON e colocar na tabela.

Código: Selecionar todos

 <script>
   $( document ).ready( function(){

		$.ajax({ 
                   type: 'GET',
                   url: "dados.json",
                   async: true,        
                   dataType: 'json',
                   success: function( data ){
                       $.each( data, function( key, val ) {
                         $('<tr>').html( "<td>" + val.id + "</td>" +
                                         "<td>" + val.nome + "</td>" ).appendTo("#registros tbody");
                         });  
                  }  
        }); // ajax


    }); // $( document ).ready
  </script>
Rápidos comentários sobre o código acima para quem não trabalhou com JQuery ainda.

Código: Selecionar todos

(1) $( document ).ready( // Aguarda o documento carregar para executar o código 
(2) $.ajax // Inicio da chamada ajax 
(3) type : 'GET' // Tipo de método usado (não faz diferença porque não tem dados para enviar)
(4) dataType: 'json' // O tipo de dado que será convertido.
(5) url // Endereço onde eu devo pegar os dados (aceita endereços relativos)
(6) success // Bloco de código que será executado em caso de sucesso (a página existe)
Essa função chamada por success é simples, basta lembrar da função de usuário do DBEDIT. É a mesma ideia.
O parâmetro data é o valor lido do arquivo já devidamente convertido para JSON (eu disse que era um JSON em dataType)

Esse $.each é um laço disfarçado de função que vai percorrer todos os elementos do JSON (agora devidamente convertido para um hash data).
E para cada elemento vai chamar um bloco de código function( key , val )

* o segundo parâmetro "val" é o que interessa. Ele já contém a chave e o valor de cada hash. Tudo automático.
* o método appendTo coloca os dados na marca que eu criei no início.

Você pode achar que eu compliquei com o AJAX, mas é até mais fácil.
2020-08-14_151253.png
Na próxima etapa vamos gerar o dados.json com mod_harbour.
Avatar do usuário
Vlademiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 752
Registrado em: 11 Jul 2005 02:46

Mini tutorial mod_harbour

Mensagem por Vlademiro »

* Gerando o JSON dinâmicamente com mod-harbour

Essa parte já foi vista na primeira parte do nosso tutorial, é laço que lerá os dados.

Apenas acrescento duas coisas :

(1) O laço terá seus dados armazenados em um array de hash para posterior conversão em JSON
(2) Use hb_JsonEncode para criar o json e exibir

* Obs: Não deve ter nada impresso antes da exibição do JSON, por isso usei ?? e não ?.


O nosso código ficou assim :

Código: Selecionar todos

#define adOpenForwardOnly 0
#define adOpenKeyset 1
#define adOpenDynamic 2
#define adOpenStatic 3
#define adLockReadOnly 1
#define adLockPessimistic 2
#define adLockOptimistic 3
#define adLockBatchOptimistic 4
#define adUseNone 1
#define adUseServer 2
#define adUseClient 3
#define adStateClose 		0

function main

   LOCAL oRs , oCn, cSql
   LOCAL cString := "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=" + PathBase() + "/scott.mdb"
   LOCAL hReg 
   LOCAL aReg := {}

   oCn := win_oleCreateObject( "ADODB.Connection" ) 
   oCn:ConnectionString := cString
   oCn:Open()
   
   oRs := win_oleCreateObject( "ADODB.Recordset" ) 
   oRs:CursorLocation = adUseClient
   oRs:Open( "SELECT * FROM emp", oCn , adOpenDynamic, adLockOptimistic )
   if oCn:State = adStateClose
		Return "ERRO"
	Endif
   if oRs:recordcount > 0
        oRs:Movefirst()
        do while !oRs:eof()
            hReg := {=>}
            hReg[ "id" ] := oRs:fields("empno"):value 
            hReg[ "nome" ] := oRs:fields("ename"):value 
            AADD( aReg , hReg )
            oRs:movenext()
        enddo
        oRs:Movefirst() // Opcional, retorna para o primeiro registro
    endif    
    ?? hb_JsonEncode( aReg )

return nil

No nosso cliente apenas informo que ele deve pegar de dados.prg e não mais de dados.json

Código: Selecionar todos

url: "dados.prg",
Aproveitei e coloquei um método a mais AJAX do JQuery, é o simples, é só para ele retornar
algo em caso de erro. Por exemplo, o seu servidor pode estar fora do ar. O usuário precisa
pelo menos saber disso, senão fica um grid estático sem nada.

Isso é feito com :

Código: Selecionar todos

error: function (xhr, ajaxOptions, thrownError) {
							alert(xhr.status);
							alert(thrownError);
						  }		
Dentro da função $.ajax do JQuery. O mesmo princípio da função de usuário da DBEDIT também.
2020-08-14_161803.png
Responder