Mostrando postagens com marcador CSS. Mostrar todas as postagens
Mostrando postagens com marcador CSS. Mostrar todas as postagens

sábado, 25 de abril de 2009

Ajax/JSON & Delphi technologies– Webbrocker, Intraweb (ISAPI), IWTemplateProcessorHTML com CSS

Estou com muita pressa, portanto serei o mais sucinto o possível ...
O objetivo deste artigo é documentar uma solução desenvolvida para atender um cliente.
Vamos criar um serviço de consulta que deverá fornecer dados para um requisição Ajax. Para isso construiremos uma aplicação servidora (Delphi/Webbrocker) a qual acessará uma base de dados MS SQL Server (especificamente o banco de dados para exemplos “Northwind”), para executarmos uma consulta parametrizada (valor que virá na requisição cliente) cujo os dados retornados serão devidamente formatados para Json (Wik) (Não vou usar XML). Ou seja, como resposta a requisição mencionada, a aplicação servidora retornará os dado que serão consumidos pelo Ajax/Json.


Não sei, ou sei muito pouco sobre o que vc esta falando, Gerson. Então veja:
Pesquisa 1
Pesquisa 2
Marco Cantù AJax XML/DOM
Neste artigo o Cantù mostra como aproveitar o XMLData do TClientDataSet no DOM/XML (mto legal para delpheros).
Marco Cantù Artigo Ajax
Json

Em seguida, desenvolveremos o aplicativo cliente, a camada de interface, em Delphi/Intraweb, aonde implementaremos uma função Javascript. Nela usaremos o XMLHttpRequest do javascript de forma assíncrona.


Mãos à Obra, Estação ZN!


Server-Side development

Inicie um projeto Webbrocker no Delphi. Menu ►File ►New ►Other ► Web Server Application.





A tecnologia de service web que vamos usar será API do IIS (ISAPI). No WebModule1 adicione os componentes de acesso a dados: TADOConnetion, TADODataSet, TDataSetProvider, TClientDataSet. No editor de string de conexão (Edit Connection String) do ADOConnection, configure a conexão com o SQL Server e em seguida associe os Datasets (Como Associar? veja no Estação ZN). O Comando SQl que definiremos no ADODataSet1 será:



select * from Customers
where CompanyName like :CompanyName


Criando a Webbrocker Action (WebAction)

Selecione o WebModule1, de maneira que suas propriedades sejam listadas no Object Inspector. Crie uma Action e configure suas propriedades conforme ilustrado abaixo:




Evento OnAction da Action “ZnConsClientes”:



uses
Math, StrUtils;

procedure TWebModule1.WebModule1ZnConsClientesAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
const
ZnTag = '%s:%s';
var
StrStatment: String;
i, CodRetorno: Integer;
begin
with ClientDataSet1 do
begin
Params[0].AsString := '%' + Request.QueryFields.Values['znNomeCli']+ '%';
try
Open;
CodRetorno := IfThen(IsEmpty, -1, 1);
StrStatment := StrStatment +
Format(ZnTag, ['codretornoZn',
IntToStr(CodRetorno)]);

if CodRetorno = 0 then Exit;

for i := 0 to Pred(FieldCount) do
begin
StrStatment := StrStatment + ','+
Format(ZnTag, [LowerCase(ClientDataSet1.Fields[i].FieldName),
IfThen((ClientDataSet1.Fields[i].AsString = ''), QuotedStr('-'),
QuotedStr(ClientDataSet1.Fields[i].AsString))]);
end;

finally
Close;
Response.Content := Format('{%s}',[StrStatment]);
end;
end;
end;


Para usar as versões sobrecarregadas da função “IfTehn” precisamos, para este exemplo, declarar (fazer uses das ...) as units “Math” e “StrUtils” (observe na linha 2 do trecho acima).
Pronto, acabamos essa primeira parte! Antes de compilar, garanta que o ADOCOnnection esteja desconectado. Propriedade “Connected” igual a “false”. Agora sim!!! Compile a aplicação servidora para gerar a dll a qual faremos deploy no IIS (Deploy de uma dll ISAPI). Vou criar o diretório virtual no IIS com o nome de “ajaxjsonzn”.

Após ter tido sucesso em realizar o deploy, vamos testar.
Para isso digitar no browser "http://localhost/ajaxjsonzn/?znNomeCli=Cactus" para se emocionar ao ver o que acabamos de criar.


Veja a string retornada pela nossa aplicação servidora Webbrocker:

{codretornoZn:1,customerid:'CACTU',companyname:'Cactus Comidas para llevar',contactname:'Patricio Simpson',
contacttitle:'Sales Agent',address:'Cerrito 333',city:'Buenos Aires',region:'-',
postalcode:'1010',country:'Argentina',phone:'(1) 135-5555',fax:'(1) 135-4892'}



Cliente-Side development

Meu querido leitor do Estação ZN, neste momento vamos começar esta segunda parte do artigo construindo uma página html. Hum, ãhhh?!?!? Como?? Mas o assunto não é Delphi? Sim, o assunto gira em torno das tecnologias para web existentes no Delphi. O que nós vamos fazer agora é demonstrar também como o framework Intraweb pode interagir com projetos onde as páginas web são desenvolvidas a parte do Delphi. Existem várias situações onde isso poderá ser extremamente vantajoso. Por exemplo, imagine um projeto onde exista uma ênfase grande na parte de design e por isso as páginas do site são desenvolvidas especificamente pela equipe de designers e diante disto a equipe de desenvolvimento deve integrá-las a parte de lógica e persistência desenvolvida no Delphi. Este cenário no contexto Delphi é até bem comum, penso que sim.
Portanto, antes de qualquer coisa execute seu editor preferido de páginas htm e Javascript e bola pra frente. Abaixo, segue o código dá pagina que desenvolvi para este exemplo:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<style type="text/css">
<!--
.AreaTexto {
font-family: "Comic Sans MS", "Courier New", Georgia;
width: 420px;
height:540px;
background-color:#FFFF38;
}
-->

</style>
<script type="text/javascript">

var ZnXmlAjaxHttpObj;

