sábado, 28 de junho de 2008

BDS 2006 & Javascript - Intraweb 8.0

O Intraweb ainda continua presente nas versões mais recentes o Delphi. Ao que parece, a versão do framework que acompanha o no BDS 2006 apresenta alguma novidade. Contudo, muita coisa importante parece não ter mudado. Por exemplo, o fonte dos componentes ainda não é acessível aos desenvolvedores. Confesso que vejo com grande antipatia essa característica proprietária da Atozed. Postura incompatível com a demonstrada por grandes fornecedores de tecnologias que se destacam atualmente. Isso me remete ao sentimento de que ao usar um produto da Atozed o desenvolvedor está lhe dando com uma empresa cujo a mentalidade reflete uma postura feudal, própria da miserável e subdesenvolvida América latina.
Pretendo criar alguns exemplos (nandjares de mirolands) para experimentar como se comporta o Intraweb 8.0.1, que esta presente no DBS 2006. (Veja: Intraweb e Delphi 7)


Iniciando nosso primeiro exemplo

No BDS 2006, para iniciar um novo projeto selecione no menu: File ► New ► Other. Em
seguida, selecione no diálogo seguinte (caixa de dialogo) IntraWeb Application Wizard. A partir da Treeview (Item Categories) conforme ilustrado na figura abaixo:





No diálogo seguinte definiremos algumas configurações importantes para nossa aplicação web.



StandAlone Application: Essa opção permite desenvolver o aplicativo Intraweb sem a necessidade de deploy em servidor web (IIS por exemplo). Isso traz algum conforto, visto que, assim é dispensável configurações obrigatórias para desenvolvimento que exija deploy e sincronismo com o servidor. Outra vantagem é que essa opção oferece um recurso de “Debug” idêntico o experimentado pelo desenvolvedor quando trabalha na IDE do Delphi com aplicações desk top. A partir dessa configuração seu aplicativo Intraweb, quando o F9 é pressionado, é “executado” pelo Browser, contudo para debuggar basta marcar o brack point (F5) na linha desejada e prosseguir como se você estivesse desenvolvendo um aplicativo convencional.
Pool Data Connection: Como o próprio título indica, refere-se a pool de conexões. Bem, tenho que confiar no que está indicando essa propriedade pois no momento não tenho como testar quase nada sobre ela.
Create User Session: Cria uma declaração, automaticamente, no seu novo projeto, de um obejto da classe TUserSession. Esse objeto, também conhecido desde a versão 5.0, tem o objetivo de ser um gerenciador de seção.
Durante muito tempo o gerenciamento de seção sempre foi uma parte sensível, bastante trabalhosa, nos primórdios do desenvolvimento para web. Na época do Delphi 7, esta estratégia de gerenciamento de seção foi uma feature que fez o Intraweb dar coro em nas tecnologias web vigentes naquela época.
Project Name: Define o nome do projeto.

Project Directory: O Framework Intraweb tem a particularidade de solicitar o path do diretório onde ficará o projeto. No contexto web isso tem uma particular importância por causa de obrigatoriedade da dependência de um servidor web. Porque ele é responsável pela interpretação e disponibilização do seu programa em forma de serviço web. Você pode estar se perguntando: “Ora, definimos o exemplo como ‘Stand Alone Application’, logo não tem servidor web. Correto?”. Errado meu caro, o Intraweb no módulo Stand Alone Application possui uma funcionalidade que simula um servidor web. O simples fato desse detalhe ficar transparente para o desenvolvedor não é a prova de que não exista a necessidade do servidor web.
Outra coisa sobre “Project Directory” ele não usa a API do windows para selecionar um diretório, isso é tosco. Em compensação, você pode digitar um diretório que não exista ainda, ele cria pra você.

Main Form: Define se o aplicativo suportará tecnologia para dispositivos móveis

De cara já percebemos novidades, pretendo verificar até que ponto elas nos representarão vantagem efetivas ou não.

Após essas configurações iniciais, click no botão “OK” e o BDS vai criar pra você as seguintes Units:




Unit1: Este é o formulário Intraweb principal do seu projeto. Esta está nomeado de “IWForm1”.

DatamoduleUnit: Como o próprio nome indica, trata-se do Datamodule (TDatamodule).

unit DataModuleUnit;

interface

uses
{$IFDEF Linux}QForms, {$ELSE}Forms, {$ENDIF}
SysUtils, Classes;

type
TDataModule1 = class(TDataModule)
private
public
end;


implementation

{$R *.dfm}

end.

ServerController: Onde está definido a classe que faz a interface com o servidor web. TIWServerController (IWServerController). Esta classe é também onde definimos muitas propriedades importantes do aplicativo web que estamos construindo.




UserSessionUnit: Gerenciador de seções do Intraweb. Nas versões anteriores, o UserSession era uma classe definida na unit do ServerController.Veja um exemplo de uma Unit “ServerController” do Delphi 7 (Intraweb 5.0):

unit ServerController;
{PUBDIST}

interface

uses
Classes,
UDm,
IWServerControllerBase, IWAppForm, IWApplication,
SysUtils;

type
TIWServerController = class(TIWServerControllerBase)
procedure IWServerControllerBaseNewSession(ASession: TIWApplication;
var VMainForm: TIWAppForm);
private
public
end;

// This is a class which you can add variables to that are specific to the user. Add variables
// to this class instead of creating global variables. This object can references by using:
// UserSession
// So if a variable named UserName of type string is added, it can be referenced by using:
// UserSession.UserName
// Such variables are similar to globals in a normal application, however these variables are
// specific to each user.
//
// See the IntraWeb Manual for more details.
TUserSession = class(TComponent)
public
FrmDm: TFrmDm;
//
constructor Create(AOwner: TComponent); override;
end;