function ZnGetClienteWsAjx(ZnMyName) {

alert('estou na função!');
if (typeof XMLHttpRequest != "undefined"){ZnXmlAjaxHttpObj = new XMLHttpRequest();}
else{
ZnXmlAjaxHttpObj = new ActiveXObject('Msxml2.XMLHTTP');
if (!ZnXmlAjaxHttpObj){ZnXmlAjaxHttpObj = new ActiveXObject('Microsoft.XMLHTTP');}
}
alert(ZnMyName.value);
var ZnSpan = document.getElementById("IWLABEL1");

ZnSpan.innerHTML = "Estaçaõ Zn: Buscando dados do Cliente pelo nome fornecido: " + ZnMyName.value + " ....";

var url = "http://localhost/ajaxjsonzn/?znNomeCli="+ ZnMyName.value;
ZnXmlAjaxHttpObj.open("GET", url, true);
ZnXmlAjaxHttpObj.onreadystatechange = ZnDynProcessaReqBuscaCliente;
ZnXmlAjaxHttpObj.send(null);
}

function ZnDynProcessaReqBuscaCliente() {
var ZnSpan2 = document.getElementById("IWLABEL2");
var ZnElement = document.getElementById("IWEDIT1");
ZnSpan2.innerHTML = 'Processando ..................';
if (ZnSpan2.innerHTML.indexOf("buscando dados",0) >= 0){ZnSpan2.innerHTML = "Processando ...";}
else {ZnSpan2.innerHTML = "<b>buscando dados do Cliente: </b>" + ZnElement.value + " ....";}

if (ZnXmlAjaxHttpObj.readyState == 4) {
if (ZnXmlAjaxHttpObj.status == 200) {
processJsonEstacaoZn(ZnXmlAjaxHttpObj.responseText);
}
}
else return false;
}

function processJsonEstacaoZn(obj1) {

var ObjLandjah;
eval('ObjLandjah = ' + obj1);
var Aux =
" <br /> customerid: "+ ObjLandjah.customerid +
" <br /> contactname: "+ ObjLandjah.contactname +
" <br /> contacttitle: "+ ObjLandjah.contacttitle +
" <br /> companyname: "+ ObjLandjah.companyname +
" <br /> country: "+ ObjLandjah.country +
" <br /> CEP/postal code: " + ObjLandjah.postalcode +
"<br /> Região: " + ObjLandjah.region +
"<br /> Cidade: " + ObjLandjah.city +
"<br />Logradouro: " + ObjLandjah.address +
" <br /> fax: " + ObjLandjah.fax +
" <br /> phone: "+ ObjLandjah.phone;
alert(Aux);
document.getElementById("cj").innerHTML += '- <b>Ninguém vai subir #@#@%#@%#%@ ... vai ficar todo mundo quietinho ae.</b>';
document.getElementById("cj").innerHTML += Aux;
document.getElementById("IWMEMO1").innerHTML += ' \n <b>100% Quatorze? </b>';
document.getElementById("IWMEMO1").innerHTML += ' \n ************************************';
//****************************************************

var insertData = "<b> Resultado Consulta www.estacaozn.blogspot.com:</b>";
try {
//alert('Cod Retorno: ' + ObjLandjah.codretornoZn);
switch (ObjLandjah.codretornoZn * 1) {
case 1:
document.getElementById("IWMEMO1").innerHTML += ' \n - Cavera meu Capitão. ';
document.getElementById("IWMEMO1").innerHTML += ' \n ************************************';
insertData += " <br /> customerid: "+ ObjLandjah.customerid +
" <br /> contactname: "+ ObjLandjah.contactname +
" <br /> contacttitle: "+ ObjLandjah.contacttitle +
" <br /> companyname: "+ ObjLandjah.companyname +
" <br /> country: "+ ObjLandjah.country +
" <br /> CEP/postal code: " + ObjLandjah.postalcode +
"<br /> Região: " + ObjLandjah.region +
"<br /> Cidade: " + ObjLandjah.city +
"<br />Logradouro: " + ObjLandjah.address +
" <br /> fax: " + ObjLandjah.fax +
" <br /> phone: " + ObjLandjah.phone;
//alert("Case, estou aqui");
// Abaixo, veja como atribuir valor do JavaScript Object Notation ao IWMemo e aos IWEdits
document.getElementById("IWMEMO1").innerHTML += ' \n ************************************';
document.getElementById("CEP").value = ObjLandjah.postalcode;
document.getElementById("CEP").disabled = true;
document.getElementById("IWMEMO1").innerHTML += " \n CEP: " + ObjLandjah.postalcode;
document.getElementById("CONTACTNAME").value = ObjLandjah.contactname;
document.getElementById("CONTACTNAME").disabled = true;
document.getElementById("IWMEMO1").innerHTML += " \n Contato: " + ObjLandjah.contactname;
document.getElementById("CONTACTTITLE").value = ObjLandjah.contacttitle;
document.getElementById("CONTACTTITLE").disabled = true;
document.getElementById("IWMEMO1").innerHTML += " \n Contato: " + ObjLandjah.contacttitle;
document.getElementById("CIDADE").value = ObjLandjah.city;
document.getElementById("CIDADE").disabled = true;
document.getElementById("IWMEMO1").innerHTML += " \n Cidade: " + ObjLandjah.city;
document.getElementById("BAIRRO").value = "Bla!";
document.getElementById("BAIRRO").disabled = true;
document.getElementById("FAX").value = ObjLandjah.fax;
document.getElementById("FAX").disabled = true;
document.getElementById("IWMEMO1").innerHTML += "\n Fax: " + ObjLandjah.fax;
document.getElementById("LOGRADOURO").value = ObjLandjah.address;
document.getElementById("LOGRADOURO").disabled = true;
document.getElementById("IWMEMO1").innerHTML += "\n Logradouro:" + ObjLandjah.address;
document.getElementById("COMPANYNAME").value = ObjLandjah.companyname;
document.getElementById("COMPANYNAME").disabled = true;
document.getElementById("IWMEMO1").innerHTML += "\n Nome da Empresa:" + ObjLandjah.companyname;
document.getElementById("COUNTRY").value = ObjLandjah.country;
document.getElementById("COUNTRY").disabled = true;
document.getElementById("IWMEMO1").innerHTML += "\n Pais:" + ObjLandjah.country;
document.getElementById("UF").value = ObjLandjah.region;
document.getElementById("UF").disabled = true;
document.getElementById("IWMEMO1").innerHTML += " \n Região: " + ObjLandjah.region;
document.getElementById("PHONE").value = ObjLandjah.phone;
document.getElementById("PHONE").disabled = true;
document.getElementById("IWMEMO1").innerHTML += " \n Tel: " + ObjLandjah.phone;
document.getElementById("IWMEMO1").innerHTML += '\n ************************************';
break;
case -1: insertData += "Cliente não encontrado!"; break;
case -2: insertData += "Valor digitado inválido!"; break;
case -3: insertData += "Ta com nojinho 02?."; break;
case -4: insertData += "AH ESSA ALTURA DO CAMPEONATO VC TA SEM AH BANDOLEIRA ??!"; break;
default: "PEDE PRA SAIR 01. Pede pra sair.";
}
}
catch(Error) {
insertData = "<br> <font color=#FF0000> eRrO. TIRA ESSA ROUPA PRETA QUE VC NÃO É CAVEIRA. </font> As Landjhas de mirandjas!!!"
}

document.getElementById("IWLABEL2").innerHTML += insertData;
document.getElementById("IWLABEL1").innerHTML += " <br /><b> Os senhores estão bem? Os senhores estão feridos? Algum dos senhores estão baleados? " +
" Então, no próximo post vcs vão aprender a carregar corpos!!! </b>"
document.getElementById("IWMEMO1").innerHTML += ' \n ';
}



</script>

</head>

<body>
<form id="form1" name="form1" method="post" action="">
<div id="PosControles" style="position: absolute; top: 32px; left: 12px; width: 887px; height: 92px; background-color: #3399CC;
font-size:16px; font-weight:400" align="justify"><br />Digite o Nome do Cliente: {%IWEdit1%} | {%IWButton1%}
<br>
{%Logradouro%}{%Bairro%}{%Cidade%} {%UF%}{%CEP%} {%CompanyName%}
{%ContactName%}
{%ContactTitle%}
{%Phone%}
{%Fax%}
{%Country%}
{%IWLink1%} <a href="http://localhost/estacaozncliente">Reload Page</a></div>
<div id="PosSpan" style="position: absolute; top: 128px; left: 12px; width: 440px; height: 580px; background-color: #99FF99;">
{%IWLabel1%} {%IWLabel2%}
<span id="cj">
</span>
</div>
<div id="PosMemo" style="position: absolute; top: 128px; left: 458px; width: 440px; height: 580px; background-color: #99FF99;"
align="center"><p>
{%IWMEMO1%}
testando!!
</div>


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


Salve a página html (o arquivo html, referente a página que acabamos de criar) com o nome de “ZnPageAjaxJsonIntraweb.html”.




O próximo passo, será criar a aplicação cliente intraweb. Retornemos ao Delphi então, para iniciarmos um projeto Intraweb ISAPI. No menu File ► New ►Other ►Intraweb ►ISAPI Application.

Adicione no IWForm1 os seguintes componentes:


IWTemplateProcessorHTML1: TIWTemplateProcessorHTML;
IWLabel1: TIWLabel;
IWEdit1: TIWEdit;
IWButton1: TIWButton;
IWMemo1: TIWMemo;
CEP: TIWEdit;
UF: TIWEdit;
Bairro: TIWEdit;
Logradouro: TIWEdit;
Cidade: TIWEdit;
IWLabel2: TIWLabel;
CompanyName: TIWEdit;
ContactName: TIWEdit;
ContactTitle: TIWEdit;
Phone: TIWEdit;
Fax: TIWEdit;
Country: TIWEdit;


No evento OnCreate do IWForm1 codifique conforme ilustrado abaixo:

procedure TformMain.IWAppFormCreate(Sender: TObject);
begin
Self.TemplateProcessor := IWTemplateProcessorHTML1;
IWTemplateProcessorHTML1.Templates.default := 'ZnPageAjaxJsonIntraweb.html';
IWLabel1.Caption := ' ';
IWMemo1.Font.Enabled := False;
IWMemo1.Font.CSSStyle := 'AreaTexto';
CEP.Width := 80;
UF.Width := 40;
Cidade.Width := 120;
Logradouro.Width := 180;
Bairro.Width := 90;
IWButton1.ExtraTagParams.Add('onClick=ZnGetCLienteWsAjax(IWEDIT1)');
IWMemo1.Lines.Add(' ');
IWEdit1.Text := 'Cactus Comidas para llevar';
end;


Observe na linha 7, estou atribuindo dinamicamente ao IWMemo1 uma classe CSS (“'AreaTexto'”) a qual está definida na página HTML que criamos anteriormente.

Ok, muito bem, meus amigos e minhas amigas, a parte referente a aplicação cliente termina aqui!! Isso é mto bom! Agora, é chegado o momento do bom e velho amigo deploy. Para isso, um “build all” na aplicação Intraweb (alt, p, b) é bem vindo, ela será compilada e a dll para deploy será gerada. So .. next step ... enjoy yourself ...
O nome do diretório virtual que vou criar será “estacaozncliente”.


No mesmo diretório onde está a dll gerada pelo Delphi na compilação deste projeto Intraweb, crie um diretório onde ficará a pagina html que o IWTemplateProcessorHTML1 vai trabalhar. Me refiro ao arquivo da página que criamos anteriormente, “ZnPageAjaxJsonIntraweb.html”. Esse diretório tem que se chamar “Templates”, desta forma não precisamos definir nenhuma configuração para TemplateProcessorHTML encontrar o arquivo.


Testando Aplicação cliente IntraWeb/ISAPI.



O link “Reload Page” coloquei para facilitar o desenvolvimento da aplicação cliente. Assim evito de ficar digitandoa url do serviço toda vez que houver alguma alteração, seja na aplicação servidora, seja na aplicação cliente, ou na página html.