// Procs
function UserSession: TUserSession;

implementation
{$R *.dfm}

uses
IWInit;

function UserSession: TUserSession;
begin
Result := TUserSession(RWebApplication.Data);
end;

{ TUserSession }

constructor TUserSession.Create(AOwner: TComponent);
begin
inherited;
FrmDm := TFrmDm.Create(AOwner);
end;

procedure TIWServerController.IWServerControllerBaseNewSession(
ASession: TIWApplication; var VMainForm: TIWAppForm);
begin
ASession.Data := TUserSession.Create(ASession);
end;

end.

Dando uma olhada rápida nessas units em termos de arquitetura o Intraweb mudou um pouco a organização entre as classes TServerController e TUserSession, porém ainda continua trabalhando com serialização de objetos. Veja que neste trecho de código do ServerController as classes são acessadas não por uma variável mas por uma função:


function UserSession: TIWUserSession;
function IWServerController: TIWServerController;
function LockDataModule: TDataModule1;
procedure UnlockDataModule(ADataModule: TDataModule1);


Observamos também que TUserSession agora herda de “TIWUserSessionBase”. Mas isso nos deixa muito pouca informação porque não temos acesso a definição desse ancestral.
Javascript no Intraweb 8.0.1
Pretendo testar um pouco como um IWForm está se comportando quando usamos processamento do lado cliente.

Propriedade “HiddenFields”

Aqui podemos criar inputs hidden dinamicamente para nossas páginas (Isso é novidade). No String List Editor digite:

GMottaZn=VariaveisOuConstates_PraQuemGosta_do_InputHidden
CoisasLoucas=Bla




Propriedade “ExtraHeader” do IWForm1

Digite o código Javascript na propriedade do IWForm1 conforme ilustrado abaixo:

<SCRIPT LANGUAGE="JavaScript">
<!-- Exibindo informações sobre o browser ...
document.write("<HR>");
document.write("<H1><center><font color=#0080C0 size=5 face=Geneva,
Arial, Helvetica, sans-serif>Estação ZN - Client Side Scripting
</font></center></H1>");
document.write("<HR>");
document.write(" <br>A versão do browser: " + navigator.appVersion);
document.write(" <br>Marca: <B>" + navigator.appName +
"</B>.");
// end script hiding -->
</SCRIPT>




Propriedade JavaScript do IWForm1
Vou criar algumas funções JavaScript e veremos o que vai acontecer. A propriedade JavaScript declaramos apenas funções porque a tag “script type” é definida pelo framework. Diferente do que experimentamos da propriedade “ExtraHeader”.


// Percorre o objeto HTML "form". O Intraweb cria todos os objetos HTMLs
a partir do seu form "Delphi"
function ZnShowObjects(){
for (var j = 0; j < document.forms[0].elements.length; j++) {
alert("Loop volta = "+j);
alert(document.forms[0].elements[j].name + ": " +document.forms[0].elements[j].value);
ZnInput = document.forms[0].elements[j];
alert("Bla");
alert(ZnInput.getAttribute("type"));
if (ZnInput.getAttribute("type").toLowerCase() == "hidden"){
alert(ZnInput.getAttribute("type"));
}
}
};

//função para exibir o input hidden que criamos na propriedade "HiddenFields"

function ExibeHidden(){
MyZn = document.getElementById("GMottaZn");
alert(MyZn.type + "|" + MyZn.name + " = "+ MyZn.value);
};

//Exemplificando uma estrutura de repetição "while" em JavaScript
function ExibeEscondido(){
MyZn = document.getElementById("GMottaZn");
alert("Veja o input hidden que criamos:" + MyZn.value);
ZnInputs = document.forms[0].getElementsByTagName('input');
Achei = 0;
i = 0;
// exemplificando o método "getElementsByTagName", ele retorna uma lista de objetos HTML
while (AZnInput = ZnInputs[i]){
alert("while");
// Procurando o hidden na lista retornada pelo "getElementsByTagName"
if (AZnInput.getAttribute('type').toLowerCase() == 'hidden'){
alert("Achei um escondido!! :" + AZnInput.name + " - "+
AZnInput.value);
Achei = Achei++;
}
else {
// Não encontrou o hidden
alert("Não é hidden: " + AZnInput.name + " - "+
AZnInput.value);
};
i++;
};
if (Achei == 0) {
alert("Não encontra os escondidos, mas eles estão lá!!!");
}
else {
alert(Achei);
};
};


Agora vamos adiciona os controles no IWF3orm1:
Adicione da plaheta IWStandard um TIWEdit, e três TIWButtons.



Testei a propriedade “ExtraTagParams” dos controles, sem sucesso por enquanto. Vou tentar mais posteriormente.



Na propriedade “ScriptEvents” da cada um dos IWButtons fiz a chamada a cada uma das funções que definimos na propriedade “JavaScript” do IWForm1. Veja as imagens abaixo e codifique igual:


IWButton1 - OnClick


IWButton2 - OnClick


IWButton3 - OnClick


Para executar a aplicação pressione F9. Vai aparecer o diálogo do simulador de servidor web, pressione F9 novamente.








Um comentário:

  1. Muito bom o seu post. Valeu.

    Fiz alguns teste e me deparei com um problema simples, porém não consegui visualizar meu erro.

    Uso um Iwfile para localizar um arquivo, que posteriormente irá como anexo em um e-mail.
    O problema é que o iwfile.filename, retorna somente o nome do arquivo, e preciso do full path para anexa-lo ao e-mail. Alguém já passou por isso?

    Abraço.

    ResponderExcluir