Conclusão
A partir da experiência realizada e documentada neste artigo, destaco as seguintes observações:
Usar a tecnologia Ajax nos seus sistemas web, sites, ou serviços traz, além de um ganho de performance, escalabilidade e interoperabilidade. Isso porque a solução Ajax é independente da tecnologia que esteja sendo utilizada no client-side. Pretendo, para o próximo post documentar um exemplo da mesma solução desenvolvida neste arquivo, sendo que a camada cliente desenvolverei em Java com o Netbeans.
O uso do JavaScript Object Notation (Json) descomplica muito a desenvolvimento de uma solução baseada em Ájax.
Um ponto muito importante neste artigo é o emprego do componente processador de “templates” o IWTemplateProcessorHTML. Ele permite que seu form Intraweb seja construído em cima de um arquivo HTML criado separadamente. Dessa forma um leque de possibilidades se abre. No momento a que eu mais quero destacar é que com isso é possível modularizar seu projeto colocando toda a parte de layout, disign, bem como o processamento client-side. Com isso, todo o Javascript que trabalhamos nos artigos anteriores pode ser definido na página web. Igualzinho é feito por webmasters, inclusive usando a tag “src” para códigos Javascript que ficam em arquivos separados.
Javascript placement: o Código JavaScript pode estar fisicamente disposto em um diretório específico para este fim, num arquivo “.js” separado da página HTML. Isso melhora inda mais a modularização do seu sistema, site, portal, etc...
O arquivo fonte do Javascript em questão é referenciado na página HTML usando a tag “script” o atributo "src" com o nome do arquivo e o path definidos como valor.


<head>
<script language="JavaScript" src="ZnJavaScriptFile.js"></script>
</head>

Estive conversando com o Felipe e com o Malta sobre os exemplos anteriores que estive postando. Onde demonstrei o código Javascript definido como string no meio do código Delphi. Essa forma de implementar é um metodologia que condeno enfaticamente nos meus projetos. Inclusive, todos dois, tanto o Felipe, quanto o Malta, concordam e estavam me chamando a atenção sobre isso. Que o Javascript no meio do código Delphi, mesmo eu “organizando”, através de constantes o caos, é uma solução macarrônica, feia, nojenta, asquerosa. Entretanto, eu fiz dessa forma nos exemplos anteriores porque acredito que assim o artigo que estou escrevendo para o Estação ZN fica menor, menos complexo, mais didático, na medida em que eu procuro estar focado nos assuntos que pretendo falar naquele momento. Quando estou postando aqui minha ênfase é totalmente didática. Entendo que para passar um conhecimento complexo ele deve ser simplificado, de maneira que seja reduzida toda complexidade inerente ao problema em questão.
Portanto, de agora em diante, sugiro que você cuide para que, imperativamente, o Javascript fique separado da aplicação Delphi. Para isso temos basicamente dois caminhos a tomar: O primeiro seria usar o “IWTemplateProcessorHTML”. Uma segunda opção seria usar um “LoadFromFile”, ou seja ler dinamicamente arquivos com as funções Javascript. Se você optar por usar o IwTemplateProcesso, implementar desta forma, o “js” na página HTML, é uma ação intuitiva. Como fazer isso está demostrado neste artigo. Caso negativo, uma idéia, proposta pelo Malta, que eu gostei bastante, seria do Delphi, fazer um “LoadFromFile” de um arquivo, onde estaria com código JavaScript parametrizado (semelhante a um parâmetro de um comando SQL). A idéia é usar, ao invés de parâmetros de “FormatString (%s)” uma sintaxe como nome de parâmetros (:nome) e fazer substituição por pares (nome, valor). Deixe-me explicar melhor:
Veja num dos artigos anteriores: O Código Javascript que defini não tem “%s” para usar na função Format? Então, substitua todos o “%s” por uma sintaxe própria, que estaríamos criando, que represente o nome de um parâmetro. Por exemplo: ..... :par1 ... :idade ... :cidade... :idade. A exemplo de um comando SQL num TSQLQurey. Para trabalhar em conjunto, criaríamos uma função para substituir os parâmetros por valores em runtime, por exemplo: “function ZnReplaceParams(const znParmName, znParamValue: String)”. A chamada seria: “ReplaceParams('idade', '18');”. De cara podemos citar como vantagens melhor legibilidade do código Javascript, além de não fica dependente de posição (como é o caso do “Format(%s)”). Dentro da função caixa preta “ZnReplaceParams”, um StringReplace pode dar conta do recado, com rfReplaceAll e rfIgnoreCase. O que inclusive facilita quando você precisa repetir o mesmo valor várias vezes no mesmo script bastaria repetir o nome da "macro" ou parâmetro. Boa Malta, Estação Zn agradece! Tks!!
Uma outra abordagem seria usar argumentos na própria função Javascript, a qual vai estar definida num arquivo “.txt”, ou “.js”, que seja, e no Delphi atribuir as definições das chamadas a essas funções nos eventos “Javascript”, nas propriedades “ExtragParams”, ou “ScriptEvent”. Como exemplifiquei no artigo sobre validação de CIC.


Falar sobre modularização é muito simples. Mas demonstrar, é no mínimo trabalhoso. Eu prefiro inclusive demonstrar o “como não fazer”, para melhorar, aumentar a aderência da explicação do sobre “como fazer”.

Aconselho ao desenvolvedor que decidir usar o Delphi/Intraweb ter muita atenção na hora de referenciar os objetos, inputs, submits, selects, criados pelo Intraweb, no que tange a caixa do nome dos controles definidos no Delphi. Isso pq o Delphi não é case sensitive, conseqüentemente o desenvolvedor delphi não deverá, a pricípio, estar acostumado com essa restrição. Portanto, cuidado com comandos do tipo “document.getElementById("IWMEMO1")”, porque todo componente Intraweb é criado na página html com o nome em CAIXA ALTA. A função “getElementById” é sensível a caixa.
Programar em Javascript exige muita atenção a questões extra-intelectuais, pois você não vai poder contar com code insight, nem auto-complemento de código (code complete) e ainda existe o overhead de atenção na questão do case sensitive sem contar que as mensagens de erro não são tão amigáveis. Uma ferramenta que pode ajudar neste sentido são os plugins para desenvolvimento web do Fire Fox.
Outro ponto adverso é desenvolver um script client-side compatível com todos os browsers. Isso exige bastante de quem está desenvolvendo. Entretanto os bônus adquiridos em usar enfaticamente Javascript acaba compensando todos os ônus listados. Além disso, com o tempo o desenvolvedor ganha prática nesta abordagem e esses fatores negativos acabam perdendo sua força.
A tecnologia Json ainda é bem nova, nas minhas pesquisas encontrei muito pouca gente usando. Mas pra minha surpresa um número razoável de pessoas, blogs, falando sobre. Dei uma pesquisada no google trends http://www.google.com/trends sobre as buscas sobre Json.





Abaixo, código completo das units Delphi:

Aplicação Cliente Intraweb


unit IWUnit1;
{PUBDIST}

interface

uses
IWAppForm, IWApplication, IWTypes, IWCompMemo, IWCompButton, IWCompEdit,
Controls, IWControl, IWCompLabel, Classes, IWLayoutMgr,
IWTemplateProcessorHTML, IWHTMLControls;

type
TformMain = class(TIWAppForm)
IWTemplateProcessorHTML1: TIWTemplateProcessorHTML;
IWLabel1: TIWLabel;
IWEdit1: TIWEdit;
IWButton1: TIWButton;
IWMemo1: TIWMemo;
CEP: TIWEdit;
UF: TIWEdit;
Bairro: TIWEdit;
Logradouro: TIWEdit;
Cidade: TIWEdit;
IWLabel2: TIWLabel;
CompanyName: TIWEdit;
ContactName: TIWEdit;
ContactTitle: TIWEdit;
Phone: TIWEdit;
Fax: TIWEdit;
Country: TIWEdit;
procedure IWAppFormCreate(Sender: TObject);
public
end;

implementation
{$R *.dfm}

uses
ServerController, IWForm;

//ajaxconcorretor

procedure TformMain.IWAppFormCreate(Sender: TObject);
begin
Self.TemplateProcessor := IWTemplateProcessorHTML1;
IWLabel1.Caption := ' ';
IWMemo1.Font.Enabled := False;
IWMemo1.Font.CSSStyle := 'AreaTexto';
CEP.Width := 80;
UF.Width := 40;
Cidade.Width := 120;
Logradouro.Width := 180;
Bairro.Width := 90;
IWButton1.ExtraTagParams.Add('onClick=return ZnGetClienteWsAjx(IWEDIT1);');
IWMemo1.RawText := True;
IWMemo1.Lines.Add(' ');
IWEdit1.Text := 'Cactus Comidas para llevar';
end;

end.



Aplicação Servidora Webbrocker



unit Unit1;

interface

uses
SysUtils, Classes, HTTPApp, DBClient, Provider, DB, ADODB;

type
TWebModule1 = class(TWebModule)
ADOConnection: TADOConnection;
ADODataSet1: TADODataSet;
DataSetProvider1: TDataSetProvider;
ClientDataSet1: TClientDataSet;
ClientDataSet1CustomerID: TWideStringField;
ClientDataSet1CompanyName: TWideStringField;
ClientDataSet1ContactName: TWideStringField;
ClientDataSet1ContactTitle: TWideStringField;
ClientDataSet1Address: TWideStringField;
ClientDataSet1City: TWideStringField;
ClientDataSet1Region: TWideStringField;
ClientDataSet1PostalCode: TWideStringField;
ClientDataSet1Country: TWideStringField;
ClientDataSet1Phone: TWideStringField;
ClientDataSet1Fax: TWideStringField;
procedure WebModule1ZnConsClientesAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;

var
WebModule1: TWebModule1;

implementation

{$R *.dfm}

uses
Math, StrUtils;

procedure TWebModule1.WebModule1ZnConsClientesAction(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
const
ZnTag = '%s:%s';
var
StrStatment: String;
i, CodRetorno: Integer;
begin
with ClientDataSet1 do
begin
Params[0].AsString := '%' + Request.QueryFields.Values['znNomeCli']+ '%';
try
Open;
CodRetorno := IfThen(IsEmpty, -1, 1);
StrStatment := StrStatment +
Format(ZnTag, ['codretornoZn',
IntToStr(CodRetorno)]);

if CodRetorno = 0 then Exit;

for i := 0 to Pred(FieldCount) do
begin
StrStatment := StrStatment + ','+
Format(ZnTag, [LowerCase(ClientDataSet1.Fields[i].FieldName),
IfThen((ClientDataSet1.Fields[i].AsString = ''), QuotedStr('-'),
QuotedStr(ClientDataSet1.Fields[i].AsString))]);
end;

finally
Close;
Response.Content := Format('{%s}',[StrStatment]);
end;
end;
end;


end.


Artigo completo (View Full Post)

segunda-feira, 22 de setembro de 2008

Java para Web no Netbeans 6 – Servlet, JSP & CSS

Java é uma linguagem de programação. Entretanto, quando nos referimos a Java como uma tecnologia estamos tratando de um grande conjunto composto por elementos distintos. Esses elementos de forma generalizada são: Padrões, frameworks e tecnologias. Esses três elementos combinados definem um outro elemento que são as arquiteturas.

Objetivo

Vamos construir um exemplo de aplicação Web onde experimentaremos de perto a complexidade de construir conteúdo dinâmico para Web. Conseqüentemente esbarraremos em algumas questões arquiteturais envolvendo tecnologia do lado cliente, e servidor. Veremos uma das soluções Java para este cenário.
Temos o arquivo Index.jsp, ele define a participação da tecnologia JSP na nossa arquitetura. Neste arquivo definiremos um formulário (objeto http form) que enviará dados para uma classe servlet a qual processará esses dados.

A tecnologia Java tem uma abordagem própria para desenvolvimento Web. Basicamente, quando você ouve falar em Java para Web invariavelmente escutará associado a esta idéia duas tecnologias: Servlet e JSP. Digo basicamente, porque as duas não são absolutas neste contexto. Existem outras, as quais vermos mais adiante, que cujo a utilização, quando feita adequadamente, pode oferecer para o desenvolver um ganho satisfatório.
A tecnologia Servlet desempenha um papel muito importante neste cenário, vamos neste artigo desenvolver um pequeno exemplo de uma aplicação Web em Java usando explicitamente a tecnologia Servlet. Meu principal objetivo e experimentar o Netbeans 6 para esse fim, durante esse processo pretendo tocar em pontos de importância básica pertinentes ou tema que escolhi inicialmente. Portanto, prossigamos:

Inicie um novo projeto Web no Netbeans 6 (Veja em “Um novo Projeto no Netbeans 6.”).




Entendendo um projeto Web Java

Veja na janela “Projects” (Project explorer vou chamar assim ...) , os diversos elementos que compõem o nosso projeto. Eles ficam organizados e dispostos numa estrutura hierarquizada de diretórios que são representados por uma Tree View a qual fornece acesso aos arquivos contidos por cada diretório.



O Diretório “Web Pages” é o principal, a raiz, de uma aplicação Java Web convencional. Contidos nele temos um arquivo index.jsp (que define a home page do site, por exemplo), além do diretório “WEB-INF” o qual contém o arquivo descritor de deploy (deployment descriptor), web.xml.

Configuration Files”, é o diretório onde ficam todos os arquivos referentes a configurações da aplicação web.

Source Packages”, velho conhecido, onde devem ficar todos os pacotes, classes Java e Servlets (obviamente, que serão criados durante o desenvolvimento da aplicação web).

Test Package”, para testes unitários.

As bibliotecas ficam em “Libraries”, exceto as que forem necessárias aos testes que devem ficar em “Tests Libraries” (por default as bibliotecas do Junit 3.8.2 e 4.1 já serão adicionadas nesta pasta).



Usando CSS

Vou criar um arquivo CSS o qual usarei neste exemplo. Para armazená-lo, vou criar um novo diretório dentro de “Web Pages”, a este chamarei de “ZnCss”. Com o botão direito do mouse, na treeview do project explorer, sobre a pasta “Web Pages” selecione New ► Folder, conforme ilustração abaixo:




O Netbeans, através do assistente vai auxiliar este trabalho. Em “Folder Name” digite o nome desejado para o novo diretório. Note que, você pode também definir a hierarquia desse novo diretório em “Parent Folder”. Para completar a criação do diretório click em “Finish”.



Para criar o arquivo CSS, selecione, com o botão direito do mouse no novo diretório, a opção New ►Other, para acessar o assistente. Em seguida, dentre as opções listadas, na categoria “Web”, selecione “Cascading Style Sheet”. Click em “Next” para continuar a criação do arquivo CSS.



Em “CSS File Name” digite o nome do arquivo: “ZnCSSlandjah”. Veja que “Location” e “Folder” já estão definidos em decorrência de termos selecionado o diretório “ZnCss”.



Click em “Finish” e seu arquivo será criado. Esse foi meu primeiro contato com o editor de CSS do Netbeans 6, gostei! Basta você digitar a classe, ou tag que deseja redefinir, e intuitivamente é possível usar os recursos da IDE para edição de CSS.
O Preview lhe permite em tempo de design ver o efeito do css que você está editando.

A seguir o código do meu css

/*
Document : ZnCSSlandjah
Created on : 22/09/2008, 10:59:57
Author : Gmotta Zn
Description:
Purpose of the stylesheet follows.
*/

div{
font-family: Cosmic Sans, Veranda,Tahoma;
font-size: 14px;
background-color: #330099;
color: #ccff99;
font-weight: bolder;
text-align: center;

}


Editando o arquivo Index.jsp

Quando iniciamos um projeto Web no Netbeans ele define no deployment descriptor qual o arquivo será executado quando o Glass Fish atender uma requisição cliente chamando a URL do seu serviço. Esse arquivo, por default é o Index.jsp. Você pode alterar isso no o arquivo “web.xml” (basta um duplo click sobre o arquivo, ou com o botão direito selecione “Open”), pela IDE na aba “Pages”.



Na tag “head” do arquivo “Index.jsp” vou linkar o CSS “ZnCSSlandjah.css”.


<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF- 8">
<title>Estação ZN - Nova JSP Page</title>
<link href="ZnCss/ZnCSSlandjah.css" rel="stylesheet" type="text/css">


O próximo passo será adicionar um “form” para postar dados para efetuarmos um processamento qualquer no servidor. Na janela “Palhette” (provavelmente ela deve estar no lado direito da IDE), selecione em “HML Forms” um objeto “Form”, click sobre ele e arraste para um local, entre a abertura e o fechamento da tag “body”. Em seguida prossiga com o assistente.



Em “Action” vou digitar “ZnLandjha” (esse vai ser o nome do Servlet que criarei posteriormente), o “method” selecione "POST".



O Editor no Netbeans é sensacional, veja um code insigth para HTML muito bom.



Agora, o “body” da minha página jsp está assim: (indexJSP.txt)

<body>
<h2> Estação ZN - Servlets </h2>
<h3> GlassFish <h3>
<div>
www.estacaozn.blogspot.com
</div>
<br>

<form name="form1" action="ZnLandjha" method="POST">

</form>
</body>


OBS: Na tag "div" pretendo aplicar o efeito do CSS ...

Vou adicionar um objeto HTML “Table” na minha página aonde pretendo colocar os “inputs”. Depois de editar o código, digite conforme ilustrado abaixo:


<%--
Document : index
Created on : 18/09/2008, 03:25:39
Author : GMotta Zn
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Estação ZN - Nova JSP Page</title>
<link href="ZnCss/ZnCSSlandjah.css" rel="stylesheet"
type="text/css">

</head>
<body>
<h2> Estação ZN - Servlets </h2>
<h3> GlassFish <h3>
<div>
www.estacaozn.blogspot.com
</div>
<br>

<form name="form1" action="ZnLandjha" method="POST">
<div>
<table border="0" cellpadding="1">
<tbody>
<tr>
<td>
Digite o Nome:
</td>
<td>
<input type="text" name="znBla" value="Bla!"
size="32" />
</td>
</tr>
<tr>
<td>
<input type="submit" value="Ok Zn" name="btnEnviar"
/>
</td>
<td>
Netbeans 6 - Servlet, JSP & CSS
</td>
</tr>
</tbody>
</table>
</div>
</form>
</body>
</html>



Criando o Servlet

Com o botão direito do mouse no que eu chamo de “Project Explore”, selecione a opção: New ►Servlet




O Nome da Classe servlet vai ser “ZnLandjha”. Note que o assistente já define pra você o projeto (Project: AppWebServletsZN, não editável) e o diretório (Location: Source Pakcages) onde será criado o arquivo onde está defina a classe que vamos codificar. Ainda não definimos uma package para nosso projeto, isso deverá ser feito neste momento. Digite “ZnWebLandjahPkg” em Pakcage. Veja ilustração abaixo:



Clicando em “Next” você pode configurar a URL de chamada ao seu servlet mediante ao valor digitado em “URL Pattern(s):”. Todas as informações definidas precisam ser persistidas no “Deployment Descriptor”, o arquivo “web.xml”. Portanto, a opção “Add information to deployment descriptor” deve ficar selecionada. Logo, vou deixar tudo como está neste diálogo e finalizar aqui. Click em “Finish”.



Codificando o Servlet “ZnLandjha”

package ZnWebLandjahPkg;

import java.io.*;
import java.net.*;
import java.util.Iterator;
import javax.servlet.*;
import javax.servlet.http.*;

/**
* @author GMottaZn
*/
public class ZnLandjha extends HttpServlet {

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String znBla = request.getParameter("znBla");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet ZnLandjha</title>");
out.println("<link href=ZnCss/ZnCSSlandjah.css rel=stylesheet type=text/css>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet ZnLandjha at " + request.getContextPath
() + "</h1> <br>");
out.println("<h4> Você Digitou: " + znBla + "</h4> <br>");
out.println("<div> Ivertendo temos: " + inverterZn(znBla)+ "</div>");
out.println("</body>");
out.println("</html>");

} finally {
out.close();
}
}

protected String inverterZn(String znValue){
StringBuffer znAux = new StringBuffer(znValue);
znAux.reverse();
return znAux.toString();
};

// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}

/**
* Returns a short description of the servlet.
*/
public String getServletInfo() {
return "Short description";
}
// </editor-fold>
}


Até que em fim um pouco de código Java. Analisado o código acima:

Linha 1: referência ao pacote (package).

Linha 3 – 7: importação de bibliotecas.

Linha 9-11: Comentário para documentação.

Linha 12- 71: Codificação da classe “ZnLandjha”, que estende de “HttpServlet” (Superclasse para Servlet). A classe “HttpServlet” estende a classe javax.servlet.GenericServlet. Ela acrescenta os métodos “doXXXX” que são executados mediante as requisições “http”. “doGet”, “doPost”, “doPut”, “doDelete”, “doOption” e “doTrave”. Cada um desses métodos são chamados em resposta a um método http evocado. Exemplo: O método “doGet” é executado quando o Servlet recebe uma requisição (de uma página que submeteu um “form”) que foi enviada ao servidor web (por exemplo, o Glass Fish) usando o método http “GET”.




Linha 16: Recebendo do “Form” postado (do lado cliente) o valor do objeto “input” cujo nome é "znBla" (O qual foi definido no arquivo “Index.jsp”).

Linha 19-34: Dentro de um bloco protegido (try...), monta a página para saída dos valores processados pelo Servlet “ZnLandjha”.

Linha 28: Saída do valor processado pelo método protegido que codificamos “inverterZn”.

Linha 37-41: Método protected “inverterZn”, responsável pela inversão da string digitada pelo cliente. A inversão está sendo efetuada na linha 39, pela execução do método “reverse”. Na linha 40 uso o método “toString” para poder atribuir o valor de “znAux”, que é do tipo “StringBuffer”, para String e dessa forma posso retornar o valor invertido no método em questão.

Agora vamos fazer o deploy da nossa aplicação, com o botão direito sobre a raiz do projeto no “project explorer”, selecione “Undeploy and Deploy”.




Testando aplicação criada

Para testar basta pressionar F6, ou na barra de ferramentas click sobre o triângulo verde.



O browser vai ser executado ...



Digite alguma coisa na caixa de texto e submeta ...



O Servlet processou a requisição ...




Fontes deste artigo

Artigo completo (View Full Post)

sexta-feira, 15 de fevereiro de 2008

Syntax Highlight para Bloggers

What about, this?

Yes, we have!!! Not banana, however ...


Syntax Highlight é uma funcionalidade, presente em alguns editores de texto, que tem a finalidade de tornar o conteúdo digitado nele mais legível (textos e códigos mais inteligíveis). O que ele faz é formatar o texto automaticamente, no imediato momento em que ele esta sendo digitado, com cores, fontes e estilos diferentes de maneira a destacar a categoria das palavras, diferenciando símbolos, sinais ou números digitados uns dos outros. Isso é um auxílio fundamental para programadores, porque essa funcionalidade destaca a estrutura tanto das linguagens de programação, quanto as de marcação. Alem destacar também os erros de sintaxe que podem eventualmente ocorrer durante a implementação de um programa.
Portanto, devemos considerar que o Syntax Highlight é uma forma estratégica, que explora um recurso didático para prover maior legibilidade destacando o contexto do código digitado num editor. Isso é extremamente conveniente para para outros contextos extra editores de texto também. Como no caso de web pages, pois formatar texto no HTML cru, na base do ponteiro e da marreta, não é tarefa pra qqr um. Isso, sem comentar o fato que mesmo assim fica uma "M" (hehehehh).


Já faz algum tempo que tenho conversado com o Felipe sobre conseguirmos um para o Estação ZN. Essa coisa de ficar manualmente destacando as palavras reservadas e comentários, estava me dando um trabalho absurdo. Eu sei que maluquice minha fazer isso, mas agora eu posso ver o meu código formatadinho, sem overhead de trabalho, e isso faz mto feliz!! Hehhehehe ....

Indo ao que interessa:
Eu usei o componente do “uncle Google”: SyntaxHighlighter. Como vocês poderão ver, ele é totalmente escrito em Javascript e CSS, muito simples de implementar, bem fácil de entender e o melhor de tudo: É eficiente, funciona, e suporta diversas linguagens!!!
Aqui vc poderá encontrar um tutorial de como usar no seu blog evitando um probleminha de inconpatibilidade com o a tag "
" em função da formatação de estilo do "Blogger" (embora , baste para isso vc dar uma olhada no fonte do Estação ZN -- últimas linhas).
Eu simplesmente, descaradamente, copiei o que ele descreveu (hehhehe ... cara, I just don’t have enough time).
O Felipe postou um comentário sobre e colocou exemplos.
Ah! vc vai precisar fazer upload dos fontes do componente para algum servidor. Eu usei o Google Pages ("uncle Google" patrocinado geral) .
So ... enjoy yourself!!!





Artigo completo (View Full Post)

segunda-feira, 21 de maio de 2007

Apresentando dados tabulares com estilo

Olá a todos mais uma vez.

Você costuma usar tabelas HTML? Você já precisou usar uma tabela HTML para mostrar dados de um banco de dados? Você (ou seu usuário) alguma vez já se confundiu com as linhas nos dados tabulares?

Bem, acho que a resposta da maioria a todas as perguntas é sim. Vamos abordar a última pergunta.

Para não haver confusões entre as linhas nós temos diversas soluções:

- Bordas na tabela: Esta é a mais fácil de se implementar e o mais básico: É só colocar o atributo border="1" na tag <Table>. Com os estilos CSS podemos colocar até bordas mais bonitas. É legal, é fácil, mas não é muito sofisticado - porém não subestime - às vezes menos é mais.


- Estilo "zebra": Cada linha de uma cor diferente, alternando entre duas cores. Uma solução bem bacana. Quando a tabela é dinâmica é bem fácil de fazer:

<table>
<tr>
<th>Título</th>
</tr>
<?
foreach ($resutset as $registro) {
$cor = ($cor == "#ffffff" ? "#eaeaea" : "#ffffff");
echo "<tr style='background: $cor'>";
..
..
echo "</tr>";
}
?>
</table>



- DHTML: Todas as linhas têm o mesmo fundo, mas a linha atual muda de cor quando o usuário passa o mouse sobre ela. Exemplo:

<table>
<tr>
<th>Título</th>
</tr>
<?
foreach ($resutset as $registro) {
?>
<tr onmouseover="this.style.background = '#eaeaea'"
onmouseout="this.style.background = 'none'">
...
...
...
</tr>
<?
}
?>
</table>


Assim também fica muito legal.

Este assunto pode parecer bobo, mas às vezes são coisas pequenas assim que definem a identidade de um site ou de uma aplicação web, levando ao seu sucesso.

Grande abraço a todos e até a próxima!

Artigo completo (View Full Post)

quinta-feira, 25 de janeiro de 2007

Centralizando o conteúdo na página com Layout fixo


Olá a todos (novamente). Agora uma dica rápida de css para quem quer definir um layout de largura fixa e centralizado. Antigamente isso era possível usando table ou div para colocar o conteúdo centralizado. Agora podemos fazer isso facilmente definindo um estilo para o objeto body. Vejam só:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
<style type="text/css">
body {
width: 700px;
margin: 0 auto;
}
</style>
</head>
<body>
<div style="border: solid 1px black;">
Oi Conteúdo centarlizado ocupando todo o tamanho disponível
</div>
</body>
</html>


Estou usando aqui o XHTML 1.1. Eu já testei com XHTML 1.0 e HTML 4.01 e também rola. Falando de navegadores, no IE7 e no Firefox 2 rola. Acho que no IE6 também rola, já que é CSS padrão.

Analisando o CSS:

body {
width: 700px;
margin: 0 auto;
}


Definimos a largura padrão para o documento de 700px e as margens como: 0 para superior e inferior e automática prar esquerda e direita.

O CSS para margens funciona assim:

margin: [superior] [direita] [esquerda] [inferior];


Caso informe somente um valor este será aplicado para todas as margens. Caso informe dois serão repetidos conforme a explicação acima.

As margens auto na direita e na esquerda indicam para o navegador dividir o espaço que sobra entre os lados, centralizando o conteúdo.

Acabou sendo mais longo que eu pensei, mas tá maneiro :) Abraços e até mais.

Artigo completo (View Full Post)

quarta-feira, 24 de janeiro de 2007

Implementando um layout mais limpo e sem tabelas

Este assunto não é muito novo, mas acho que vale a pena falar algo aqui sobre este assunto. Há um tempo atrás era uma obrigação usar e abusar de tabelas para conseguir fazer um layout de várias colunas dentro do site.

Hoje em dia há uma nova forma de construir layout: tableless. Quem é/era acostumado a construir layouts com tabelas sabe como é chato e trabalhoso trabalhar com tabelas para layout. E ainda tem outro problema: quando temos que mexer no layout nós temos um sério problema se usamos tabelas. Principalmente na relação designer/programador (hehe).

Agora com divs e CSS nós conseguimos construir estes layouts de forma muito mais fácil e prática. Com um pequeno código html vou mostrar como fazer um layout padrão de site com 3 colunas somente usando div.

código HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<title>Layout de colunas sem tabelas</title>

<style type="text/css">
#cabecalho {
clear: both;
height: 50px;
background: #eaeaea;
margin-bottom: 5px;
}

#esquerda {
float: left;
width: 120px;
height: 300px;
background: #eaeaea;
}

#direita {
float: right;
width: 120px;
height: 300px;
background: #eaeaea;
}

#conteudo {
margin-left: 130px;
margin-right: 130px;
height: 300px;
}

#rodape {
clear: both;
height: 20px;
background: #eaeaea;
margin-top: 5px;
}

</style>

</head>


<body>

<div id="cabecalho">
Cabeçalho
</div>

<div id="esquerda">
Esquerda
</div>

<div id="direita">
Direita
</div>

<div id="conteudo">
Conteúdo
</div>

<div id="rodape">
rodapé
</div>

</body>

</html>


o resultado fica assim:



Cabeçalho


Esquerda


Direita


Conteúdo


Rodapé



Os tamanhos foram reduzidos para caber aqui mas as propriedades são as mesmas.

Agora vamos estudar os estilos css dos elementos acima:

float: indica onde a camada vai 'flutuar' de acordo com o próximo elemento - possui como opções left, right e none.

clear: indica que esta camada não vai permitir flutuações na posição especificada - possui como opções left, right e both.

A regra deste layout é que a ordem das colunas deve ser sempre esta: primeiro coluna da esquerda, depois coluna da direita e por último a coluna do meio.

Nas colunas da esquerda e da direita definimos uma largura de 120px, cada uma com seu respectivo float. Na div do conteúdo definimos as margens esquerda e direita como 130px. Isso é para fazer com que o texto do conteúdo sempre fique dentro destes limites, mesmo que as colunas laterais já tenham acabado.

O cabeçalho e o rodapé possuem a propriedade clear: both para não serem afetados pela flutuação das camadas. A margem inferior do cabeçalho e inferior do rodapé são apenas para manter um espaço entre os elementos.

Quem quiser aprender mais sobre tableless, há um ótimo site brasileiro sobre o assunto, inclusive com vídeo aulas: www.tableless.com.br.

Então é isso. Agora nós já podemos construir layouts de forma mais simples e que permita alteração mais facilmente. Tabelas agora serão somente para o que elas servem: dados tabulares. Até mais.

Artigo completo (View Full Post)

 
BlogBlogs.Com.Br