tag:blogger.com,1999:blog-19392195073087185942024-03-08T02:34:57.079-03:00Estação ZNEstamos estudando e o resultado disso postamos aqui. Sinceramente desejamos que o conteúdo aqui semeado possa ser útil para muitas pessoas.<br>
Seja bem-vindo e fique à vontade para contribuir da forma que puder e quiser.<br>
Bola pra frente ... :)GMotta ZNhttp://www.blogger.com/profile/14738149386892914626noreply@blogger.comBlogger238125tag:blogger.com,1999:blog-1939219507308718594.post-67085495782352276732011-11-13T16:39:00.001-03:002011-11-13T16:51:26.458-03:00Atualização no programa encode-xvid - Agora com interface gráfica<p>Olá novamente. Neste post venho com uma notícia: o programa que estou desenvolvendo - <a href="http://code.google.com/p/encode-xvid/">encode-xvid</a> agora está com uma interface gráfica. Desenvolvi uma em python usando a biblioteca gráfica pyGTK. Este é um wrapper onde eu posso montar a linha de comando com mais facilidade - mas ao mesmo tempo é um hobby onde posso desenvolver em python, que gosto tanto.</p>
<p>Quem quiser conferir o projeto, é só ir lá na página no google code e pegar instruções de como fazer svn checkout, ou conferir os fontes lá mesmo - http://code.google.com/p/encode-xvid/</p>
<p>Por enquanto só vai funcionar no GNU/Linux, porque o script está em shell script, mas pretendo reescrever em python, aí vai rodar em outros SO também, desde que tenham o ambiente instalado.</p>
<p>Grande abraço e até a próxima.</p>Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com1tag:blogger.com,1999:blog-1939219507308718594.post-36835267394530156492011-11-07T19:47:00.001-03:002011-11-07T19:52:45.309-03:00Script para encode xvid agora no google code<p>O script que criei <a href="http://estacaozn.blogspot.com/2011/11/shell-script-para-gerar-arquivos-xvid.html">em outro post</a> para gerar arquivos para dvd agora está no google code. Resolvi colocar ele lá para ficar mais fácil compartilhar o desenvolvimento e manter atualizado.</p>
<p>Se quiser acompanhar a evolução deste script é só pegar em <a href="https://code.google.com/p/encode-xvid/">https://code.google.com/p/encode-xvid/</a></p>
<p>Sei que este script não é coisa muito grande, mas é meu primeiro esforço em desenvolver software livre. vou tentar melhorá-lo com o tempo.</p>Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-62405855285840391302011-11-06T23:55:00.009-03:002011-11-07T00:59:04.232-03:00Shell script para gerar arquivos xvid com áudio mp3Olá pessoal. Neste post vou colocar um script que eu mesmo fiz para fazer encode de arquivos de vídeo no formato avi com o codec de vídeo xvid e áudio mp3.<br /><br />Faço essa conversão porque tenho dois probleminhas: 1 - meu dvd é velhinho e roda arquivos com legendas, mas não arquivos muito grandes - nesse caso tenho que reduzir o bitrate. 2 - meu xbox 360 não carrega legendas externas (srt) de vídeos e só roda xvid.<br /><br />O software que eu uso para encode é o mencoder, o SO é GNU/Linux distro Slackware 13.37. O mplayer foi compilado por mim. Versão:<br /><pre>MPlayer SVN-r34308-4.5.2 (C) 2000-2011 MPlayer Team</pre><br /><br />Meu mplayer foi compilado com as bibliotecas adicionais xvid e libmp3lame, mas para encode do xvid eu estou usando lavc. Para audio estou usando mp3lame.<br /><br />Antes de postar o script, vale lembrar que é minha primeira aventura de script shell para automatizar alguma tarefa minha, então o código pode não ser o melhor possível. Dicas são muito bem vindas!<br /><br />Abaixo o script:<br /><br /><pre name="code" style="white-space: pre-wrap"><br />#!/bin/bash<br /><br />function usage {<br /> echo "uso: video-encode -v video -l legenda -ab audio-bitrate -vb video-bitrate [-vol volume] [-sim] -o arqiuvo-output"<br />}<br /><br />function error_exit {<br /> echo "$1" 1>&2<br /> exit 1<br />}<br /><br />while [ "$1" != "" ]; do<br /> case $1 in<br /> -v )<br /> shift<br /> video=$1<br /> ;;<br /> -l )<br /> shift<br /> legenda=$1<br /> ;;<br /> -vb )<br /> shift<br /> vb=$1<br /> ;;<br /> -ab )<br /> shift<br /> ab=$1<br /> ;;<br /> -o )<br /> shift<br /> output=$1<br /> ;;<br /> -vol )<br /> shift<br /> vol=":vol=$1"<br /> ;;<br /> -sim )<br /> sim=true<br /> ;;<br /> * )<br /> usage<br /> error_exit "Parâmetro não reconhecido: $1"<br /> ;;<br /> esac<br /> shift<br />done<br /><br /><br /># Verificando se o arquivo de vídeo é válido<br />test -n "$video" -a -f "$video" || error_exit "Arquivo inválido: $video"<br /><br /># Verificando se o arquivo de legenda (se informado) é válido<br />test -z "$legenda" -o -f "$legenda" || error_exit "Legenda inválida: $legenda"<br /><br /># Verificando se o arquivo de legenda (se informado) está no format utf-8<br />test -f "$legenda" -a $(file -bi "$legenda" | sed 's/\(.*\)charset=//') == "utf-8" || error_exit "A legenda não está no formato utf-8: $legenda"<br /><br /># Tenta criar o arquivo de saída<br />touch "$output" > /dev/null 2>&1 || error_exit "Erro ao criar o arquivo de saída: $output"<br /><br />echo<br />echo "******************************************************"<br />echo "Ambiente"<br />echo "video: $video"<br />echo "legenda: $legenda"<br />echo "vbitrate: $vb"<br />echo "abitrate: $ab"<br />echo "******************************************************"<br />echo<br /><br />function echo_exec {<br /> echo $1<br /> echo $2<br /><br /> if [ -z $sim ]; then<br /> eval $2 || error_exit "Operação cancelada"<br /> fi<br />}<br /><br />cmd="mencoder \"$video\" -sub \"$legenda\" -ovc lavc -lavcopts vcodec=mpeg4:vpass=1 -oac mp3lame -ffourcc XVID -o /dev/null"<br />echo_exec "Encoding 2-pass - parte 1" "$cmd"<br /> <br />cmd="mencoder \"$video\" -sub \"$legenda\" -ovc lavc -lavcopts vcodec=mpeg4:vpass=2:vbitrate=$vb -oac mp3lame -lameopts abr:br=$ab$vol -ffourcc XVID -o \"$output\" -utf8"<br />echo_exec "Encoding 2-pass - parte 2" "$cmd"<br /></pre><br /><br />Explicando em termos gerais, o script aceita os seguintes parâmetros de linha de comando:<br />-v arquivo de vídeo origem<br />-l arquivo de legendas<br />-vb bitrate do vídeo<br />-ab bitrate do áudio<br />-o arquivo de output<br />-vol volume do áudio - opcional (para aplicar ganho - pode distorcer)<br />-sim modo simulação (na verdade só exibe os comandos na tela, sem executar nada)<br /><br />Estou usando o método 2pass do mencoder porque achei que tive videos de melhor performance assim.<br /><br />Alguns pontos a melhorar:<br /><br />O mencoder está sempre usando -utf8, por isso precisa do arquivo de legendas em formato utf-8. Vou tentar criar uma função para converter automaticamente o arquivo para utf-8 caso não seja - atualmente o programa retorna um erro e não prossegue.<br /><br />Antes de rodar o programa é preciso saber de antemão o bitrate de áudio e vídeo que serão usados. Vou tentar identificar no arquivo de origem e dar suporte ao usuário entrar com as informações através de prompt.<br /><br />Tornar a seleção da legenda opcional. Embora era minha intenção, ainda não está funcionando.<br /><br />Acabei de executar o script e na minha máquina está funcionando (bem, na nossa máquina sempre funciona, né...), então espero que ajude outras pessoas da mesma forma que me ajuda aqui.<br /><br />Grande abraço a todos e até a próxima.Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com3tag:blogger.com,1999:blog-1939219507308718594.post-82053851607204001602011-10-30T11:41:00.004-03:002011-10-30T12:28:25.294-03:00Problema de conexão tcp/ip com MySQL no Slackware13.37 - ResolvidoOlá a todos mais uma vez.<br /><br />Neste post vou relatar um problema que aconteceu comigo e o que eu fiz para resolver.<br /><br />Neste fim de semana montei uma instalação GNU/Linux para desenvolver alguns projetos em Java com JBoss Seam e MySQl - minha primeira escolha era o postgres, mas o mysql já estava instalado e eu encontrei dificuldades instalando o postgres no Slackware, mas fica para outro post - A distro escolhida foi o Slackware, em sua versão recentemente lançada 13.37.<br /><br />SO, BD, eclipse e Jboss instalados, banco de teste criado, fui criar uma conexão no eclipse para começar a trabalhar na IDE. Quando veio o problema: Não conseguia conectar no banco pelo software.<br /><br />Horas e horas procurando consegui resolver.<br /><br />Primeira orientação que vi foi procurar no arquivo my.cnf - no meu caso fica no /etc/my.cnf - se existe alguma entrada skip-networking não comentada.<br /><br />Esta entrada skip-networking desabilita o suporte a rede: Só é possível conectar ao servidor na mesma máquina e pelo socket /var/lib/mysql/mysql.sock.<br /><br />O meu problema era que não havia esta configuração no meu servidor, e mesmo assim não conseguia conectar via tcp/ip. Foi quando encontrei no arquivo de script que inicia o meu servidor que o script estava passando esse parâmetro pela linha de comando.<br /><br />No meu é /etc/rc.d/rc.mysqld. Na linha 32 do script tem a seguinte linha:<br /><br /><code>SKIP="--skip-networking"</code><br /><br />Essa linha deve ser comentada para o servidor aceitar conexões tcp/ip.<br /><br />Grande abraço e até a próxima.Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com3tag:blogger.com,1999:blog-1939219507308718594.post-57108204011392942622011-10-27T09:56:00.005-03:002011-10-27T10:10:06.945-03:00Rational Team Concert - JazzHub<!--[if gte mso 9]><xml> <w:worddocument> <w:view>Normal</w:View> <w:zoom>0</w:Zoom> <w:trackmoves/> <w:trackformatting/> <w:hyphenationzone>21</w:HyphenationZone> <w:punctuationkerning/> <w:validateagainstschemas/> <w:saveifxmlinvalid>false</w:SaveIfXMLInvalid> <w:ignoremixedcontent>false</w:IgnoreMixedContent> <w:alwaysshowplaceholdertext>false</w:AlwaysShowPlaceholderText> <w:donotpromoteqf/> <w:lidthemeother>PT-BR</w:LidThemeOther> <w:lidthemeasian>X-NONE</w:LidThemeAsian> <w:lidthemecomplexscript>X-NONE</w:LidThemeComplexScript> <w:compatibility> <w:breakwrappedtables/> <w:snaptogridincell/> <w:wraptextwithpunct/> <w:useasianbreakrules/> <w:dontgrowautofit/> <w:splitpgbreakandparamark/> <w:dontvertaligncellwithsp/> <w:dontbreakconstrainedforcedtables/> <w:dontvertalignintxbx/> <w:word11kerningpairs/> <w:cachedcolbalance/> </w:Compatibility> <w:browserlevel>MicrosoftInternetExplorer4</w:BrowserLevel> <m:mathpr> <m:mathfont val="Cambria Math"> <m:brkbin val="before"> <m:brkbinsub val="--"> <m:smallfrac val="off"> <m:dispdef/> <m:lmargin val="0"> <m:rmargin val="0"> <m:defjc val="centerGroup"> <m:wrapindent val="1440"> <m:intlim val="subSup"> <m:narylim val="undOvr"> </m:mathPr></w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:latentstyles deflockedstate="false" defunhidewhenused="true" defsemihidden="true" defqformat="false" defpriority="99" latentstylecount="267"> <w:lsdexception locked="false" priority="0" semihidden="false" unhidewhenused="false" qformat="true" name="Normal"> <w:lsdexception locked="false" priority="9" semihidden="false" unhidewhenused="false" qformat="true" name="heading 1"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 2"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 3"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 4"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 5"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 6"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 7"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 8"> <w:lsdexception locked="false" priority="9" qformat="true" name="heading 9"> <w:lsdexception locked="false" priority="39" name="toc 1"> <w:lsdexception locked="false" priority="39" name="toc 2"> <w:lsdexception locked="false" priority="39" name="toc 3"> <w:lsdexception locked="false" priority="39" name="toc 4"> <w:lsdexception locked="false" priority="39" name="toc 5"> <w:lsdexception locked="false" priority="39" name="toc 6"> <w:lsdexception locked="false" priority="39" name="toc 7"> <w:lsdexception locked="false" priority="39" name="toc 8"> <w:lsdexception locked="false" priority="39" name="toc 9"> <w:lsdexception locked="false" priority="35" qformat="true" name="caption"> <w:lsdexception locked="false" priority="10" semihidden="false" unhidewhenused="false" qformat="true" name="Title"> <w:lsdexception locked="false" priority="1" name="Default Paragraph Font"> <w:lsdexception locked="false" priority="11" semihidden="false" unhidewhenused="false" qformat="true" name="Subtitle"> <w:lsdexception locked="false" priority="22" semihidden="false" unhidewhenused="false" qformat="true" name="Strong"> <w:lsdexception locked="false" priority="20" semihidden="false" unhidewhenused="false" qformat="true" name="Emphasis"> <w:lsdexception locked="false" priority="59" semihidden="false" unhidewhenused="false" name="Table Grid"> <w:lsdexception locked="false" unhidewhenused="false" name="Placeholder Text"> <w:lsdexception locked="false" priority="1" semihidden="false" unhidewhenused="false" qformat="true" name="No Spacing"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 1"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 1"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 1"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 1"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 1"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 1"> <w:lsdexception locked="false" unhidewhenused="false" name="Revision"> <w:lsdexception locked="false" priority="34" semihidden="false" unhidewhenused="false" qformat="true" name="List Paragraph"> <w:lsdexception locked="false" priority="29" semihidden="false" unhidewhenused="false" qformat="true" name="Quote"> <w:lsdexception locked="false" priority="30" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Quote"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 1"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 1"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 1"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 1"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 1"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 1"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 1"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 1"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 2"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 2"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 2"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 2"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 2"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 2"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 2"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 2"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 2"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 2"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 2"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 2"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 2"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 2"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 3"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 3"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 3"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 3"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 3"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 3"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 3"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 3"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 3"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 3"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 3"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 3"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 3"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 3"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 4"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 4"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 4"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 4"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 4"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 4"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 4"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 4"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 4"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 4"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 4"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 4"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 4"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 4"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 5"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 5"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 5"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 5"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 5"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 5"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 5"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 5"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 5"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 5"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 5"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 5"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 5"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 5"> <w:lsdexception locked="false" priority="60" semihidden="false" unhidewhenused="false" name="Light Shading Accent 6"> <w:lsdexception locked="false" priority="61" semihidden="false" unhidewhenused="false" name="Light List Accent 6"> <w:lsdexception locked="false" priority="62" semihidden="false" unhidewhenused="false" name="Light Grid Accent 6"> <w:lsdexception locked="false" priority="63" semihidden="false" unhidewhenused="false" name="Medium Shading 1 Accent 6"> <w:lsdexception locked="false" priority="64" semihidden="false" unhidewhenused="false" name="Medium Shading 2 Accent 6"> <w:lsdexception locked="false" priority="65" semihidden="false" unhidewhenused="false" name="Medium List 1 Accent 6"> <w:lsdexception locked="false" priority="66" semihidden="false" unhidewhenused="false" name="Medium List 2 Accent 6"> <w:lsdexception locked="false" priority="67" semihidden="false" unhidewhenused="false" name="Medium Grid 1 Accent 6"> <w:lsdexception locked="false" priority="68" semihidden="false" unhidewhenused="false" name="Medium Grid 2 Accent 6"> <w:lsdexception locked="false" priority="69" semihidden="false" unhidewhenused="false" name="Medium Grid 3 Accent 6"> <w:lsdexception locked="false" priority="70" semihidden="false" unhidewhenused="false" name="Dark List Accent 6"> <w:lsdexception locked="false" priority="71" semihidden="false" unhidewhenused="false" name="Colorful Shading Accent 6"> <w:lsdexception locked="false" priority="72" semihidden="false" unhidewhenused="false" name="Colorful List Accent 6"> <w:lsdexception locked="false" priority="73" semihidden="false" unhidewhenused="false" name="Colorful Grid Accent 6"> <w:lsdexception locked="false" priority="19" semihidden="false" unhidewhenused="false" qformat="true" name="Subtle Emphasis"> <w:lsdexception locked="false" priority="21" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Emphasis"> <w:lsdexception locked="false" priority="31" semihidden="false" unhidewhenused="false" qformat="true" name="Subtle Reference"> <w:lsdexception locked="false" priority="32" semihidden="false" unhidewhenused="false" qformat="true" name="Intense Reference"> <w:lsdexception locked="false" priority="33" semihidden="false" unhidewhenused="false" qformat="true" name="Book Title"> <w:lsdexception locked="false" priority="37" name="Bibliography"> <w:lsdexception locked="false" priority="39" qformat="true" name="TOC Heading"> </w:LatentStyles> </xml><![endif]--><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Tabela normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-priority:99; mso-style-qformat:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin-top:0cm; mso-para-margin-right:0cm; mso-para-margin-bottom:10.0pt; mso-para-margin-left:0cm; line-height:115%; mso-pagination:widow-orphan; font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:"Times New Roman"; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin;} </style> <![endif]--> <p class="MsoNormal">Atenção, pessoal do RJ! </p> <p class="MsoNormal">Para o corajoso que estiver disposto a encarar o trânsito na Gávea na hora do rush .... </p><div style="text-align: justify;"> O pessoal da IBM vai ministrar uma palestra a qual pretende demonstrar a ferramenta Rational Team Concert. <a href="http://www.ibm.com/developerworks/newsletter/devcom/email/port/dW_Brazil_Rational_Team_Concert_10-24.html">No site da IBM aondhttp://www.blogger.com/img/blank.gife o evento esta sendo anunciado</a> cita que haverá demonstração de como criar um projeto e demonstrará os principais recursos da ferramenta. Acho que vale dar uma conferida.<br />O evento vai ser na PUC-RIO no RIO DE JANEIRO 28/10/11, 19h30<br /></div><span class="fullpost"><br />Auditório: B8 Edifício Frings – 8ª andar - Rua Marquês de São Vicente, 225 – Gávea<br /><br /><span style="font-weight:bold;">OBS:</span><br />O Palestrante será o Gerente de Desenvolvimento Sênior da IBM Estados Unidos que também é responsável pelos projetos “jazz.net” e “JazzHub”, Robin D Garside.<br /><!-- poste dentro desta tag o conteúdo que só aparecerá no link permanente do link --></span>GMotta ZNhttp://www.blogger.com/profile/14738149386892914626noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-8876383777430977842011-06-27T09:55:00.008-03:002011-10-07T17:32:01.887-03:00Tortoise/SVN Command Bat execute<div style="text-align: justify;">Pode ser uma boa solução automatizar os comandos que fazemos repetidamente pelo Tortoise. Por exemplo, o comando <span style="font-weight: bold;">update</span> nas pastas que você precisa atualizar. Existem casos em que, dependendo da configuração do SVN, somos obrigados a dar <span style="font-weight: bold;">update</span> em diretório por diretório, o que além de ser extremante chato ainda corremos o risco de esquecer alguma atualização.<br />Ainda existem os casos dos que não precisam dar o update na raiz de diretórios porque vai atualizar coisas demais que não são necessárias.<br /></div><div style="text-align: justify;">Em fim, se for o caso de um "bat" lhe ser útil para executar ações do Tortoise, segue o exemplo abaixo de um script que o <a href="http://estacaozn.blogspot.com/2009/05/cursor-with-parameters-in-plsql.html">Felipe Guerço</a> criou e agilizou bastante as coisas aqui. Obrigado Felipe!<br />Segue exemplo:<br /></div><br /><span class="fullpost"><br />Segue referência, <a href="http://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-automation.html">TortoiseSVN Commands</a> ...<br /><pre class="normal">@echo off<br /><br />FOR %%A IN (<br /> <br /> "C:\sorteJayk\projeto\GLADY07\Implementation"<br /> "C:\sorteJayk\projeto\GLADY07\Req"<br /> "C:\sorteJayk\projeto\GLADY08\AChecklist"<br /> "C:\sorteJayk\projeto\GLADY08\ZYZ"<br /> "C:\sorteJayk\projeto\GLADY08\Homologacao_interna"<br /> "C:\sorteJayk\projeto\GLADY09\Projetc_first"<br /> "C:\sorteJayk\projeto\GLADY09\Projetc_log"<br /> "C:\sorteJayk\projeto\GLADY09\Requist"<br /> "D:\PROJETOS sorteJayk\TI\ACESSO"<br /> "D:\PROJETOS sorteJayk\TI\GLADY"<br /> "D:\PROJETOS sorteJayk\TI\MVC"<br /> "D:\PROJETOS sorteJayk\TI\PTR_MAIN"<br /> <br />) DO "C:\Arquivos de programas\TortoiseSVN\bin\TortoiseProc.exe" /notempfile /command:update /path:%%A /closeonend:3<br /></pre><br /></span><br /><span class="fullpost"><br /></span>GMotta ZNhttp://www.blogger.com/profile/14738149386892914626noreply@blogger.com3tag:blogger.com,1999:blog-1939219507308718594.post-44133604528373348392010-07-30T11:29:00.005-03:002010-07-30T14:29:37.389-03:00Commitou o que não era pra comittar? Dá "Rollback"!Fala ai, pessoal!<br /><br />Se você é de TI, com certeza já passou por uma situação como essa: <br />Atualizando dados de uma tabela em um banco de dados Oracle, você alterou um ou vários campos com o valor errado, ou até mesmo excluiu um ou mais registros e deu COMMIT. E agora?!?! Fedeu?!?! NÃO!!! Você pode recuperar os dados...<br /><span class='fullpost'>Fala ai, pessoal!<br /><br />Se você é de TI, com certeza já passou por uma situação como essa: <br />Atualizando dados de uma tabela em um banco de dados Oracle, você alterou um ou vários campos com o valor errado, ou até mesmo excluiu um ou mais registros e deu COMMIT. E agora?!?! Fedeu?!?! NÃO!!! Você pode recuperar os dados através do Oracle Flashback.<br /><br />Para isso, a tarefa é muito simples. Basta fazer um select na tal tabela, normal mesmo, com os campos e condições que você quer e, no from, após o nome da tabela, colocar "as of timestamp systimestamp - interval 'X' minute", onde esse "X" é o tempo que passou desde a bobagem que você fez até agora.<br /><br />Por exemplo: Tenho uma tabela CLIENTE na minha base de dados Oracle e vou atualizar os clientes que não fazem compras há mais de 1 mês para Inativos.<br /><br />Então fiz lá meu update, atualizando o campo STATUS_CLIENTE para "I", depois de fazer um select que retorna os tais clientes que não compraram no último mês. Dei o COMMIT. Alguns desses clientes estavam com o STATUS "A" de Ativo, "D" de Devedor, "V" de VIP.<br /><br />Daí, chega o meu chefe, 30 minutos depois que eu fiz o update, dizendo que esse update não pode ser feito em clientes VIP e eu... DANÇO? Não! Eu faço o seguinte:<br /><br />select ID_CLIENTE<br />from CLIENTE<br />as of timestamp systimestamp - interval '30' minute<br />where STATUS_CLIENTE = 'V';<br /><br />PRONTO! Peguei todo mundo que tava com o campo STATUS_CLIENTE = 'V' 30 minutos atrás.<br />Com os IDs, eu faço um novo update, passando essa galera, que está com o STATUS = 'I', pra 'V'.<br /><br />Salvei meu emprego e deixei meu chefe feliz!<br /><br />PS.: Agradecimentos ao camarada Willian Rodrigues que ajudou nesse post!<br /><br />Abraço a todos!<br /><br /></span>Daniel Bezerrahttp://www.blogger.com/profile/03650858234225510922noreply@blogger.com9tag:blogger.com,1999:blog-1939219507308718594.post-91531714389530412242010-04-26T14:51:00.003-03:002010-04-26T15:17:41.761-03:00D2010 e Data Snap - Por Bruno LichotSobre o D2010:<br />Vale apena ficar antenado, <a href="http://www.scrumalliance.org/profiles/47586-bruno-lichot">Bruno Lichot</a> esta publicando uma série de artigos sobre DataSnap 2010 na revista <a href="http://www.activedelphi.com.br/mostra_edicao.php?ed=74">Acitve Delphi</a>.<br /><!-- coloque fora da tag abaixo os primeiros parágrafos do post - os que você que que apareçam no index --><span class='fullpost'> O exemplo publicado nesta edição pode ser baixado <a href="http://cc.embarcadero.com/author/795118">aqui!</a> <br /><br /><!-- poste dentro desta tag o conteúdo que só aparecerá no link permanente do link --></span>GMotta ZNhttp://www.blogger.com/profile/14738149386892914626noreply@blogger.com2tag:blogger.com,1999:blog-1939219507308718594.post-63004308948313116232009-08-24T18:04:00.016-03:002010-01-02T06:37:55.921-03:00Delphi - Intraweb: Passar e recuperar parâmetros entre requisições HTTP<div style="text-align: justify;">Inicie uma <a href="http://estacaozn.blogspot.com/2008/06/delphi-java-script-intraweb.html">aplicação Intraweb no Delphi</a>. O Assunto é sobre passar, e recuperar, parâmetros entre requisições HTTP. Especificamente, pretendo exemplificar como chamar uma outra aplicação web, sendo que nesta chamada passaremos parâmetros, os quais, obviamente, serão recuperados e processados pela aplicação que foi requisitada.<br /></div><br /><div style="text-align: justify;"><br />Neste artigo criaremos duas aplicações Intraweb ISAPI. Um delas (“AppEstacaoZNSubmit”) servirá para passar parâmetros para outra (“AppRequestQueryFieldsEstacaoZN”). Esta segunda por sua vez, recupera os valores destes parâmetros processa e os exibe. <br />Ok, definido o que pretendemos fazer passamos agora a parte prática.<br /><br />A seguir o código fonte da aplicação ISAPI que chama e passa os parâmetros. Salvei essa app de com o nome “<span style="font-weight: bold;">AppEstacaoZNSubmit</span>”.<br /></div><br /><span class="fullpost">O Form principal e único desta aplicação “IWUnit1.pas”:<br /><pre name="code" class="delphi"><br />unit IWUnit1;<br />{PUBDIST}<br /><br />interface<br /><br />uses<br /> IWAppForm, IWApplication, IWTypes, IWCompButton, Classes, Controls,<br /> IWControl, IWCompEdit, IWCompLabel;<br /><br />type<br /> TformMain = class(TIWAppForm)<br /> IWEdit1: TIWEdit;<br /> IWButton1: TIWButton;<br /> IWLabel1: TIWLabel;<br /> EdtURLZN: TIWEdit;<br /> IWLabel2: TIWLabel;<br /> procedure IWAppFormCreate(Sender: TObject);<br /> procedure IWButton1Click(Sender: TObject);<br /> public<br /> end;<br /><br />implementation<br />{$R *.dfm}<br /><br />uses<br /> ServerController, SysUtils, IWForm;<br /><br />procedure TformMain.IWAppFormCreate(Sender: TObject);<br />begin<br /> IWEdit1.Text := '';<br /> IWButton1.Caption := 'Enviar - ZN';<br /> IWLabel1.Caption := 'Digite o valor que será enviado';<br /> IWLabel2.Caption := 'Digite a URL da aplicação ISAPI que será chamada' +<br /> 'e exibirá o valor digitado acima.';<br /> EdtURLZN.Text := '';<br />end;<br /><br />procedure TformMain.IWButton1Click(Sender: TObject);<br />const<br /> AJSComando = 'window.open("%s?estacaoZnValor=%s")';<br />begin<br /> AddToInitProc(Format(AJSComando, [EdtURLZN.Text, IWEdit1.Text]));<br />end;<br /><br />end.<br /></pre><br /><br />Em seguida o “.dpr”:<br /><pre name="code" class="delphi"><br />library AppEstacaoZNSubmit;<br /><br />uses<br /> IWInitISAPI,<br /> ServerController in 'ServerController.pas' {IWServerController: TIWServerControllerBase},<br /> IWUnit1 in 'IWUnit1.pas' {formMain: TIWForm1};<br /><br />{$R *.RES}<br /><br />begin<br /> IWRun(TFormMain, TIWServerController);<br />end.<br /></pre><br /><br /><div style="text-align: justify;">Não editei nada no “IWServerController”, portanto após compilar e efetuar o <a href="http://estacaozn.blogspot.com/2008/09/deploy-de-uma-dll-isapi-no-iss-5.html">deploy</a> da “AppEstacaoZNSubmit.dll” no IIS damos por encerrada esta etapa do nosso exemplo.</div> <br /><br /><span style="font-weight:bold;">O próximo passo </span>é codificar a segunda aplicação. Logo, novamente inicie um <a href="http://estacaozn.blogspot.com/2008/06/delphi-java-script-intraweb.html">novo projeto Intraweb</a> ISAPI, salve com o nome de “AppRequestQueryFieldsEstacaoZN”. No evento “OnRender” do IWForm1 implementaremos o que especificamos anteriormente. Abaixo, o fonte da IWUnit1.pas:<br /><pre name="code" class="delphi"><br />unit IWUnit1;<br />{PUBDIST}<br /><br />interface<br /><br />uses<br /> IWAppForm, IWApplication, IWTypes, Classes, Controls, IWControl,<br /> IWCompLabel, IWCompListbox, IWCompMemo;<br /><br />type<br /> TformMain = class(TIWAppForm)<br /> IWLabel1: TIWLabel;<br /> procedure IWAppFormRender(Sender: TObject);<br /> public<br /> end;<br /><br />implementation<br />{$R *.dfm}<br /><br />uses<br /> ServerController, IWForm, SysUtils;<br /><br />procedure TformMain.IWAppFormRender(Sender: TObject);<br />const<br /> ZnMsg = 'www.estacaozn.blogspot.com O Valor recebido de "%s" é: %s';<br />begin<br /> IWLabel1.Caption := Format(ZnMsg,<br /> [WebApplication.Request.RemoteAddr,<br /> WebApplication.Request.QueryFields.Values['estacaoZnValor']]);<br /> IWLabel1.Font.Size := 20; <br />end;<br /></pre><br /><br />Vejamos o “.dpr” da “AppRequestQueryFieldsEstacaoZN.dpr”.<br /><br /><pre name="code" class="delphi"><br />library AppRequestQueryFieldsEstacaoZN;<br /><br />uses<br /> IWInitISAPI,<br /> ServerController in 'ServerController.pas' {IWServerController: TIWServerControllerBase},<br /> IWUnit1 in 'IWUnit1.pas' {formMain: TIWForm1};<br /><br />{$R *.RES}<br /><br />begin<br /> IWRun(TFormMain, TIWServerController);<br />end.<br /></pre><br /><br /><div style="text-align: justify;">Após proceder a implementação deste módulo conforme ilustrado acima, semelhante ao exemplo anterior compile e efetue o deploy da “AppRequestQueryFieldsEstacaoZN.dll” no ISS. <br />Feito isso já é possível testar. No browser, chame o diretório virtual definido no deploy da primeira aplicação (AppEstacaoZNSubmit.dll).</div> <br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_buFzmAtZPuc/SzpHfErYxBI/AAAAAAAABdo/5T68RUnYJno/s1600-h/chamaApp1.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 202px;" src="http://1.bp.blogspot.com/_buFzmAtZPuc/SzpHfErYxBI/AAAAAAAABdo/5T68RUnYJno/s320/chamaApp1.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5420723700651050002" /></a><br /><br /><div style="text-align: justify;">Digite no “IWEdit1” o valor para parâmetro “estacaoZnValor”, o qual será exibido. Digite também a URL da segunda aplicação no “EdtURLZN”, para somente então clicar no IWButton1.</div><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_buFzmAtZPuc/SzpIyoyq-HI/AAAAAAAABdw/e8WfOzD_PUE/s1600-h/DigitandoVaolores.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 202px;" src="http://1.bp.blogspot.com/_buFzmAtZPuc/SzpIyoyq-HI/AAAAAAAABdw/e8WfOzD_PUE/s320/DigitandoVaolores.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5420725136274421874" /></a><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_buFzmAtZPuc/SzpJlDt-hyI/AAAAAAAABd4/cPF7DtCQOww/s1600-h/ChamandoApp2.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 221px;" src="http://3.bp.blogspot.com/_buFzmAtZPuc/SzpJlDt-hyI/AAAAAAAABd4/cPF7DtCQOww/s320/ChamandoApp2.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5420726002495948578" /></a><br /><br /><div style="text-align: justify;">Na primeira aplicação, no evento OnClick do IWButton1, chamamos o método “<span style="font-weight:bold;">AddToInitProc</span>” de “TformMain”. Este método nos permite “colocar” scripts (Javascript) que serão executados quando a função “Initialize()" padronizada pelo framework Intraweb, quando o browser estiver interpretando a tag “<span style="font-weight:bold;">body</span>”, da página construída pelo Intraweb. No body <span style="font-weight:bold;">onload</span> é definida a chamada a função “Initialize()". </div><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_buFzmAtZPuc/SzpNmAS1s_I/AAAAAAAABeA/6ZIiWIlSW28/s1600-h/windowOpen.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 256px;" src="http://2.bp.blogspot.com/_buFzmAtZPuc/SzpNmAS1s_I/AAAAAAAABeA/6ZIiWIlSW28/s320/windowOpen.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5420730416803197938" /></a><br /><br /><pre name="code" class="javascript"><br />function Initialize() {<br />InitSubmitter();<br />StaticInit();<br />if (document.body.leftMargin < 0 && document.body.topMargin < 0) {<br /> document.body.leftMargin = 0;<br /> document.body.topMargin = 0;<br />}<br />InitRects(614, 451);<br />InitIWCLObjects();<br /><br />window.open("http://localhost/requesestacaozn/?estacaoZnValor=Landjah Estação ZN")<br />}<br /><br /></pre><br /><br /><div style="text-align: justify;">Então, podemos concluir que, no Intraweb quando você precisar executar uma função qualquer no evento “onload” no body basta para isso passá-la como parâmetro no método “AddToInitProc” do TIWForm em questão.<br /><br />Na segunda aplicação, “<span style="font-weight:bold;">AppEstacaoZNSubmit</span>”, o comando<br />"<span style="font-weight:bold;">WebApplication.Request.QueryFields.Values</span>" pode ser entendido da mesma forma que o Webbrocker trabalha com o protocolo http.<br />Podemos também recuperas outras variáveis através do objeto “WebApplication”, sua propriedade “Request”, tais como o “RemoteHost”, “UserAgent” e etc..<br /><br />Por hora é só .... Até a próx!!!<br /><br /></div><br /></span>ralencarhttp://www.blogger.com/profile/17947676750754221519noreply@blogger.com3tag:blogger.com,1999:blog-1939219507308718594.post-55766711526200262402009-08-24T16:39:00.020-03:002010-01-02T06:38:46.743-03:00JSP e Oracle - Para apresentar uma TreeviewOlá pessoal!<br /><br />Dando manutenção em um sistema java web com interface jsp precisei usar uma treeview para apresentar as categorias de produtos para o usuário. Vou relatar aqui a experiência.<br /><br /><br />As categorias estão modeladas no banco em uma tabela com autorelacionamento.<br /><br /><a href="http://3.bp.blogspot.com/_XV7fFbhKKpk/SpLuNPROyOI/AAAAAAAABME/JntxqtSggcQ/s1600-h/post-categoria.JPG"><img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 231px; DISPLAY: block; HEIGHT: 153px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5373619216610937058" border="0" alt="" src="http://3.bp.blogspot.com/_XV7fFbhKKpk/SpLuNPROyOI/AAAAAAAABME/JntxqtSggcQ/s320/post-categoria.JPG" /></a><br /><span class="fullpost"><br />No oracle para consultar uma table com autorelacionamento podemos utilizar a seguinte query:<br /><br /><pre class="sql" name="code"><br />select id, LEVEL, SYS_CONNECT_BY_PATH(nome, '@') as caminho<br />from categoria CONNECT BY parent_id = PRIOR id START WITH id = categoria_inicial<br /></pre><br /><br />A categoria_inicial é a primeira categoria de uma árvore, nesse sistemas existem várias árvores de categorias.<br /><br />O resultado fica assim para a categoria_inicial igual a 30:<br /><pre class="java" name="code"><br />id level caminho<br />30 1 @Material de escritório<br />31 2 @Material de escritório@Informática<br />34 3 @Material de escritório@Informática@Tinta<br />55 4 @Material de escritório@Informática@Tinta@Tinta Impressoras<br />60 3 @Material de escritório@Informática@Armazenamento<br />63 4 @Material de escritório@Informática@Armazenamento@DAT/DLT/DVD/DDS<br />64 4 @Material de escritório@Informática@Armazenamento@Disquetes<br />92 3 @Material de escritório@Informática@Teste<br />93 4 @Material de escritório@Informática@Teste@Teste1<br />113 4 @Material de escritório@Informática@Teste@Teste2<br />120 4 @Material de escritório@Informática@Teste@Test3<br /></pre><br />Ai no java criei uma classe para representar a estrutura da categoria, ficou assim:<br /><pre class="java" name="code"><br />public class CategoriaTreeView {<br /> public String id;<br /> public int level;<br /> public String path;<br /><br /> public CategoriaTreeView(String id, int level, String path){<br /> this.id = id;<br /> this.level = level;<br /> this.path = path;<br /> }<br />}<br /></pre><br /><br />Como essa classe vai ser utilizada somente como uma estrutura de dados para representar o dado que será exibido na tela ela não tem gets e sets. Nem toda classe java precisa ter gets e sets. Gets e sets aqui são desnecessários e não acresentam nada. Acredite. Mas isso é assunto para outro post.<br /><br />Também tenho um DAO que acessa o banco e entrega um List com os objetos CategoriaTreeView.<br /><br />Antes disso fiz uma pesquisa na internet sobre como criar uma treeview no jsp (ou html) e encontrei o <a href="http://bassistance.de/jquery-plugins/jquery-plugin-treeview/">jQuery plugin: Treeview</a> que transforma uma lista não ordenada do html <ul> em uma árvore.<br /><br />Agora o problema é transformar a minha coleção de CategoriaTreeView em uma lista não ordenada com <ul> e <li>. Para isso eu criei a seguinte função recursiva que retorna uma String que será utilizada dentro do html:<br /><br /><pre class="java" name="code"><br />private String processa(int atual, List<CategoriaTreeView> lista){<br /> if(lista == null) return "";<br /> String out = "";<br /> if(lista.size() == 0) {<br /> if(atual > 0){<br /> out += "</li>\n";<br /> out += "</ul>\n";<br /> out += processa(atual - 1, lista);<br /> }<br /> }else if(lista.size()>0){<br /> CategoriaTreeView item = lista.remove(0);<br /> if(item.level == atual){<br /> out += "</li>\n";<br /> out += "<li><span>" + subString(item.level, item.path) + "</span>\n";<br /> out += processa(item.level, lista);<br /> }else if(item.level > atual){<br /> out += "<ul>\n";<br /> out += "<li><span>" + subString(item.level, item.path) + "</span>\n";<br /> out += processa(item.level, lista);<br /> }else if(item.level < atual){<br /> out += "</li>\n";<br /> out += "</ul>\n";<br /> // adiciono o cara de volta na lista pois ainda não foi processado. estou voltando um nivel na árvore.<br /> lista.add(0, item);<br /> out += processa(atual - 1, lista);<br /> }<br /> }<br /> return out;<br />}<br /></pre><br />Também temos a função para retornar a categoria de dentro do caminho:<br /><br /><pre class="java" name="code"><br />private String subString(int i, String s){<br /> String[] ss = s.split("@");<br /> return ss[i];<br />}<br /></pre><br /><br />Dentro do meu servlet eu tenho o seguinte código:<br /><pre class="java" name="code"><br />ArrayList categorias = dao.categorias(categoria_inicial);<br />String treeView = processa(0, categorias);<br />treeView = treeView.replaceFirst("<ul>", "<ul id=\"browser\">");<br />request.setAttribute("treeView", treeView);<br /></pre><br />Para exibir a treeview no jsp eu utilizei o exemplo simple.html que vem no download do jQuery plugin: Treeview. A única mudança foi que eu fiz o download do <a href="http://jquery.com/">jquery </a>ao invés de usar o link direto do ajax.googleapis.com. <br /><br />Adicionei o seguinte ao jsp:<br /><br /><pre class="java" name="code"><br /><link rel="stylesheet" href="../jquery.treeview.css" /><br /><link rel="stylesheet" href="../red-treeview.css" /><br /><link rel="stylesheet" href="screen.css" /><br /><br /><script type="text/javascript" src="jquery-1.3.2.min.js"></script><br /><script src="../lib/jquery.cookie.js" type="text/javascript"></script><br /><script src="../jquery.treeview.js" type="text/javascript"></script><br /><br /><script type="text/javascript"><br />$(document).ready(function(){<br /> $("#browser").treeview({control: "#treecontrol", animated:"normal", persist: "cookie"});<br />});<br /></script><br /><br /><%<br />String s = (String)request.getAttribute("treeView");<br />if(s != null && !s.trim().equals("")){<br />%><br /><tr><br /> <td><br /> <br><br /> <div id="treecontrol"><br /> <a title="Collapse the entire tree below" href="#">Fechar Tudo</a><br /> <a title="Expand the entire tree below" href="#">Abrir Tudo</a><br /> </div><br /><br /> </td><br /></tr><br /><tr><br /> <td><br /> <br><br /> <div><%= s %></div><br /> </td><br /></tr><br /><%<br />}<br />%><br /></pre><br /><br />O resultado fica parecido com esse demo que está no site.<br /><br /><a href="http://2.bp.blogspot.com/_XV7fFbhKKpk/SpLxrojP6oI/AAAAAAAABMM/Ntg4rTDr_V0/s1600-h/post-treeview.JPG"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 155px; height: 187px;" src="http://2.bp.blogspot.com/_XV7fFbhKKpk/SpLxrojP6oI/AAAAAAAABMM/Ntg4rTDr_V0/s320/post-treeview.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5373623037328353922" /></a><br /><br />Abraços, Rodrigo Alencar.<br /></span>ralencarhttp://www.blogger.com/profile/17947676750754221519noreply@blogger.com1tag:blogger.com,1999:blog-1939219507308718594.post-82865659855054779062009-05-23T11:31:00.002-03:002009-05-23T11:42:10.999-03:00Cursor with parameters in PL/SQL<a href="http://estacaozn.blogspot.com/2009/05/cursor-com-parametros-em-plsql.html">Ver este post em Portugûes</a><br /><br />Here I'm gonna show another technique to work with cursors in PL/SQL. I had to do something at work where it was very useful: cursor that take arguments.<br /><br /><span class='fullpost'>The biggest advantages of parametrized queries is that the server doesn't have to pass through the parse and plan phases ever again (after the first time, of course) and the compile-time checking for syntax errors (when we use string queries we only know any syntax errors in runtime).<br /><br />That said let's go to examples:<br /><br /><pre name="code" class="sql"><br />cursor ProductCursor(pname in varchar2) is<br /> select *<br /> from product<br /> where name like pname;<br /></pre><br /><br />Nice, isn't it? It's like a procedure in terms of syntax. And opening the cursor is like this:<br /><br /><pre name="code" class="sql"><br />open ProductCursor('A%');<br /></pre><br /><br />It'll open the cursor with all the products which name starts with 'A'.<br /><br />We can create a rowtype based var from this cursor:<br /><br /><pre name="code" class="sql"><br />prod ProductCursor%rowtype;<br /></pre><br /><br />Now I'm gonna join it all in a script:<br /><br /><pre name="code" class="sql"><br />declare<br /> -- Cursor<br /> cursor ProductCursor(pname in varchar2) is<br /> select *<br /> from product<br /> where name like pname;<br /><br /> -- Simple loop<br /> prod ProductCursor%rowtype;<br /><br /> -- bulk collect loop<br /> type Tprods is table of ProductCursor%rowtype;<br /> prods Tprods;<br /> i integer;<br /><br />begin<br /> -- simple loop<br /> open ProductCursor('A%');<br /> loop<br /> fetch ProductCursor into prod;<br /> exit when ProductCursor%notfound;<br /> DBMS_OUTPUT.put_line(prod.nome);<br /> -- other commands<br /> end loop;<br /> close ProductCursor;<br /><br /> -- bulk collect loop<br /> open ProductCursor('A%');<br /> fetch ProductCursor bulk collect into prods;<br /> for i in prods.first .. prods.last loop<br /> DBMS_OUTPUT.put_line(prods(i).nome);<br /> -- another commands using prods(i)<br /> end loop;<br /> close ProductCursor;<br />end;<br /></pre><br /><br />Cool, isn't it? See you next time.Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-79150614554649506822009-05-23T11:09:00.005-03:002009-05-23T11:44:44.550-03:00Cursor com parâmetros em PL/SQL<a href="http://estacaozn.blogspot.com/2009/05/cursor-with-parameters-in-plsql.html">View this post in English</a><br /><br />Aqui vou mostrar outra técnica para trabalhar com cursores em PL/SQL. Eu tive que fazer um trabalho recentemente onde isso foi muito útil: Cursores que aceitam argumentos.<br /><br /><span class='fullpost'>As maiores vantagem de usar queries parametrizadas no banco de dados é que o servidor não precisa fazer o parse e traçar um plano de execução (ele só faz isso na primeira vez que a query é executada) e ela fica certa em tempo de compilação (ao contrário das queries em string que nós só sabemos se há um erro de sintaxe em tempo de execução).<br /><br />Dito isso vamos a um exemplo:<br /><br /><pre name="code" class="sql"><br />cursor ProdutoCursor(pnome in varchar2) is<br /> select *<br /> from produto<br /> where nome like pnome;<br /></pre><br /><br />Legal, não? A sintaxe fica muito parecida com uma procedure. E o método de abrir o cursor também é legal:<br /><br /><pre name="code" class="sql"><br />open ProdutoCursor('A%');<br /></pre><br /><br />Aqui vai abrir o cursor trazendo todos os produtos onde o nome começa com a letra 'A'.<br /><br />Podemos ainda criar um rowtype a partir deste cursor:<br /><br /><pre name="code" class="sql"><br />prod ProdutoCursor%rowtype;<br /></pre><br /><br />Agora vou criar um script para juntar tudo:<br /><br /><pre name="code" class="sql"><br />declare<br /> -- Cursor<br /> cursor ProdutoCursor(pnome in varchar2) is<br /> select *<br /> from produto<br /> where nome like pnome;<br /><br /> -- Para loop simples<br /> prod ProdutoCursor%rowtype;<br /><br /> -- Para loop com bulk collect<br /> type Tprods is table of ProdutoCursor%rowtype;<br /> prods Tprods;<br /> i integer;<br /><br />begin<br /> -- Loop simples<br /> open ProdutoCursor('A%');<br /> loop<br /> fetch ProdutoCursor into prod;<br /> exit when ProdutoCursor%notfound;<br /> -- comandos a serem executados com o registro prod<br /> DBMS_OUTPUT.put_line(prod.nome);<br /> end loop;<br /> close ProdutoCursor;<br /><br /> -- Loop com bulk collect<br /> open ProdutoCursor('A%');<br /> fetch ProdutoCursor bulk collect into prods;<br /> for i in prods.first .. prods.last loop<br /> -- comandos a serem executaos com o registro prods(i)<br /> DBMS_OUTPUT.put_line(prods(i).nome);<br /> end loop;<br /> close ProdutoCursor;<br />end;<br /></pre><br /><br />Muito legal, né? Até a próxima.<br /><br /></span>Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-13366212842838361352009-05-23T10:49:00.003-03:002009-05-23T10:58:20.086-03:00Generics - A great addition to .Net<a href="http://estacaozn.blogspot.com/2009/05/generics-uma-grande-adicao-net.html">Ver este post em Portugûes</a><br /><br />Hello. In this post I'll show something very nice about .Net: Generics.<br /><br />First, I'll show a simple struct in order to explain the feature:<br /><br /><pre name="code" class="csharp"><br />struct Person {<br /> public string Name;<br /> public string Address;<br /> public string Zip;<br />}<br /></pre><br /><br /><span class="fullpost">We have here a classic example of a data struct. Here we define fields with their respective data types (we're talking here about a strongly typed language). That means we have to provide the data type of the attributes at compile time. But, what if we could let the (struct's) user define what type s/he wants to use in their struct? How so? e.g.: A struct, two fields and their data type is open to the user to specify and set the attribute, making it "appear" a weakly typed language, but with the advantage of type checking at compile time.<br /><br />Let's take a look at an example:<br /><br /><pre name="code" class="csharp"><br />struct Pair<TClass1, TClass2><br /> where TClass1 : class<br /> where TClass2 : class {<br /><br /> public TClass1 obj1;<br /> public TClass2 obj2;<br />}<br /></pre><br /><br />Here comes the generics: We define a struct, asking the user to provide which clases will will represent the TClass1 and TClass2, which we are defining that have to inherit the class object and it automatically defines what data type that fields inside will accept<br /><br />The nice part is when we start to use this structure. Let's see another code block:<br /><br /><pre name="code" class="csharp"><br /> class Customer {<br /> public int ID;<br /> public string Name;<br /><br /> public override string ToString() {<br /> return string.Format("Customer ID = {0}, Name = {1}", ID, Name);<br /> }<br /> }<br /><br /> class Product {<br /> public int ID;<br /> public string Name;<br /><br /> public override string ToString() {<br /> return string.Format("Product ID = {0}, Name = {1}", ID, Name);<br /> }<br /> }<br /><br /> struct Pair<TClass1, TClass2><br /> where TClass1 : class<br /> where TClass2 : class {<br /><br /> public TClass1 obj1;<br /> public TClass2 obj2;<br /> }<br /><br /> class Program {<br /> static void Main(string[] args) {<br /><br /> var c = new Customer { ID = 1, Name = "Felipe" };<br /> var p = new Product { ID = 1, Name = "Caneta BIC" };<br /><br /> var pair = new Pair<Customer, Product>() { obj1 = c, obj2 = p };<br /><br /> Console.WriteLine(pair.obj1.ToString());<br /> Console.WriteLine(pair.obj2.ToString());<br /><br /> }<br /> }<br /></pre><br /><br />The braces after the new instanct are a new notation of C# that allows us to create new instances of classes and set values to public fields in the same instruction.<br /><br />In the progem we create instances of Customer and Product and define these types as the relevant types for the struct Pair. Note that, after we define the struct with these types we can only inform instances of these types for the specific fields. The compiler doens't let us inform any other value; and even the IntelliSense indicates correctly.<br /><br />I hope you all liked this post and again, sorry for my english, as I am no native English speaker. Thank you very much and see you next time.<br /></span>Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-63634693195751985542009-05-23T10:26:00.008-03:002009-05-23T10:58:01.983-03:00Generics - Uma Grande adição a .Net<a href="http://estacaozn.blogspot.com/2009/05/generics-great-addition-to-net.html">View this post in English</a><br /><br />Olá a todos. Neste post vou mostrar algo muito legal a respeito da .Net: Generics.<br /><br />Primeiro vou preparar o terreno para explicar o recurso: Vamos ter como exemplo uma estrutura básica:<br /><br /><pre name="code" class="csharp"><br /><br />struct Pessoa {<br /> public string Nome;<br /> public string Endereco;<br /> public string CEP;<br />}<br /></pre><br /><br /><span class='fullpost'>Nós temos aqui um exemplo clássico de uma estrutura de dados. Nela nós definimos campos com os tipos definidos de dados (claro, numa linguagem fortemente tipada). Isso significa que nós temos que fornecer os tipos de dados na hora em que a criamos. Mas, E se pudéssemos criar uma estrutura de dados onde o usuário (da estrutura, claro) escolha os tipos de dados dos atributos? Como assim? A estrutura possui dois atributos e o usuário diz de que tipo de dados são estes atributos antes de definir seus valores, tendo "aparência" de linguagem de tipagem fraca, mas com a vantagem de checagem de tipos em tempo de compilação.<br /><br />Nada melhor para explicar do que um exemplo prático:<br /><br /><pre name="code" class="csharp"><br />struct Par<TClasse1, TClasse2><br /> where TClasse1 : class<br /> where TClasse2 : class {<br /><br /> public TClasse1 obj1;<br /> public TClasse2 obj2;<br />}<br /></pre><br /><br />Aqui vem o uso dos genéricos: Definimos uma estrutura, pedido que o usuário forneça dois tipo, TClasse1 e TClasse2, que dizemos abaixo que elas devem ser descendentes de object (ou object) e isso vira uma classe para ser referenciada dentro da struct.<br /><br />A parte legal vem na hora em que começamos a utilizar esta estrutura. Abaixo tem mais um bloco de código:<br /><br /><pre name="code" class="csharp"><br /> class Cliente {<br /> public int ID;<br /> public string Nome;<br /><br /> public override string ToString() {<br /> return string.Format("Cliente ID = {0}, Nome = {1}", ID, Nome);<br /> }<br /> }<br /><br /> class Produto {<br /> public int ID;<br /> public string Nome;<br /><br /> public override string ToString() {<br /> return string.Format("Produto ID = {0}, Nome = {1}", ID, Nome);<br /> }<br /> }<br /><br /> struct Par<TClasse1, TClasse2><br /> where TClasse1 : class<br /> where TClasse2 : class {<br /><br /> public TClasse1 obj1;<br /> public TClasse2 obj2;<br /> }<br /><br /> class Program {<br /> static void Main(string[] args) {<br /><br /> var c = new Cliente { ID = 1, Nome = "Felipe" };<br /> var p = new Produto { ID = 1, Nome = "Caneta BIC" };<br /><br /> var par = new Par<Cliente, Produto>() { obj1 = c, obj2 = p };<br /><br /> Console.WriteLine(par.obj1.ToString());<br /> Console.WriteLine(par.obj2.ToString());<br /><br /> }<br /> }<br /></pre><br /><br /><br />As chaves depois da nova instância das classes é uma facilidade do C# que nos permite criar uma nova instância de uma classe e atribuir valores aos membros públicos naquele momento.<br /><br />Dentro do programa nós criamos instâncias das classes Cliente e Produto e definimos como atributos da nossa estrutura para usarmos depois. O detalhe é que, assim que nós definimos que as classes da estrutura são Cliente e Produto, o compilador não deixa nenhum outro valor; até o IntelliSense indica corretamente.<br /><br />Espero que que vocês tenham gostado deste post e o assunto tenha despertado em vocês o interesse que despertou em mim. Muito obrigado e até a próxima.<br /></span>Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-25642663604511493802009-05-23T10:12:00.002-03:002009-05-23T10:23:01.566-03:00Você já isntalou o IE8?Como o título já diz: eu já. A microsoft colocou o Internet Explorer 8 como atualização crítica para o Windows XP e cá estamos nós usuários deste maravilhoso sistema operacional atualizando.<br /><br />O navegador é muito bonitinho: A interface é boa, tem depurador de Javascript (já dava para fazer isso anteriormente, mas agora está incorporado no navegador), etc. Mas um problema assola alguns usuários (como minha digníssima que ainda usa muito o Internet Explorer): o teclado.<br /><br />Alguns usuários têm notado que no IE 8 o teclado não responde legal. Na minhma máquina acontece isso <a href='http://forum.clubedohardware.com.br/dica-windows-xp/p3565124#post3565124'>Neste link</a> [forum.clubedohardware.com.br] há uma discussão do problema e possíveis causas e soluções.<br /><br />Alguns males vêm para bem: Agora minha patroa já está começando a usar o querido por todos Firefox para navegar, graças as minhas insistentes investidas. Ha ha. Aproveitei essa hora para trazê-la ao lado da luz.<br /><br />Abraços e até a próxima!Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com1tag:blogger.com,1999:blog-1939219507308718594.post-60806197050598188452009-05-15T11:34:00.008-03:002009-05-15T14:32:46.999-03:00JclStrings - StrPadRight, StrPadLeft<div align="justify">È uma biblioteca da JCL (<a href="http://estacaozn.blogspot.com/2007/01/projeto-jedi.html">Jedi</a>), como o nome da “unit” indica, para trabalhar com strings. Esteja certo de que, tudo e qualquer coisa que você pensar fazer com strings eles implementaram nesta biblioteca. </div><span class="fullpost"><br /><div align="justify">Caso você, desafortunadamente, precise de alguma função para trabalhar com strings e não encontre na JclStrings, provavelmente é porque você está querendo fazer alguma variação do “<a href="http://desciclo.pedia.ws/wiki/Bozosort">BozoSort</a>” (rsrsrs, neste caso <a href="http://nerdson.com/blog/category/bozo/">procure o Bozo </a>ou o Jaspion). Quem me apresentou a ela foi o <a href="http://singularsistemas.com.br/blog/">Malta</a>, desde então nunca mais me separei dela. A seguir, um exemplo de como concatenar caracteres a esquerda ou a direita de uma string de tamanho limitado. Ou seja, mantendo o tamanho (Length) da string inalterado.</div><br /><pre name="code" class="delphi"><br />unit Unit1;<br /><br />interface<br /><br />uses<br /> Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br /> Dialogs, StdCtrls, Buttons;<br /><br />type<br /> TForm1 = class(TForm)<br /> BitBtn1: TBitBtn;<br /> procedure BitBtn1Click(Sender: TObject);<br /> private<br /> { Private declarations }<br /> public<br /> { Public declarations }<br /> end;<br /><br />var<br /> Form1: TForm1;<br /><br />implementation<br /><br />{$R *.dfm}<br /><br />uses jclStrings, Math;<br /><br />procedure TForm1.BitBtn1Click(Sender: TObject);<br />var<br /> ZnDt, ZnNum: String;<br /> ADay, AMonth, AYear: Word;<br />begin<br /><br /> DecodeDate(Date, AYear, AMonth, ADay);<br /> ZnDt := Format('%s%s%s', [ StrPadLeft(IntToStr(ADay), 2, '0'),<br /> StrPadLeft(IntToStr(AMonth), 2, '0'), IntToStr(AYear)]);<br /> Self.Canvas.TextOut(12, 32, ZnDt);<br /><br /> Randomize;<br /> ZnNum := IntToStr(RandomRange(0, 50000));<br /> ZnNum := StrPadRight(ZnNum, 6, 'X');<br /> Self.Canvas.TextOut(12, 52, ZnNum);<br /><br />end;<br /></pre><br /><br />Por falar me Bozo, lembrei de uma coisa (rsrsrs)..... Esse exemplo com datas, não foi uma boa idéia!?!?!?!??!?! <br />Na verdade ... esse exemplo com datas foi ótimo! Para demonstrarmos como não fazer ... uma coisa que provavelmente todo desenvolvedor, em algum momento, vai precisar fazer (rsrsrs).<br />Por favor, não façam assim (concatenar zeros a direita do dia e do mês).<br />Por isso, preste a tenção para substituir o código da linha 35 ...<br /><pre name="code" class="delphi"><br /> ZnDt := Format('%s%s%s', [ StrPadLeft(IntToStr(ADay), 2, '0'), <br /> StrPadLeft(IntToStr(AMonth), 2, '0'), IntToStr(AYear)]); <br /></pre><br />Por <pre name="code" class="delphi"><br /> ZnDt := Format('%.2d%.2d%.4d', [ADay, AMonth, AYear]);<br /></pre><br />Bem melhor agora!!!!!!!<br /><br />Se você veio procurar "StrPadLeft" para trabalhar com datas, se deu bem! Use o "Format('%.2d%.2d%.4d, [ADay, AMonth, AYear])". <br />O Malta, mais uma vez, nos emprestou o conhecimento dele.<br />Grato! <br /></span>GMotta ZNhttp://www.blogger.com/profile/14738149386892914626noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-89614059284658327842009-04-29T12:07:00.005-03:002009-05-01T15:31:48.297-03:00Controle de Versão - "Seus problemas acabaram!"<!-- coloque fora da tag abaixo os primeiros parágrafos do post - os que você que que apareçam no index --><br />Você é aquele cara que, pra controlar as versões do seu sistema, zipa os fontes e nomeia com o número da versão? Ou paga um software caríssimo de controle de versão? Ou toma uma coça pra instalar um controlador gratuito? SEUS PROBLEMAS ACABARAM!!!<br /><span class='fullpost'><br /><br />Apresento-lhes os dois softwares que vão resolver todos os seus problemas: VisualSVN + TortoiseSVN.<br /><br />O primeiro é um servidor Windows de Subversion, um controlador de versões gratuito muito bom. Muito simples de instalar, esquema Windows: next, next, next, finish.<br />Muito fácil também de manusear. Basta criar os repositórios e os usuários que acessam esses repositórios.<br />Então aqui vai o link do VisualSVN: <a href=http://www.visualsvn.com/server/>http://www.visualsvn.com/server/</a><br />O segundo é um cliente de Subversion muito, muito bom mesmo. Integra-se ao Windows Explorer e é super simples de usar também. Basicamente, você deve criar uma pasta que apontará para o repositório do VisualSVN. Depois do TortoiseSVN instalado, quando você clicar com o botão direito sobre a pasta pelo Windows Explorer, vai aparecer uma opção chamada "SVN Checkout...".<br />Colocou arquivos/diretórios novos dentro da pasta, "Add". Quer subir os fontes? "Commit". Quer atualizar seus fontes? "Update".<br />No próximo post sobre o assunto, eu vou dar uma passada mais detalhada sobre esta ferramenta.<br />Chega de blá, blá, blá. Lá vai o link: <a href=http://tortoisesvn.net/>http://tortoisesvn.net/</a><br /><br />Então é isso. Abraço a todos e até o próximo post!<br /></span>Daniel Bezerrahttp://www.blogger.com/profile/03650858234225510922noreply@blogger.com3tag:blogger.com,1999:blog-1939219507308718594.post-59680132991046608552009-04-25T19:01:00.004-03:002009-04-26T05:50:07.748-03:00Ajax/JSON & Delphi technologies– Webbrocker, Intraweb (ISAPI), IWTemplateProcessorHTML com CSS<div align="justify">Estou com muita pressa, portanto serei o mais sucinto o possível ...<br />O objetivo deste artigo é documentar uma solução desenvolvida para atender um cliente.<br />Vamos criar um serviço de <a href="http://estacaozn.blogspot.com/2008/04/mdulo-de-consulta-para-crud-win32-for.html">consulta</a> 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 <a href="http://www.blogger.com/JavaScript%20Object%20Notation%20http://json.org/">Json</a> (<a href="http://pt.wikipedia.org/wiki/JSON">Wik</a>) (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. </div><br /><br /><span style="font-weight:bold;">Não sei, ou sei muito pouco sobre o que vc esta falando, Gerson</span>. Então veja:<br /><a href="http://www.bergbrandt.com.br/v1/asp/mostra_artigo.asp?artigo_id=14">Pesquisa 1</a><br /><a href="http://ctrlc.blog.br/2007/10/json-javascript-object-notation.html">Pesquisa 2</a><br /><a href="http://conferences.embarcadero.com/article/33365">Marco Cantù AJax XML/DOM</a><br />Neste artigo o Cantù mostra como aproveitar o XMLData do TClientDataSet no DOM/XML (mto legal para delpheros).<br /><a href="http://ajax.marcocantu.com/doc/DelphiAndAjax.html">Marco Cantù Artigo Ajax</a><br /><a href="http://json.org/">Json</a><br /><br /><div align="justify">Em seguida, desenvolveremos o aplicativo cliente, a camada de interface, em Delphi/<span style="font-weight:bold;">Intraweb</span>, aonde implementaremos uma função Javascript. Nela usaremos o <span style="font-weight:bold;">XMLHttpRequest</span> do javascript de forma <span style="font-weight:bold;">assíncrona</span>.<br /></div><div align="center"><br /><span style="color:#009900;"><br /><strong>Mãos à Obra, Estação ZN!</strong></span></div><br /><br /><span style="font-weight:bold;">Server-Side development</span><span class="fullpost"><br /><br /><div align="justify">Inicie um projeto Webbrocker no Delphi. Menu ►File ►New ►Other ► Web Server Application.</div><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_buFzmAtZPuc/SfQM8Jn3qmI/AAAAAAAABcg/LfI7z3f7xp4/s1600-h/NewWebServerApplication.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 266px;" src="http://2.bp.blogspot.com/_buFzmAtZPuc/SfQM8Jn3qmI/AAAAAAAABcg/LfI7z3f7xp4/s320/NewWebServerApplication.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5328898486600968802" /></a><br /><br /><div align="justify"><br />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á:</div><br /><br /><pre name="code" class="sql"><br /> select * from Customers<br /> where CompanyName like :CompanyName<br /></pre><br /><br /><div align="center"><span style="font-weight:bold;">Criando a Webbrocker Action</span> (WebAction)</div><br /><div align="justify">Selecione o WebModule1, de maneira que suas propriedades sejam listadas no Object Inspector. Crie uma Action e configure suas propriedades conforme ilustrado abaixo:<br /></div><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_buFzmAtZPuc/SfQNIDU0giI/AAAAAAAABco/lS8QwuD9Wkw/s1600-h/CStringdeConexaoSQLServerNorthwind.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 255px; height: 320px;" src="http://3.bp.blogspot.com/_buFzmAtZPuc/SfQNIDU0giI/AAAAAAAABco/lS8QwuD9Wkw/s320/CStringdeConexaoSQLServerNorthwind.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5328898691068887586" /></a><br /><br />Evento OnAction da Action “<span style="font-weight:bold;">ZnConsClientes</span>”:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_buFzmAtZPuc/SfQPSI5mc6I/AAAAAAAABcw/eqrLsmBelpY/s1600-h/ObjInspectorWebModuleActions.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 202px; height: 320px;" src="http://1.bp.blogspot.com/_buFzmAtZPuc/SfQPSI5mc6I/AAAAAAAABcw/eqrLsmBelpY/s320/ObjInspectorWebModuleActions.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5328901063387280290" /></a><br /><pre name="code" class="delphi"><br />uses<br /> Math, StrUtils;<br /><br />procedure TWebModule1.WebModule1ZnConsClientesAction(Sender: TObject;<br /> Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);<br />const<br /> ZnTag = '%s:%s';<br />var<br /> StrStatment: String;<br /> i, CodRetorno: Integer;<br />begin<br /> with ClientDataSet1 do<br /> begin<br /> Params[0].AsString := '%' + Request.QueryFields.Values['znNomeCli']+ '%';<br /> try<br /> Open;<br /> CodRetorno := IfThen(IsEmpty, -1, 1);<br /> StrStatment := StrStatment +<br /> Format(ZnTag, ['codretornoZn',<br /> IntToStr(CodRetorno)]);<br /><br /> if CodRetorno = 0 then Exit;<br /><br /> for i := 0 to Pred(FieldCount) do<br /> begin<br /> StrStatment := StrStatment + ','+<br /> Format(ZnTag, [LowerCase(ClientDataSet1.Fields[i].FieldName),<br /> IfThen((ClientDataSet1.Fields[i].AsString = ''), QuotedStr('-'),<br /> QuotedStr(ClientDataSet1.Fields[i].AsString))]);<br /> end;<br /><br /> finally<br /> Close;<br /> Response.Content := Format('{%s}',[StrStatment]);<br /> end;<br /> end;<br />end;<br /> </pre><br /><div align="justify"><br />Para usar as versões sobrecarregadas da função “<span style="font-weight:bold;">IfTehn</span>” precisamos, para este exemplo, declarar (fazer uses das ...) as units “Math” e “StrUtils” (observe na linha 2 do trecho acima).<br />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 (<a href="http://estacaozn.blogspot.com/2008/09/deploy-de-uma-dll-isapi-no-iss-5.html">Deploy de uma dll ISAPI</a>). Vou criar o diretório virtual no IIS com o nome de “ajaxjsonzn”.</div></span><br />Após ter tido sucesso em realizar o deploy, vamos testar.<br />Para isso digitar no browser "http://localhost/ajaxjsonzn/?znNomeCli=Cactus" para se emocionar ao ver o que acabamos de criar.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_buFzmAtZPuc/SfQPn8GdboI/AAAAAAAABc4/-ldUntKMgFU/s1600-h/TestandoAAppServnoBrowser.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 138px;" src="http://3.bp.blogspot.com/_buFzmAtZPuc/SfQPn8GdboI/AAAAAAAABc4/-ldUntKMgFU/s320/TestandoAAppServnoBrowser.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5328901437908676226" /></a><br /><span class="fullpost">Veja a string retornada pela nossa aplicação servidora Webbrocker:<br /><pre><br />{codretornoZn:1,customerid:'CACTU',companyname:'Cactus Comidas para llevar',contactname:'Patricio Simpson',<br /> contacttitle:'Sales Agent',address:'Cerrito 333',city:'Buenos Aires',region:'-',<br /> postalcode:'1010',country:'Argentina',phone:'(1) 135-5555',fax:'(1) 135-4892'}<br /></pre> <br /><br /><br /><span style="font-weight:bold;">Cliente-Side development</span><br /><br /><div align="justify">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. <br />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:</div><br /><pre name="code" class="javascript"><br /><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><br /><html xmlns="http://www.w3.org/1999/xhtml"><br /><head><br /><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><br /><title>Untitled Document</title><br /><style type="text/css"><br /><!-- <br />.AreaTexto {<br /> font-family: "Comic Sans MS", "Courier New", Georgia;<br /> width: 420px;<br /> height:540px;<br /> background-color:#FFFF38;<br />}<br />--><br /><br /></style><br /><script type="text/javascript"><br /><br />var ZnXmlAjaxHttpObj;<br /> <br />function ZnGetClienteWsAjx(ZnMyName) { <br /> <br /> alert('estou na função!');<br /> if (typeof XMLHttpRequest != "undefined"){ZnXmlAjaxHttpObj = new XMLHttpRequest();}<br /> else{<br /> ZnXmlAjaxHttpObj = new ActiveXObject('Msxml2.XMLHTTP');<br /> if (!ZnXmlAjaxHttpObj){ZnXmlAjaxHttpObj = new ActiveXObject('Microsoft.XMLHTTP');}<br /> } <br /> alert(ZnMyName.value); <br /> var ZnSpan = document.getElementById("IWLABEL1");<br /> <br /> ZnSpan.innerHTML = "Estaçaõ Zn: Buscando dados do Cliente pelo nome fornecido: " + ZnMyName.value + " ....";<br /> <br /> var url = "http://localhost/ajaxjsonzn/?znNomeCli="+ ZnMyName.value;<br /> ZnXmlAjaxHttpObj.open("GET", url, true);<br /> ZnXmlAjaxHttpObj.onreadystatechange = ZnDynProcessaReqBuscaCliente; <br /> ZnXmlAjaxHttpObj.send(null); <br /> } <br /> <br /> function ZnDynProcessaReqBuscaCliente() { <br /> var ZnSpan2 = document.getElementById("IWLABEL2");<br /> var ZnElement = document.getElementById("IWEDIT1");<br /> ZnSpan2.innerHTML = 'Processando ..................';<br /> if (ZnSpan2.innerHTML.indexOf("buscando dados",0) >= 0){ZnSpan2.innerHTML = "Processando ...";}<br /> else {ZnSpan2.innerHTML = "<b>buscando dados do Cliente: </b>" + ZnElement.value + " ....";}<br /> <br /> if (ZnXmlAjaxHttpObj.readyState == 4) {<br /> if (ZnXmlAjaxHttpObj.status == 200) {<br /> processJsonEstacaoZn(ZnXmlAjaxHttpObj.responseText);<br /> }<br /> } <br /> else return false;<br />} <br /><br />function processJsonEstacaoZn(obj1) {<br /> <br /> var ObjLandjah; <br /> eval('ObjLandjah = ' + obj1);<br /> var Aux =<br /> " <br /> customerid: "+ ObjLandjah.customerid +<br /> " <br /> contactname: "+ ObjLandjah.contactname +<br /> " <br /> contacttitle: "+ ObjLandjah.contacttitle +<br /> " <br /> companyname: "+ ObjLandjah.companyname +<br /> " <br /> country: "+ ObjLandjah.country +<br /> " <br /> CEP/postal code: " + ObjLandjah.postalcode +<br /> "<br /> Região: " + ObjLandjah.region +<br /> "<br /> Cidade: " + ObjLandjah.city +<br /> "<br />Logradouro: " + ObjLandjah.address +<br /> " <br /> fax: " + ObjLandjah.fax +<br /> " <br /> phone: "+ ObjLandjah.phone;<br /> alert(Aux); <br /> document.getElementById("cj").innerHTML += '- <b>Ninguém vai subir #@#@%#@%#%@ ... vai ficar todo mundo quietinho ae.</b>';<br /> document.getElementById("cj").innerHTML += Aux; <br /> document.getElementById("IWMEMO1").innerHTML += ' \n <b>100% Quatorze? </b>'; <br /> document.getElementById("IWMEMO1").innerHTML += ' \n ************************************';<br /> //****************************************************<br /> <br /> var insertData = "<b> Resultado Consulta www.estacaozn.blogspot.com:</b>";<br /> try {<br /> //alert('Cod Retorno: ' + ObjLandjah.codretornoZn);<br /> switch (ObjLandjah.codretornoZn * 1) {<br /> case 1: <br /> document.getElementById("IWMEMO1").innerHTML += ' \n - Cavera meu Capitão. ';<br /> document.getElementById("IWMEMO1").innerHTML += ' \n ************************************';<br /> insertData += " <br /> customerid: "+ ObjLandjah.customerid +<br /> " <br /> contactname: "+ ObjLandjah.contactname +<br /> " <br /> contacttitle: "+ ObjLandjah.contacttitle +<br /> " <br /> companyname: "+ ObjLandjah.companyname +<br /> " <br /> country: "+ ObjLandjah.country +<br /> " <br /> CEP/postal code: " + ObjLandjah.postalcode +<br /> "<br /> Região: " + ObjLandjah.region +<br /> "<br /> Cidade: " + ObjLandjah.city +<br /> "<br />Logradouro: " + ObjLandjah.address +<br /> " <br /> fax: " + ObjLandjah.fax + <br /> " <br /> phone: " + ObjLandjah.phone;<br /> //alert("Case, estou aqui");<br /> // Abaixo, veja como atribuir valor do JavaScript Object Notation ao IWMemo e aos IWEdits <br /> document.getElementById("IWMEMO1").innerHTML += ' \n ************************************';<br /> document.getElementById("CEP").value = ObjLandjah.postalcode;<br /> document.getElementById("CEP").disabled = true;<br /> document.getElementById("IWMEMO1").innerHTML += " \n CEP: " + ObjLandjah.postalcode;<br /> document.getElementById("CONTACTNAME").value = ObjLandjah.contactname;<br /> document.getElementById("CONTACTNAME").disabled = true;<br /> document.getElementById("IWMEMO1").innerHTML += " \n Contato: " + ObjLandjah.contactname;<br /> document.getElementById("CONTACTTITLE").value = ObjLandjah.contacttitle;<br /> document.getElementById("CONTACTTITLE").disabled = true;<br /> document.getElementById("IWMEMO1").innerHTML += " \n Contato: " + ObjLandjah.contacttitle; <br /> document.getElementById("CIDADE").value = ObjLandjah.city;<br /> document.getElementById("CIDADE").disabled = true;<br /> document.getElementById("IWMEMO1").innerHTML += " \n Cidade: " + ObjLandjah.city;<br /> document.getElementById("BAIRRO").value = "Bla!";<br /> document.getElementById("BAIRRO").disabled = true;<br /> document.getElementById("FAX").value = ObjLandjah.fax;<br /> document.getElementById("FAX").disabled = true;<br /> document.getElementById("IWMEMO1").innerHTML += "\n Fax: " + ObjLandjah.fax;<br /> document.getElementById("LOGRADOURO").value = ObjLandjah.address;<br /> document.getElementById("LOGRADOURO").disabled = true;<br /> document.getElementById("IWMEMO1").innerHTML += "\n Logradouro:" + ObjLandjah.address;<br /> document.getElementById("COMPANYNAME").value = ObjLandjah.companyname;<br /> document.getElementById("COMPANYNAME").disabled = true;<br /> document.getElementById("IWMEMO1").innerHTML += "\n Nome da Empresa:" + ObjLandjah.companyname;<br /> document.getElementById("COUNTRY").value = ObjLandjah.country;<br /> document.getElementById("COUNTRY").disabled = true;<br /> document.getElementById("IWMEMO1").innerHTML += "\n Pais:" + ObjLandjah.country;<br /> document.getElementById("UF").value = ObjLandjah.region;<br /> document.getElementById("UF").disabled = true;<br /> document.getElementById("IWMEMO1").innerHTML += " \n Região: " + ObjLandjah.region;<br /> document.getElementById("PHONE").value = ObjLandjah.phone;<br /> document.getElementById("PHONE").disabled = true;<br /> document.getElementById("IWMEMO1").innerHTML += " \n Tel: " + ObjLandjah.phone;<br /> document.getElementById("IWMEMO1").innerHTML += '\n ************************************'; <br /> break;<br /> case -1: insertData += "Cliente não encontrado!"; break;<br /> case -2: insertData += "Valor digitado inválido!"; break;<br /> case -3: insertData += "Ta com nojinho 02?."; break;<br /> case -4: insertData += "AH ESSA ALTURA DO CAMPEONATO VC TA SEM AH BANDOLEIRA ??!"; break;<br /> default: "PEDE PRA SAIR 01. Pede pra sair.";<br /> }<br /> }<br /> catch(Error) {<br /> insertData = "<br> <font color=#FF0000> eRrO. TIRA ESSA ROUPA PRETA QUE VC NÃO É CAVEIRA. </font> As Landjhas de mirandjas!!!"<br /> }<br /> <br /> document.getElementById("IWLABEL2").innerHTML += insertData;<br /> document.getElementById("IWLABEL1").innerHTML += " <br /><b> Os senhores estão bem? Os senhores estão feridos? Algum dos senhores estão baleados? " +<br /> " Então, no próximo post vcs vão aprender a carregar corpos!!! </b>"<br /> document.getElementById("IWMEMO1").innerHTML += ' \n ';<br /> } <br /><br /><br /> <br /></script><br /><br /></head><br /><br /><body><br /><form id="form1" name="form1" method="post" action=""><br /><div id="PosControles" style="position: absolute; top: 32px; left: 12px; width: 887px; height: 92px; background-color: #3399CC; <br /> font-size:16px; font-weight:400" align="justify"><br />Digite o Nome do Cliente: {%IWEdit1%} | {%IWButton1%} <br /><br> <br />{%Logradouro%}{%Bairro%}{%Cidade%} {%UF%}{%CEP%} {%CompanyName%}<br /> {%ContactName%}<br /> {%ContactTitle%}<br /> {%Phone%}<br /> {%Fax%}<br /> {%Country%}<br /> {%IWLink1%} <a href="http://localhost/estacaozncliente">Reload Page</a></div><br /><div id="PosSpan" style="position: absolute; top: 128px; left: 12px; width: 440px; height: 580px; background-color: #99FF99;"><br />{%IWLabel1%} {%IWLabel2%}<br /><span id="cj"><br /></span><br /></div><br /><div id="PosMemo" style="position: absolute; top: 128px; left: 458px; width: 440px; height: 580px; background-color: #99FF99;"<br />align="center"><p><br />{%IWMEMO1%}<br />testando!!<br /></div><br /><br /><br /></form><br /></body><br /></html><br /></pre><br /><br /><div align="justify">Salve a página html (o arquivo html, referente a página que acabamos de criar) com o nome de “ZnPageAjaxJsonIntraweb.html”.</div><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_buFzmAtZPuc/SfQP8JmnHfI/AAAAAAAABdA/1qr1dl7oaEk/s1600-h/DirvirtualEstacaoZnCliente.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 248px;" src="http://2.bp.blogspot.com/_buFzmAtZPuc/SfQP8JmnHfI/AAAAAAAABdA/1qr1dl7oaEk/s320/DirvirtualEstacaoZnCliente.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5328901785130573298" /></a><br /><br /><div align="justify">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.<br /><br />Adicione no IWForm1 os seguintes componentes:</div> <br /> <pre class="normal"><br /> IWTemplateProcessorHTML1: TIWTemplateProcessorHTML;<br /> IWLabel1: TIWLabel;<br /> IWEdit1: TIWEdit;<br /> IWButton1: TIWButton;<br /> IWMemo1: TIWMemo;<br /> CEP: TIWEdit;<br /> UF: TIWEdit;<br /> Bairro: TIWEdit;<br /> Logradouro: TIWEdit;<br /> Cidade: TIWEdit;<br /> IWLabel2: TIWLabel;<br /> CompanyName: TIWEdit;<br /> ContactName: TIWEdit;<br /> ContactTitle: TIWEdit;<br /> Phone: TIWEdit;<br /> Fax: TIWEdit;<br /> Country: TIWEdit; </pre><br /><br />No evento OnCreate do IWForm1 codifique conforme ilustrado abaixo:<br /><pre name="code" class="delphi"><br />procedure TformMain.IWAppFormCreate(Sender: TObject);<br />begin<br /> Self.TemplateProcessor := IWTemplateProcessorHTML1;<br /> IWTemplateProcessorHTML1.Templates.default := 'ZnPageAjaxJsonIntraweb.html';<br /> IWLabel1.Caption := ' ';<br /> IWMemo1.Font.Enabled := False;<br /> IWMemo1.Font.CSSStyle := 'AreaTexto';<br /> CEP.Width := 80;<br /> UF.Width := 40;<br /> Cidade.Width := 120;<br /> Logradouro.Width := 180;<br /> Bairro.Width := 90;<br /> IWButton1.ExtraTagParams.Add('onClick=ZnGetCLienteWsAjax(IWEDIT1)');<br /> IWMemo1.Lines.Add(' ');<br /> IWEdit1.Text := 'Cactus Comidas para llevar';<br />end; </pre><br /><div align="justify"><br />Observe na linha 7, estou atribuindo dinamicamente ao IWMemo1 uma classe CSS (“'AreaTexto'”) a qual está definida na página HTML que criamos anteriormente. <br /><br />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 ... <br />O nome do diretório virtual que vou criar será “estacaozncliente”.<br /></div><br /><br /><div align="justify">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.</div><br /><br /><span style="font-weight:bold;">Testando Aplicação cliente IntraWeb/ISAPI.</span><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_buFzmAtZPuc/SfQR0a02buI/AAAAAAAABdM/WRe9pNBbKtk/s1600-h/TestandoAppAclienteIntraWebIsapi.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 300px;" src="http://2.bp.blogspot.com/_buFzmAtZPuc/SfQR0a02buI/AAAAAAAABdM/WRe9pNBbKtk/s320/TestandoAppAclienteIntraWebIsapi.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5328903851338002146" /></a><br /><br /><div align="justify">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.</div><br /><span style="font-weight:bold;">Conclusão </span><br /><div align="justify">A partir da experiência realizada e documentada neste artigo, destaco as seguintes observações:<br />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.<br />O uso do JavaScript Object Notation (Json) descomplica muito a desenvolvimento de uma solução baseada em Ájax. <br />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 <a href="http://estacaozn.blogspot.com/search/label/Javascript">Javascript</a> que trabalhamos nos <a href="http://estacaozn.blogspot.com/2009/02/delphi-intraweb-gerar-dinamicamente.html">artigos anteriores</a> 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.<br />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...<br />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. </div><br /><pre><br /> <head><br /> <script language="JavaScript" src="ZnJavaScriptFile.js"></script><br /> </head> <br /></pre><br /><div align="justify">Estive conversando com o Felipe e com o Malta <a href="http://estacaozn.blogspot.com/2009/01/inicializando-o-iwform-com-alguns.html">sobre os exemplos anteriores que estive postando</a>. 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 <a href="http://estacaozn.blogspot.com/2009/01/delphi-intraweb-javascript-ii-continua.html">Javascript no meio do código Delphi</a>, mesmo eu “organizando”, através de <a href="http://estacaozn.blogspot.com/2007/02/3-constantes-variveis-e-tipos-de-dados.html">constantes</a> 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 <a href="http://estacaozn.blogspot.com">Estação ZN</a> 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. <br />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:<br /><a href="http://estacaozn.blogspot.com/2009/02/delphi-intraweb-gerar-dinamicamente.html">Veja num dos artigos anteriores</a>: 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 <a href="http://estacaozn.blogspot.com/2008/08/o-princpio-da-caixa-preta.html">caixa preta</a> “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!!<br />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”. <a href="http://estacaozn.blogspot.com/2009/04/validacao-de-cpf-e-cnpj-com-javascript.html">Como exemplifiquei no artigo sobre validação de CIC.</a> </div><br /><br /><div align="justify">Falar sobre <a href="http://estacaozn.blogspot.com/2008/08/modularizao-em-programao-coeso-x.html">modularização</a> é 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”.<br /><br />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. <br />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. <br />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. <br />A tecnologia <span style="font-weight:bold;">Json</span> 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.</div><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_buFzmAtZPuc/SfQS8nFokjI/AAAAAAAABdc/eom-w6JX_ec/s1600-h/GoogleTrends.jpg"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 250px;" src="http://1.bp.blogspot.com/_buFzmAtZPuc/SfQS8nFokjI/AAAAAAAABdc/eom-w6JX_ec/s320/GoogleTrends.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5328905091580203570" /></a><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_buFzmAtZPuc/SfQSAiR5wPI/AAAAAAAABdU/R3ruRg6sy9g/s1600-h/TestandoAppAclienteIntraWebIsapiProcessado.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 300px;" src="http://2.bp.blogspot.com/_buFzmAtZPuc/SfQSAiR5wPI/AAAAAAAABdU/R3ruRg6sy9g/s320/TestandoAppAclienteIntraWebIsapiProcessado.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5328904059497332978" /></a><br /><br />Abaixo, código completo das units Delphi:<br /><br /><div align="center"><span style="font-weight:bold;">Aplicação Cliente Intraweb</span></div><br /><pre name="code" class="delphi"><br />unit IWUnit1;<br />{PUBDIST}<br /><br />interface<br /><br />uses<br /> IWAppForm, IWApplication, IWTypes, IWCompMemo, IWCompButton, IWCompEdit,<br /> Controls, IWControl, IWCompLabel, Classes, IWLayoutMgr,<br /> IWTemplateProcessorHTML, IWHTMLControls;<br /><br />type<br /> TformMain = class(TIWAppForm)<br /> IWTemplateProcessorHTML1: TIWTemplateProcessorHTML;<br /> IWLabel1: TIWLabel;<br /> IWEdit1: TIWEdit;<br /> IWButton1: TIWButton;<br /> IWMemo1: TIWMemo;<br /> CEP: TIWEdit;<br /> UF: TIWEdit;<br /> Bairro: TIWEdit;<br /> Logradouro: TIWEdit;<br /> Cidade: TIWEdit;<br /> IWLabel2: TIWLabel;<br /> CompanyName: TIWEdit;<br /> ContactName: TIWEdit;<br /> ContactTitle: TIWEdit;<br /> Phone: TIWEdit;<br /> Fax: TIWEdit;<br /> Country: TIWEdit;<br /> procedure IWAppFormCreate(Sender: TObject);<br /> public<br /> end;<br /><br />implementation<br />{$R *.dfm}<br /><br />uses<br /> ServerController, IWForm;<br /><br /> //ajaxconcorretor<br /><br />procedure TformMain.IWAppFormCreate(Sender: TObject);<br />begin<br /> Self.TemplateProcessor := IWTemplateProcessorHTML1;<br /> IWLabel1.Caption := ' ';<br /> IWMemo1.Font.Enabled := False;<br /> IWMemo1.Font.CSSStyle := 'AreaTexto';<br /> CEP.Width := 80;<br /> UF.Width := 40;<br /> Cidade.Width := 120;<br /> Logradouro.Width := 180;<br /> Bairro.Width := 90;<br /> IWButton1.ExtraTagParams.Add('onClick=return ZnGetClienteWsAjx(IWEDIT1);');<br /> IWMemo1.RawText := True;<br /> IWMemo1.Lines.Add(' ');<br /> IWEdit1.Text := 'Cactus Comidas para llevar';<br />end;<br /><br />end.<br /></pre><br /><br /><br /><div align="center"><span style="font-weight:bold;">Aplicação Servidora Webbrocker</span></div><br /><pre name="code" class="delphi"><br /><br />unit Unit1;<br /><br />interface<br /><br />uses<br /> SysUtils, Classes, HTTPApp, DBClient, Provider, DB, ADODB;<br /><br />type<br /> TWebModule1 = class(TWebModule)<br /> ADOConnection: TADOConnection;<br /> ADODataSet1: TADODataSet;<br /> DataSetProvider1: TDataSetProvider;<br /> ClientDataSet1: TClientDataSet;<br /> ClientDataSet1CustomerID: TWideStringField;<br /> ClientDataSet1CompanyName: TWideStringField;<br /> ClientDataSet1ContactName: TWideStringField;<br /> ClientDataSet1ContactTitle: TWideStringField;<br /> ClientDataSet1Address: TWideStringField;<br /> ClientDataSet1City: TWideStringField;<br /> ClientDataSet1Region: TWideStringField;<br /> ClientDataSet1PostalCode: TWideStringField;<br /> ClientDataSet1Country: TWideStringField;<br /> ClientDataSet1Phone: TWideStringField;<br /> ClientDataSet1Fax: TWideStringField;<br /> procedure WebModule1ZnConsClientesAction(Sender: TObject;<br /> Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);<br /> private<br /> { Private declarations }<br /> public<br /> { Public declarations }<br /> end;<br /><br />var<br /> WebModule1: TWebModule1;<br /><br />implementation<br /><br />{$R *.dfm}<br /><br />uses<br /> Math, StrUtils;<br /><br />procedure TWebModule1.WebModule1ZnConsClientesAction(Sender: TObject;<br /> Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);<br />const<br /> ZnTag = '%s:%s';<br />var<br /> StrStatment: String;<br /> i, CodRetorno: Integer;<br />begin<br /> with ClientDataSet1 do<br /> begin<br /> Params[0].AsString := '%' + Request.QueryFields.Values['znNomeCli']+ '%';<br /> try<br /> Open;<br /> CodRetorno := IfThen(IsEmpty, -1, 1);<br /> StrStatment := StrStatment +<br /> Format(ZnTag, ['codretornoZn',<br /> IntToStr(CodRetorno)]);<br /><br /> if CodRetorno = 0 then Exit;<br /><br /> for i := 0 to Pred(FieldCount) do<br /> begin<br /> StrStatment := StrStatment + ','+<br /> Format(ZnTag, [LowerCase(ClientDataSet1.Fields[i].FieldName),<br /> IfThen((ClientDataSet1.Fields[i].AsString = ''), QuotedStr('-'),<br /> QuotedStr(ClientDataSet1.Fields[i].AsString))]);<br /> end;<br /><br /> finally<br /> Close;<br /> Response.Content := Format('{%s}',[StrStatment]);<br /> end;<br /> end;<br />end;<br /><br /><br />end.<br /></pre><br /><br /></span>GMotta ZNhttp://www.blogger.com/profile/14738149386892914626noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-75506891767107892852009-04-22T03:35:00.003-03:002009-04-22T03:43:07.023-03:00Navegar? Pois é, eu preciso ...<div style="text-align: center;"><span style="font-weight: bold;">Opera</span><br /><br /></div>Faz tempo que eu não usava o Opera (<a href="http://my.opera.com/community/">Opera Software</a>). Acho que a última vez foi por volta de 1999. Volta e meia, navegando, vejo alguém falando bem da nova versão. Prontamente, instalei e gostei muito! Realmente é bem rápido. Imediatamente você percebe isso. Mas o melhor vem depois, se você gosta de ficar antenado, e conhecer coisas que te tragam vantagens vale a pena experimentar e <a href="http://pt.wikipedia.org/wiki/Opera">conferir o que ele tem de bom</a>.<br /><br /><span class="fullpost"><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_buFzmAtZPuc/Se68H95Ku0I/AAAAAAAABcY/d-JHA4iF8QY/s1600-h/OperaSite.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 250px;" src="http://2.bp.blogspot.com/_buFzmAtZPuc/Se68H95Ku0I/AAAAAAAABcY/d-JHA4iF8QY/s320/OperaSite.jpg" alt="" id="BLOGGER_PHOTO_ID_5327402254285323074" border="0" /></a><br /></span>GMotta ZNhttp://www.blogger.com/profile/14738149386892914626noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-84529880291723980892009-04-22T02:00:00.008-03:002009-04-22T02:58:03.493-03:00O Cara é o Kutiman<div style="text-align: justify;">É impressionantemente, surpreendente, sensacional, criativo, positivo, sadio, anárquico, idoneamente geek, inteligentemente livre e devastadoramente afinado a nova mídia.<br /></div><br /><div style="text-align: center;"><span style="font-weight: bold;">Mother of All Funk Chords - E9</span><br /></div><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/tprMEs-zfQA&hl=pt-br&fs=1&color1=0x2b405b&color2=0x6b8ab6"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/tprMEs-zfQA&hl=pt-br&fs=1&color1=0x2b405b&color2=0x6b8ab6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object><br /><br />Nada mais a dizer ... estou sem palavras!!!! :-) <br /><a href="http://thru-you.com/">Thru-you </a> Aperte o play ...<br /><span class="fullpost"><br /><span style="font-weight: bold;">I'm New</span><br />Destaque para <a href="http://www.youtube.com/user/ElexisTrinity">ElexisTrinity</a>, para o <a href="http://www.youtube.com/user/hef513">rapper HE 513knect</a> e também para segunda cantora (Misteriosa Mandy).<br /><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/EsBfj6khrG4&hl=pt-br&fs=1&color1=0x2b405b&color2=0x6b8ab6"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/EsBfj6khrG4&hl=pt-br&fs=1&color1=0x2b405b&color2=0x6b8ab6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object><br /><br /></span><div style="text-align: justify;"><span class="fullpost">Se você ja assistiu o video, prossiga: O que ele fez do Noturno de Chopin foi magnífico, acho pouco provável que isso seja percebido facilmente, mas basta conferir no <a href="http://www.youtube.com/watch?v=OSCoaQgmx0I">video original - Chopin Nocturne Number 13 in C-Minor Op.48 No.1 </a>. Eu percebi de cara pq cresci ouvindo minha mãe tocar Chopin de forma maravilhosa, sempre. </span><br /></div><span class="fullpost"><br /></span><div style="text-align: center;"><span class="fullpost"><span style="font-weight: bold;">Wait For Me</span></span><br /></div><span class="fullpost"><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/i88CKr6Shn4&hl=pt-br&fs=1&color1=0x006699&color2=0x54abd6"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/i88CKr6Shn4&hl=pt-br&fs=1&color1=0x006699&color2=0x54abd6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object><br /><br /><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/xDMFBsuc3Ig&hl=pt-br&fs=1&color1=0x2b405b&color2=0x6b8ab6"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/xDMFBsuc3Ig&hl=pt-br&fs=1&color1=0x2b405b&color2=0x6b8ab6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object></span><br /><span style="font-weight:bold;">OBS:</span> pOR fAvoR, Não deixe de conferir na totalidade as informações sobre o video que ele escreve.GMotta ZNhttp://www.blogger.com/profile/14738149386892914626noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-39035454503349639042009-04-19T16:55:00.006-03:002009-04-19T17:18:35.419-03:00Mídias na Web - A questão de propriedade intelectual<div style="text-align: justify;">Encontrei no <a href="http://idgnow.uol.com.br/internet/2009/02/02/entrevista-saiba-como-usar-imagens-na-web-sem-infringir-a-lei/">IDG Now uma entrevista</a> interessante com dicas de como fazer uso de imagens baixadas da web.<span class="fullpost"><br />Embora o assunto principal da entrevista seja sobre “como usar imagens da web”, vale dar uma olhada porque são dadas dicas que servem para qualquer tipo de mídia produzida e publicada na web. </span><br /><span class="fullpost">Baixei o áudio da entrevista.</span><br /></div><span class="fullpost"><br /><object type="video/x-ms-wmv" standby="Loading Microsoft Windows Media Player components..." data="http://estacaozn.googlepages.com/bruno_magrani_030209.mp3" align="middle" width="320" height="260"><br /><param name="src" value="http://estacaozn.googlepages.com/MsgInBottleSolo.mp3"><br /><param name="autostart" value="false"><br /><param name="animationatStart" value="true"><br /><param name="transparentatStart" value="true"><br /><param name="controller" value="true"><br /></object><br /></span><br />OBS, Importante visitar:<br /><a href="http://creativecommons.org.br/">Creative Commons Barsil</a><br /><a href="http://creativecommons.org/">Creative Commons org/</a><br />Muita coisa interessante lá ...GMotta ZNhttp://www.blogger.com/profile/14738149386892914626noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-16316052498532233122009-04-15T05:55:00.017-03:002009-04-15T06:51:09.903-03:00Validação de CPF e CNPJ com Javascript - Delphi/Intraweb<div style="text-align: justify;"><span style="color: rgb(0, 153, 0);">Mais um da série ... <span style="color: rgb(51, 51, 51);">(</span></span>da séria série ...)<br />Ok, já fizemos vários artigos sobre como usar Javascript no Intraweb. Tenho gastado tempo registrando essa abordagem por vários motivos:<br /></div><br /><div style="text-align: justify;">Um deles é (uma tecla que venho batendo bastante) a importância de buscar um equilíbrio, distribuído responsabilidades entre client-side e server-side (obviamente, me refiro ao contexto restrito os sistemas desenvolvidos para plataforma web). Um segundo motivo pode ser: “Como fazer isso, se eu uso Delphi/Intraweb?” Na medida em que essa é uma questão que considero possuir alguma relevância. Outro motivo, porem, trata sobre “Qual implicação, ou quais implicações, terei ao percorrer este caminho?” Tenho procurado, nos assuntos abordados, trazer alguns elementos que apontem para a responder a essa questão.<br /></div><div style="text-align: justify;">Justamente, esse último ponto, sobre as implicações, ou seja, falar sobre algumas vantagens e desvantagens, é um dos objetivos desse texto. No Intraweb existem certas particularidades ao se aplicar o Javascript, uma delas é o evento “onSubmit” do form definido numa página web. Veremos, então, sobre isso mais adiante.</div><br /><br /><div style="text-align: justify;">Neste artigo pretendo mostrar também como podemos usar a passagem por parâmetro, de uma função Javascript, para a referência de um objeto “html” de um form no Intraweb. Seguindo a metodologia de ir do mais simples para o mais complexo, iniciaremos nossa parte prática com a criação de uma função para validação no lado cliente. Validação essa para a qual atribuiremos a responsabilidade de exemplificar esse uso de parâmetros, ao qual me referi, em Javascript, relacionado aos objetos Intraweb.<br /></div><div style="text-align: justify;">Quero usar um exemplo que seja prático, ordinário, para um cenário de sistemas de informação. Portanto, vamos criar uma função para validar CPF, uma outra para validar CNPJ e uma terceira função que vai opcionalmente validar CNPJ, CPF, ou os dois simultaneamente. Desta forma teremos uma função polivalente (a qual servirá para validar ambos os casos), cujo o processamento será realizado no lado do cliente.<br /></div><br /><br /><div style="text-align: center; font-weight: bold; color: rgb(0, 102, 0);">Javascript para validar CNPJ, CPF no Delphi/Intraweb<br /></div><span class='fullpost'><br /><div style="text-align: justify;">Inicie um novo projeto Intraweb no Delphi, adicione no IWForm1 um IWEdit e três IWButtons. Em seguida, defina uma área de declarações de constantes e digite conforme ilustrado abaixo:<br /></div></span><br /><pre name="code" class="delphi"><br />implementation<br /><br />uses IWBaseForm;<br /><br />{$R *.dfm}<br />const<br /> AQuebraLinhaJsZN = #13;<br /> AFncCriticaCIC =<br /> ' function CriticaCIC(ZnNumCic, ZnCnpjBool, ZnCpfBool){ ' + AQuebraLinhaJsZN +<br /> ' alert("www.estacaozn.blogspot.com verifica CPF/CNPJ");' + AQuebraLinhaJsZN +<br /> ' var CicValidoZn = false; ' + AQuebraLinhaJsZN +<br /> ' ' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && !ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' if(!ZnVerificaCnpj(ZnNumCic)){ ' + AQuebraLinhaJsZN +<br /> ' alert("CNPJ Inválido"); ' + AQuebraLinhaJsZN +<br /> ' return false;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' else if (!ZnCnpjBool && ZnCpfBool){ ' + AQuebraLinhaJsZN +<br /> ' if (!ZnVerificaCPF(ZnNumCic)){ ' + AQuebraLinhaJsZN +<br /> ' alert("CPF inválido"); ' + AQuebraLinhaJsZN +<br /> ' return false; ' + AQuebraLinhaJsZN +<br /> ' ;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' else { ' + AQuebraLinhaJsZN +<br /> ' CicValidoZn = ZnVerificaCnpj(ZnNumCic); ' + AQuebraLinhaJsZN +<br /> ' if(CicValidoZn){ ' + AQuebraLinhaJsZN +<br /> ' return true;} ' + AQuebraLinhaJsZN +<br /> ' else{ ' + AQuebraLinhaJsZN +<br /> ' CicValidoZn = ZnVerificaCPF(ZnNumCic); ' + AQuebraLinhaJsZN +<br /> ' if(!CicValidoZn){ ' + AQuebraLinhaJsZN +<br /> ' alert("CIC Inválido") ' + AQuebraLinhaJsZN +<br /> ' return false;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' var ZnMsg = ""; ' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CPJ ou CNPJ"; }' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && !ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CNPJ"; }' + AQuebraLinhaJsZN +<br /> ' if (!ZnCnpjBool && ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CPF"; }' + AQuebraLinhaJsZN +<br /> ' alert("Valor Validado Ok, " +ZnMsg + ": " + ZnNumCic.value);' + AQuebraLinhaJsZN +<br /> ' return true;} ' + AQuebraLinhaJsZN;<br /><br /> AFncCriticaCPF =<br /> ' function ZnVerificaCPF (ZnCpfObj){ ' + AQuebraLinhaJsZN +<br /> ' var gmSort = new Array(ZnCpfObj.value.length); ' + AQuebraLinhaJsZN +<br /> ' for (i=0; i< ZnCpfObj.value.length; i++){gmSort[i] = ZnCpfObj.value.charAt(i);} ' + AQuebraLinhaJsZN +<br /> ' gmSort.sort(); ' + AQuebraLinhaJsZN +<br /> ' if (gmSort[0] == gmSort[gmSort.length -1]){ ' + AQuebraLinhaJsZN +<br /> ' alert("www.estacaozn.blogspot.com: Os números são iguais: " + ZnCpfObj.value); ' + AQuebraLinhaJsZN +<br /> ' return false; ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' ZnAuxCal = 0; ' + AQuebraLinhaJsZN +<br /> ' for (ZnCont = 0; ZnCont < 9; ZnCont ++) ' + AQuebraLinhaJsZN +<br /> ' ZnAuxCal += parseInt(ZnCpfObj.value.charAt(ZnCont)) * (10 - ZnCont); ' + AQuebraLinhaJsZN +<br /> ' DgVZn = 11 - (ZnAuxCal % 11); ' + AQuebraLinhaJsZN +<br /> ' if (DgVZn == 10 || DgVZn == 11) ' + AQuebraLinhaJsZN +<br /> ' DgVZn = 0; ' + AQuebraLinhaJsZN +<br /> ' if (DgVZn != parseInt(ZnCpfObj.value.charAt(9))) ' + AQuebraLinhaJsZN +<br /> ' return false; ' + AQuebraLinhaJsZN +<br /> ' ZnAuxCal = 0; ' + AQuebraLinhaJsZN +<br /> ' for (ZnCont = 0; ZnCont < 10; ZnCont ++) ' + AQuebraLinhaJsZN +<br /> ' ZnAuxCal += parseInt(ZnCpfObj.value.charAt(ZnCont)) * (11 - ZnCont); ' + AQuebraLinhaJsZN +<br /> ' DgVZn = 11 - (ZnAuxCal % 11); ' + AQuebraLinhaJsZN +<br /> ' if (DgVZn == 10 || DgVZn == 11) ' + AQuebraLinhaJsZN +<br /> ' DgVZn = 0; ' + AQuebraLinhaJsZN +<br /> ' if (DgVZn != parseInt(ZnCpfObj.value.charAt(10))){ ' + AQuebraLinhaJsZN +<br /> ' return false;} ' + AQuebraLinhaJsZN +<br /> ' //alert("O CPF INFORMADO É VÁLIDO."); ' + AQuebraLinhaJsZN +<br /> ' return true; ' + AQuebraLinhaJsZN +<br /> '} ' + AQuebraLinhaJsZN;<br /><br /> AFncCriticaCNPJ =<br /> ' function ZnVerificaCnpj(ZNObjInput){' + AQuebraLinhaJsZN +<br /> ' var ZnDigitos, ZnDg, ZnSum, ZnCount;' + AQuebraLinhaJsZN +<br /> ' var ZnResult, ZnPos, tamanho;' + AQuebraLinhaJsZN +<br /> ' var ZnAuxCNPJ = ZNObjInput.value.replace(/\D+/g, "");' + AQuebraLinhaJsZN +<br /> '' + AQuebraLinhaJsZN +<br /> ' if (ZnAuxCNPJ.length != 14){' + AQuebraLinhaJsZN +<br /> ' ZNObjInput.focus();' + AQuebraLinhaJsZN +<br /> ' return false;' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> ' var gmSort = new Array(ZNObjInput.value.length); ' + AQuebraLinhaJsZN +<br /> ' for (i=0; i< ZNObjInput.value.length; i++){gmSort[i] = ZNObjInput.value.charAt(i);} ' + AQuebraLinhaJsZN +<br /> ' gmSort.sort(); ' + AQuebraLinhaJsZN +<br /> ' if (gmSort[0] == gmSort[gmSort.length -1]){ ' + AQuebraLinhaJsZN +<br /> ' alert("www.estacaozn.blogspot.com: Os números são iguais: " + ZNObjInput.value); ' + AQuebraLinhaJsZN +<br /> ' return false; ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> '' + AQuebraLinhaJsZN +<br /> ' ZnAuxTamanho = ZnAuxCNPJ.length - 2' + AQuebraLinhaJsZN +<br /> ' ZnDigitos = ZnAuxCNPJ.substring(0,ZnAuxTamanho);' + AQuebraLinhaJsZN +<br /> ' ZnDg = ZnAuxCNPJ.substring(ZnAuxTamanho);' + AQuebraLinhaJsZN +<br /> ' ZnSum = 0;' + AQuebraLinhaJsZN +<br /> ' ZnPos = ZnAuxTamanho - 7;' + AQuebraLinhaJsZN +<br /> ' for (ZnCount = ZnAuxTamanho; ZnCount >= 1; ZnCount--){' + AQuebraLinhaJsZN +<br /> ' ZnSum += ZnDigitos.charAt(ZnAuxTamanho - ZnCount) * ZnPos--;' + AQuebraLinhaJsZN +<br /> ' if (ZnPos < 2)' + AQuebraLinhaJsZN +<br /> ' ZnPos = 9;' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> ' ZnResult = ZnSum % 11 < 2 ? 0 : 11 - ZnSum % 11;' + AQuebraLinhaJsZN +<br /> ' if (ZnResult != ZnDg.charAt(0)){' + AQuebraLinhaJsZN +<br /> ' ZNObjInput.focus();' + AQuebraLinhaJsZN +<br /> ' return false;' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> '' + AQuebraLinhaJsZN +<br /> ' ZnAuxTamanho = ZnAuxTamanho + 1;' + AQuebraLinhaJsZN +<br /> ' ZnDigitos = ZnAuxCNPJ.substring(0,ZnAuxTamanho);' + AQuebraLinhaJsZN +<br /> ' ZnSum = 0;' + AQuebraLinhaJsZN +<br /> ' ZnPos = ZnAuxTamanho - 7;' + AQuebraLinhaJsZN +<br /> ' for (ZnCount = ZnAuxTamanho; ZnCount >= 1; ZnCount--){' + AQuebraLinhaJsZN +<br /> ' ZnSum += ZnDigitos.charAt(ZnAuxTamanho - ZnCount) * ZnPos--;' + AQuebraLinhaJsZN +<br /> ' if (ZnPos < 2)' + AQuebraLinhaJsZN +<br /> ' ZnPos = 9;}' + AQuebraLinhaJsZN +<br /> '' + AQuebraLinhaJsZN +<br /> ' ZnResult = ZnSum % 11 < 2 ? 0 : 11 - ZnSum % 11;' + AQuebraLinhaJsZN +<br /> ' if (ZnResult != ZnDg.charAt(1)){' + AQuebraLinhaJsZN +<br /> ' ZNObjInput.focus();' + AQuebraLinhaJsZN +<br /> ' return false;}' + AQuebraLinhaJsZN +<br /> ' else {' + AQuebraLinhaJsZN +<br /> ' return true;' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN;<br /></pre><br /><span class='fullpost'><br /><div style="text-align: justify;">Dando continuidade, para usarmos o que acabamos de definir devemos usar as propriedades específicas dos componentes Intraweb destinadas a trabalhar com Javascript. Elas existem tanto no IWForm (Formulário Delphi para web), quanto nos controles, IWControls.</div><br /> <br /><div style="text-align: center; font-weight: bold; color: rgb(0, 102, 0);">Evento OnCreate do IWFrom1:</div><br /><br /><pre name="code" class="delphi"><br />procedure TIWForm1.IWAppFormCreate(Sender: TObject);<br />begin<br /> (* Atribuindo a propriedade "JavaScript" do IWForm1 as <br /> funções que serão processadas pelo browser*)<br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(AFncCriticaCPF);<br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(AFncCriticaCNPJ);<br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(AFncCriticaCIC);<br /> Self.JavaScript.Add('');<br /> // O IWButton1 vai validar as duas opções CPF e CNPJ<br /> IWButton1.Caption := 'Valida CPF e CNPJ';<br /> IWButton1.Width := 200;<br /> IWButton1.ExtraTagParams.Add(<br /> Format('onClick=CriticaCIC(%s, %s, %s)', [UpperCase(IWEdit1.Name),<br /> 'true', 'true']));<br /> //O IWButton2 vai validar apenas CPF<br /> IWButton2.Caption := 'Valida CPF';<br /> IWButton2.Width := 200;<br /> IWButton2.ExtraTagParams.Add(<br /> Format('onClick=CriticaCIC(%s, %s, %s)', [UpperCase(IWEdit1.Name),<br /> 'false', 'true']));<br /> //O IWButton3 vai validar apenas CNPJ<br /> IWButton3.Caption := 'Valida CNPJ';<br /> IWButton3.Width := 200;<br /> IWButton3.ExtraTagParams.Add(<br /> Format('onClick=CriticaCIC(%s, %s, %s)', [UpperCase(IWEdit1.Name),<br /> 'true', 'false']));<br />end;<br /></pre><br /><div style="text-align: justify;"><br />No trecho de código acima, podemos observar, comparando com os exemplos postados nos artigos anteriores, sobre Intraweb e Javascript, que o uso de parâmetros nas funções Javascript para referenciar os objetos do form (na página html), reduz sensivelmente a o número de linhas. Isso melhora a legibilidade do código, consequentimente aumenta a manutenibilidade do mesmo. Visto que, não precisamos usar o temperamental “document.all” (sensível a diversidade de navegadores). Também não precisamos mais do “document.forms[x]”, isso nos abstém da preocupação em referenciar o form específico (Lembra, no Intraweb 8, o framework pode criar vários forms na mesma página?). Obviamente, isso é possível porque a chamada a função esta sendo feita no mesmo form proprietário do objeto que está sendo passado como argumento. Em outras palavras: O objeto que está sendo passado como parâmetro na função critica CIC 2, está definido no mesmo form no qual a função esta sendo chamada. <br />Entretanto, infelizmente, essa abordagem pode encontrar limitações. Vejamos adiante ....<br /><br />Sobre as funções de validação de CNPJ e CPF, não estou preocupado com a otimização da lógica que elas implementam. Basiei-me em alguns dos milhares de exemplos que podemos encontrar na web. Com certeza, fiz alguns ajustes. Mas nada que mereça grande atenção, embora elas funcionem corretamente, no sentido de serem eficientes em alcançarem o objetivo que se propõem. Reiterando, o propósito dessa parte do artigo é exemplificar como resolver via Javascript uma validação bastante necessária, uma situação comum, presumo, em muitos sistemas (desenvolvidos com Intraweb).<br /></div></span><br /><br /><div style="text-align: justify; font-weight: bold; color: rgb(0, 102, 0);">OnClick do IWButton chamar mais de uma função Javascript no evento “onSubmit” do form</div><br /><div style="text-align: justify;"> <br />Supondo que o IWButton, ou qualquer outro controle que seja, já possua uma chamada a uma função Javascript. Hipoteticamente, imagine um cenário onde o mesmo IWButton, que vai submeter o form da página web, precisa, no mesmo evento “OnClick”, validar o CIC e fazer qualquer outro tipo de validação. </div><span class='fullpost'><div style="text-align: justify;"> Note que estou, propositalmente, construindo uma situação onde o click do botão está relacionado a ação de submeter o form da página web. Além disso, estamos trabalhando com um grau de complexidade onde você precisa (ou precisará) executar mais de um função em reposta ação do usuário clicar esse botão. O botão “Submit” (no caso, nosso IWButton1). Ora, grau de complexidade? Isso que você descreveu, Gerson, me parece tão comum! Concordo, é muito comum se você está trabalhando com outra tecnologia. No Intraweb, lamentavelmente isso não é trivial. <br />Então, prosseguindo, vejamos: Em primeiro lugar, vamos criar a segunda função (a qual será responsável por tornar o valor do IWEdit1 obrigatório). Ou seja, para submeter o form da página web, o usuário será obrigado a digitar algum valor no IWEdit1. Feito isso, teremos construído todos elementos necessários para a experiência que irá confirmar minha argumentação (assim espero ....). Portanto, na seção “const” (que definimos anteriormente) codificaremos, em forma de outra constante, a string com a função supracitada. Digite conforme ilustrado abaixo:</div><br /><br /><pre name="code" class="delphi"><br /><br />AFncValorRequerido =<br /> ' function ValorRequerido(){ ' + AQuebraLinhaJsZN +<br /> ' var ObjInput = document.getElementById("%s); ' + AQuebraLinhaJsZN +<br /> ' var AFriendlyName = "%s"; ' + AQuebraLinhaJsZN +<br /> ' if (ObjInput.value == ""){ ' + AQuebraLinhaJsZN +<br /> ' alert("É obrigatório o valor para o campo: " + AFriendlyName); ' + AQuebraLinhaJsZN +<br /> ' ObjInput.style.backgroundColor = "#FD88AA"; ' + AQuebraLinhaJsZN +<br /> ' ObjInput.focus(); ' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> ' else { ' + AQuebraLinhaJsZN +<br /> ' ObjInput.style.backgroundColor = "#FFFFFF"; ' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN;<br /></pre><br /><div style="text-align: justify;"> <br />Em seguida faremos uma pequena modificação na primeira função que criamos, “CriticaCIC”. No caso, ela é a segunda constante de definimos para o exemplo anterior, a “AFncCriticaCIC”. Espere, não é exatamente isso o que faremos. O que quero realmente fazer é copiar a constante “AFncCriticaCIC”, a partir disso, definir uma nova com o mesmo conteúdo. Porque, desta forma posso fazer as alterações que preciso, sem perder completamente o exemplo anterior. Logo, assim sendo, quem estiver acompanhando este artigo poderá facilmente testar e verificar a diferença entra as duas <a href="http://desciclo.pedia.ws/wiki/Conceito_de_Estrat%C3%A9gia ">estratégias</a> (“do grego, "Στρατηγικη"... ...no inglês, "strategy"... ...no francês, "stratégie"... ZzZzZzZzzzz...... ...Senhor leitor, o senhor está dormindo? Senhor leitor, tenha bondade..”. (Parafraseando Capitão Nascimento)<br /><br />Prosseguindo (era brincadeira), retomemos: Criaremos então a nova constante a partir da cópia de “AFncCriticaCIC”:<br /></div><br /><pre name="code" class="delphi"><br />AFncCriticaCIC2 =<br /> ' function CriticaCIC2(ZnCnpjBool, ZnCpfBool){ ' + AQuebraLinhaJsZN +<br /> ' var ZnNumCic = document.getElementById("%s); ' + AQuebraLinhaJsZN +<br /> ' alert("www.estacaozn.blogspot.com verifica CPF/CNPJ");' + AQuebraLinhaJsZN +<br /> ' var CicValidoZn = false; ' + AQuebraLinhaJsZN +<br /> ' ' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && !ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' if(!ZnVerificaCnpj(ZnNumCic)){ ' + AQuebraLinhaJsZN +<br /> ' alert("CNPJ Inválido"); ' + AQuebraLinhaJsZN +<br /> ' return false;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' else if (!ZnCnpjBool && ZnCpfBool){ ' + AQuebraLinhaJsZN +<br /> ' if (!ZnVerificaCPF(ZnNumCic)){ ' + AQuebraLinhaJsZN +<br /> ' alert("CPF inválido"); ' + AQuebraLinhaJsZN +<br /> ' return false; ' + AQuebraLinhaJsZN +<br /> ' ;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' else { ' + AQuebraLinhaJsZN +<br /> ' CicValidoZn = ZnVerificaCnpj(ZnNumCic); ' + AQuebraLinhaJsZN +<br /> ' if(CicValidoZn){ ' + AQuebraLinhaJsZN +<br /> ' return true;} ' + AQuebraLinhaJsZN +<br /> ' else{ ' + AQuebraLinhaJsZN +<br /> ' CicValidoZn = ZnVerificaCPF(ZnNumCic); ' + AQuebraLinhaJsZN +<br /> ' if(!CicValidoZn){ ' + AQuebraLinhaJsZN +<br /> ' alert("CIC Inválido") ' + AQuebraLinhaJsZN +<br /> ' return false;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' var ZnMsg = ""; ' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CPJ ou CNPJ"; }' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && !ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CNPJ"; }' + AQuebraLinhaJsZN +<br /> ' if (!ZnCnpjBool && ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CPF"; }' + AQuebraLinhaJsZN +<br /> ' alert("Valor Validado Ok, " +ZnMsg + ": " + ZnNumCic.value);' + AQuebraLinhaJsZN +<br /> ' return true;} ' + AQuebraLinhaJsZN;<br /></pre><div style="text-align: justify;"> <br />Essa nova versão da crítica de “CIC” possui um parâmetro a menos. Eu retirei o argumento referente ao objeto do form (input que recebe o valor digitado do suposto CIC). Já que decidimos não perder o que foi feito no exemplo anterior, vamos adicionar mais um IWButton. O IWButton4, servirá, nessa segunda parte do artigo, para chamar a nova critica CIC (o conteúdo da AFncCriticaCIC2). Feito isso, vamos acrescentar mais umas linhas de código no evento “OnCreate” do IWForm1.<br /></div><br /><pre name="code" class="delphi"><br /> <br /> (* segunda parte do artigo:<br /> OnClick do IWButton chamar mais de uma função Javascript *)<br /> IWEdit1.FriendlyName := 'CIC: "CNPJ" ou "CPF"';<br /> Self.JavaScript.Add('//**************************************');<br /> Self.JavaScript.Add('//segunda parte do artigo:' + #13 +<br /> '// OnClick do IWButton chamar mais de uma função Javascript');<br /> Self.JavaScript.Add(Format(AFncCriticaCIC2, [UpperCase(IWEdit1.Name)]));<br /> Self.JavaScript.Add('');<br /><br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(Format(AFncValorRequerido, [UpperCase(IWEdit1.Name),<br /> IWEdit1.FriendlyName]));<br /> Self.JavaScript.Add('//*******www.estacaozn.blogspot.com**********');<br /><br /> IWButton4.Caption := 'Valor Obrigatório & Valida CIC';<br /> IWButton4.Width := 360;<br /> IWButton4.ScriptEvents.Add('onClick').EventCode.Add(<br /> 'ValorRequerido() && CriticaCIC(true, true)');<br /></pre><br /></span><div style="text-align: justify;"><br />No Intraweb, chamar, efetivamente, no evento “onClick”, mais de um função pode ser feito declarando o nome das funções, juntamente com o operador lógico adequado, ao caso específico, na propriedade “ScriptEvent” do componente escolhido (No nosso caso o escolhido foi o TIWButton). Provavelmente, essa não deve ser a única forma de se fazer isso, essa é apenas uma (suponho ;-)). Especificamente a que eu encontrei no momento para alcançar meu objetivo.</div><span class='fullpost'><div style="text-align: justify;"><br />Cabe registrar que, como alternativa, para propriedade “ExtraTagParams” existe um restrição. Só funciona se a ação não envolver o submit do form. Como posso ter certeza do acabei de afirmar?<br />Para exemplificar, respondendo a pergunta anterior, vamos submeter o form. Contudo, para isso, precisamos pelo menos processar algo no servidor. Com essa finalidade, codificaremos qualquer coisa dummy no evento OnClick do componente Delphi/Intraweb TIWButton4. Adicione um novo componente, um IWLabel, em seguida, acompanhe trecho de código abaixo:</div><br /><pre name="code" class="delphi"><br />procedure TIWForm1.IWButton4Click(Sender: TObject);<br />begin<br /> IWLabel1.Font.Size := 16;<br /> IWLabel1.Caption := Format('Valor digitado válido: %s', [IWEdit1.Text]); ;<br />end;<br /></pre><br /><br />Veja, como o Intraweb monta a função que submete o form:<br /> <br /><pre name="code" class="javascript"><br /> var IWLABEL1IWCL = null;<br /> var IWBUTTON1IWCL = null;<br /> var IWEDIT1IWCL = null;<br /> var IWBUTTON2IWCL = null;<br /> var IWBUTTON3IWCL = null;<br /> var IWBUTTON4IWCL = null;<br /> function IWBUTTON4_onclick(event) {<br /> return ValorRequerido() && CriticaCIC2(true, true)<br /> }<br /><br />function IWBUTTON4_onclick0(event) {<br />return SubmitClickConfirm('IWBUTTON4','', true, '');<br />}<br /></pre><br />Ok, finalizamos! Podemos testar, F9 .. e manda ver ...<br /><div style="text-align: center; font-weight: bold; color: rgb(0, 102, 0);">Prova dos Nove</div><div style="text-align: justify;"><br />Considero que terminamos o assunto aqui. Se por acaso você inda quer conferir o que eu afirmei acima prossiga:<br />Agora vamos testar se realmente, de fato, quando esta situação acontece, não é possível ter sucesso usando a propriedade “ExtraTagParams”.<br />Adicionaremos mais um IWButton, no meu exemplo esse será o IWButton5. Retornaremos ao evento “OnCreate” do IWForm1 (Unit1) e codificaremos a chamada ao Javascript de crítica de valor requerido e validação de CIC, na propriedade ExtraTagParams do último IWButton adicionado. Veja abaixo como ficou:</div><br /><br /><pre name="code" class="delphi"><br />procedure TIWForm1.IWAppFormCreate(Sender: TObject);<br />begin<br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(AFncCriticaCPF);<br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(AFncCriticaCNPJ);<br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(AFncCriticaCIC);<br /> Self.JavaScript.Add('');<br /> // O IWButton1 vai validar as duas opções CPF e CNPJ<br /> IWButton1.Caption := 'Valida CPF e CNPJ';<br /> IWButton1.Width := 200;<br /> IWButton1.ExtraTagParams.Add(<br /> Format('onClick=CriticaCIC(%s, %s, %s)', [UpperCase(IWEdit1.Name),<br /> 'true', 'true']));<br /> //O IWButton2 vai validar apenas CPF<br /> IWButton2.Caption := 'Valida CPF';<br /> IWButton2.Width := 200;<br /> IWButton2.ExtraTagParams.Add(<br /> Format('onClick=CriticaCIC(%s, %s, %s)', [UpperCase(IWEdit1.Name),<br /> 'false', 'true']));<br /> //O IWButton3 vai validar apenas CNPJ<br /> IWButton3.Caption := 'Valida CNPJ';<br /> IWButton3.Width := 200;<br /> IWButton3.ExtraTagParams.Add(<br /> Format('onClick=CriticaCIC(%s, %s, %s)', [UpperCase(IWEdit1.Name),<br /> 'true', 'false']));<br /><br /> (* segunda parte do artigo:<br /> OnClick do IWButton chamar mais de uma função Javascript *)<br /> IWEdit1.FriendlyName := 'CIC: CNPJ ou CPF';<br /> Self.JavaScript.Add('//**************************************');<br /> Self.JavaScript.Add('//segunda parte do artigo:' + #13 +<br /> '// OnClick do IWButton chamar mais de uma função Javascript');<br /> Self.JavaScript.Add(Format(AFncCriticaCIC2, [UpperCase(IWEdit1.Name)]));<br /> Self.JavaScript.Add('');<br /><br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(Format(AFncValorRequerido, [UpperCase(IWEdit1.Name),<br /> IWEdit1.FriendlyName]));<br /> Self.JavaScript.Add('//*******www.estacaozn.blogspot.com**********');<br /><br /> IWButton4.Caption := 'Valor Obrigatório & Valida CIC';<br /> IWButton4.Width := 360;<br /> IWButton4.ScriptEvents.Add('onClick').EventCode.Add(<br /> 'return ValorRequerido() && CriticaCIC2(true, true)');<br /><br /> (* testando chamar duas funções Javascript na propriedade ExtraTagParams *)<br /><br /> IWButton5.ExtraTagParams.Add(<br /> Format('onClick=return ValorRequerido() && CriticaCIC(%s, %s, %s)', [UpperCase(IWEdit1.Name),<br /> 'true', 'true']));<br />end;<br /></pre><br /><div style="text-align: justify;"><br />O trecho que acabamos de digitar inicia com o comentário da linha 48. Note que fizemos a chamada semelhante ao IWButton4. Da forma como está agora, funciona perfeitamente. Mesmo que eu faça a chamada, no IWButton5, igualzinho a do IWButton4, funciona.<br /></div><br /><pre name="code" class="delphi"><br /> IWButton5.ExtraTagParams.Add(<br /> Format('onClick=return ValorRequerido() && CriticaCIC2(true, true)',<br /> [UpperCase(IWEdit1.Name)]));<br /></pre><br /><div style="text-align: justify;"><br />Todavia, se eu envolver o IWButton5 no submit do form teremos fracasso. Babau! A vaca vai pro brejo. <br />Para conferir basta codificar qualquer coisa no evento “OnClick” do IWButton5. Isso irá forçar um submit para que esse código seja processado no servidor. Vou colocar uma dummy aqui ... veja:</div><br /><pre name="code" class="delphi"><br />procedure TIWForm1.IWButton5Click(Sender: TObject);<br />begin<br /> IWLabel1.Caption := IWEdit1.Text;<br /> WebApplication.ShowMessage('Se você esta codificando esse exemplo corretamente, '+<br /> 'essa mensagem nunca não vai ser exibida. Jamais será! Garanto (heheh ..).');<br />end;<br /></pre><br /><div style="text-align: justify;"><br />O Intraweb tenta ter controle total de alguns eventos do objeto form da página html. Isso acontece de forma mais rigorosa no evento “onLoad”. Eu até entendo a razão deles fazerem isso, mas não a considero justificável, e justamente por isso discordo desse tipo de controle. Acho isso extremamente prejudicial ao desenvolvimento de sites, sistemas, serviços, web com o Intraweb. Ao mesmo tempo isso demonstra de forma muito clara o quanto esse framework é frágil e imaturo. <br /><br />Abaixo, o código integral da Unit1, seguido do código da página html gerado pelo Intraweb:</div><br /><pre name="code" class="delphi"><br />unit Unit1;<br /><br />interface<br /><br />uses<br /> Classes, SysUtils, IWAppForm, IWApplication, IWColor, IWTypes, IWCompEdit,<br /> Controls, IWVCLBaseControl, IWBaseControl, IWBaseHTMLControl, IWControl,<br /> IWCompButton, IWCompLabel;<br /><br />type<br /> TIWForm1 = class(TIWAppForm)<br /> IWButton1: TIWButton;<br /> IWEdit1: TIWEdit;<br /> IWButton2: TIWButton;<br /> IWButton3: TIWButton;<br /> IWButton4: TIWButton;<br /> IWLabel1: TIWLabel;<br /> IWButton5: TIWButton;<br /> procedure IWButton5Click(Sender: TObject);<br /> procedure IWButton4Click(Sender: TObject);<br /> procedure IWAppFormCreate(Sender: TObject);<br /> public<br /> end;<br /><br />implementation<br /><br /><br />{$R *.dfm}<br />const<br /> AQuebraLinhaJsZN = #13;<br /> AFncCriticaCIC =<br /> ' function CriticaCIC(ZnNumCic, ZnCnpjBool, ZnCpfBool){ ' + AQuebraLinhaJsZN +<br /> ' alert("www.estacaozn.blogspot.com verifica CPF/CNPJ");' + AQuebraLinhaJsZN +<br /> ' var CicValidoZn = false; ' + AQuebraLinhaJsZN +<br /> ' ' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && !ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' if(!ZnVerificaCnpj(ZnNumCic)){ ' + AQuebraLinhaJsZN +<br /> ' alert("CNPJ Inválido"); ' + AQuebraLinhaJsZN +<br /> ' return false;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' else if (!ZnCnpjBool && ZnCpfBool){ ' + AQuebraLinhaJsZN +<br /> ' if (!ZnVerificaCPF(ZnNumCic)){ ' + AQuebraLinhaJsZN +<br /> ' alert("CPF inválido"); ' + AQuebraLinhaJsZN +<br /> ' return false; ' + AQuebraLinhaJsZN +<br /> ' ;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' else { ' + AQuebraLinhaJsZN +<br /> ' CicValidoZn = ZnVerificaCnpj(ZnNumCic); ' + AQuebraLinhaJsZN +<br /> ' if(CicValidoZn){ ' + AQuebraLinhaJsZN +<br /> ' return true;} ' + AQuebraLinhaJsZN +<br /> ' else{ ' + AQuebraLinhaJsZN +<br /> ' CicValidoZn = ZnVerificaCPF(ZnNumCic); ' + AQuebraLinhaJsZN +<br /> ' if(!CicValidoZn){ ' + AQuebraLinhaJsZN +<br /> ' alert("CIC Inválido") ' + AQuebraLinhaJsZN +<br /> ' return false;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' var ZnMsg = ""; ' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CPJ ou CNPJ"; }' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && !ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CNPJ"; }' + AQuebraLinhaJsZN +<br /> ' if (!ZnCnpjBool && ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CPF"; }' + AQuebraLinhaJsZN +<br /> ' alert("Valor Validado Ok, " +ZnMsg + ": " + ZnNumCic.value);' + AQuebraLinhaJsZN +<br /> ' return true;} ' + AQuebraLinhaJsZN;<br /><br /> AFncCriticaCPF =<br /> ' function ZnVerificaCPF (ZnCpfObj){ ' + AQuebraLinhaJsZN +<br /> ' var gmSort = new Array(ZnCpfObj.value.length); ' + AQuebraLinhaJsZN +<br /> ' for (i=0; i< ZnCpfObj.value.length; i++){gmSort[i] = ZnCpfObj.value.charAt(i);} ' + AQuebraLinhaJsZN +<br /> ' gmSort.sort(); ' + AQuebraLinhaJsZN +<br /> ' if (gmSort[0] == gmSort[gmSort.length -1]){ ' + AQuebraLinhaJsZN +<br /> ' alert("www.estacaozn.blogspot.com: Os números são iguais: " + ZnCpfObj.value); ' + AQuebraLinhaJsZN +<br /> ' return false; ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' ZnAuxCal = 0; ' + AQuebraLinhaJsZN +<br /> ' for (ZnCont = 0; ZnCont < 9; ZnCont ++) ' + AQuebraLinhaJsZN +<br /> ' ZnAuxCal += parseInt(ZnCpfObj.value.charAt(ZnCont)) * (10 - ZnCont); ' + AQuebraLinhaJsZN +<br /> ' DgVZn = 11 - (ZnAuxCal % 11); ' + AQuebraLinhaJsZN +<br /> ' if (DgVZn == 10 || DgVZn == 11) ' + AQuebraLinhaJsZN +<br /> ' DgVZn = 0; ' + AQuebraLinhaJsZN +<br /> ' if (DgVZn != parseInt(ZnCpfObj.value.charAt(9))) ' + AQuebraLinhaJsZN +<br /> ' return false; ' + AQuebraLinhaJsZN +<br /> ' ZnAuxCal = 0; ' + AQuebraLinhaJsZN +<br /> ' for (ZnCont = 0; ZnCont < 10; ZnCont ++) ' + AQuebraLinhaJsZN +<br /> ' ZnAuxCal += parseInt(ZnCpfObj.value.charAt(ZnCont)) * (11 - ZnCont); ' + AQuebraLinhaJsZN +<br /> ' DgVZn = 11 - (ZnAuxCal % 11); ' + AQuebraLinhaJsZN +<br /> ' if (DgVZn == 10 || DgVZn == 11) ' + AQuebraLinhaJsZN +<br /> ' DgVZn = 0; ' + AQuebraLinhaJsZN +<br /> ' if (DgVZn != parseInt(ZnCpfObj.value.charAt(10))){ ' + AQuebraLinhaJsZN +<br /> ' return false;} ' + AQuebraLinhaJsZN +<br /> ' //alert("O CPF INFORMADO É VÁLIDO."); ' + AQuebraLinhaJsZN +<br /> ' return true; ' + AQuebraLinhaJsZN +<br /> '} ' + AQuebraLinhaJsZN;<br /><br /> AFncCriticaCNPJ =<br /> ' function ZnVerificaCnpj(ZNObjInput){' + AQuebraLinhaJsZN +<br /> ' var ZnDigitos, ZnDg, ZnSum, ZnCount;' + AQuebraLinhaJsZN +<br /> ' var ZnResult, ZnPos, tamanho;' + AQuebraLinhaJsZN +<br /> ' var ZnAuxCNPJ = ZNObjInput.value.replace(/\D+/g, "");' + AQuebraLinhaJsZN +<br /> '' + AQuebraLinhaJsZN +<br /> ' if (ZnAuxCNPJ.length != 14){' + AQuebraLinhaJsZN +<br /> ' ZNObjInput.focus();' + AQuebraLinhaJsZN +<br /> ' return false;' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> ' var gmSort = new Array(ZNObjInput.value.length); ' + AQuebraLinhaJsZN +<br /> ' for (i=0; i< ZNObjInput.value.length; i++){gmSort[i] = ZNObjInput.value.charAt(i);} ' + AQuebraLinhaJsZN +<br /> ' gmSort.sort(); ' + AQuebraLinhaJsZN +<br /> ' if (gmSort[0] == gmSort[gmSort.length -1]){ ' + AQuebraLinhaJsZN +<br /> ' alert("www.estacaozn.blogspot.com: Os números são iguais: " + ZNObjInput.value); ' + AQuebraLinhaJsZN +<br /> ' return false; ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> '' + AQuebraLinhaJsZN +<br /> ' ZnAuxTamanho = ZnAuxCNPJ.length - 2' + AQuebraLinhaJsZN +<br /> ' ZnDigitos = ZnAuxCNPJ.substring(0,ZnAuxTamanho);' + AQuebraLinhaJsZN +<br /> ' ZnDg = ZnAuxCNPJ.substring(ZnAuxTamanho);' + AQuebraLinhaJsZN +<br /> ' ZnSum = 0;' + AQuebraLinhaJsZN +<br /> ' ZnPos = ZnAuxTamanho - 7;' + AQuebraLinhaJsZN +<br /> ' for (ZnCount = ZnAuxTamanho; ZnCount >= 1; ZnCount--){' + AQuebraLinhaJsZN +<br /> ' ZnSum += ZnDigitos.charAt(ZnAuxTamanho - ZnCount) * ZnPos--;' + AQuebraLinhaJsZN +<br /> ' if (ZnPos < 2)' + AQuebraLinhaJsZN +<br /> ' ZnPos = 9;' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> ' ZnResult = ZnSum % 11 < 2 ? 0 : 11 - ZnSum % 11;' + AQuebraLinhaJsZN +<br /> ' if (ZnResult != ZnDg.charAt(0)){' + AQuebraLinhaJsZN +<br /> ' ZNObjInput.focus();' + AQuebraLinhaJsZN +<br /> ' return false;' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> '' + AQuebraLinhaJsZN +<br /> ' ZnAuxTamanho = ZnAuxTamanho + 1;' + AQuebraLinhaJsZN +<br /> ' ZnDigitos = ZnAuxCNPJ.substring(0,ZnAuxTamanho);' + AQuebraLinhaJsZN +<br /> ' ZnSum = 0;' + AQuebraLinhaJsZN +<br /> ' ZnPos = ZnAuxTamanho - 7;' + AQuebraLinhaJsZN +<br /> ' for (ZnCount = ZnAuxTamanho; ZnCount >= 1; ZnCount--){' + AQuebraLinhaJsZN +<br /> ' ZnSum += ZnDigitos.charAt(ZnAuxTamanho - ZnCount) * ZnPos--;' + AQuebraLinhaJsZN +<br /> ' if (ZnPos < 2)' + AQuebraLinhaJsZN +<br /> ' ZnPos = 9;}' + AQuebraLinhaJsZN +<br /> '' + AQuebraLinhaJsZN +<br /> ' ZnResult = ZnSum % 11 < 2 ? 0 : 11 - ZnSum % 11;' + AQuebraLinhaJsZN +<br /> ' if (ZnResult != ZnDg.charAt(1)){' + AQuebraLinhaJsZN +<br /> ' ZNObjInput.focus();' + AQuebraLinhaJsZN +<br /> ' return false;}' + AQuebraLinhaJsZN +<br /> ' else {' + AQuebraLinhaJsZN +<br /> ' return true;' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN;<br /><br /> AFncValorRequerido =<br /> ' function ValorRequerido(){ ' + AQuebraLinhaJsZN +<br /> ' var ObjInput = document.getElementById("%s"); ' + AQuebraLinhaJsZN +<br /> ' var AFriendlyName = "%s"; ' + AQuebraLinhaJsZN +<br /> ' if (ObjInput.value == ""){ ' + AQuebraLinhaJsZN +<br /> ' alert("É obrigatório o valor para o campo: " + AFriendlyName); ' + AQuebraLinhaJsZN +<br /> ' ObjInput.style.backgroundColor = "#FD88AA"; ' + AQuebraLinhaJsZN +<br /> ' ObjInput.focus(); ' + AQuebraLinhaJsZN +<br /> ' return false; ' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> ' else { ' + AQuebraLinhaJsZN +<br /> ' ObjInput.style.backgroundColor = "#FFFFFF"; ' + AQuebraLinhaJsZN +<br /> ' }' + AQuebraLinhaJsZN +<br /> ' return true;}' + AQuebraLinhaJsZN;<br /><br /> AFncCriticaCIC2 =<br /> ' function CriticaCIC2(ZnCnpjBool, ZnCpfBool){ ' + AQuebraLinhaJsZN +<br /> ' var ZnNumCic = document.getElementById("%s"); ' + AQuebraLinhaJsZN +<br /> ' alert("www.estacaozn.blogspot.com verifica CPF/CNPJ");' + AQuebraLinhaJsZN +<br /> ' var CicValidoZn = false; ' + AQuebraLinhaJsZN +<br /> ' ' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && !ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' if(!ZnVerificaCnpj(ZnNumCic)){ ' + AQuebraLinhaJsZN +<br /> ' alert("CNPJ Inválido"); ' + AQuebraLinhaJsZN +<br /> ' return false;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' else if (!ZnCnpjBool && ZnCpfBool){ ' + AQuebraLinhaJsZN +<br /> ' if (!ZnVerificaCPF(ZnNumCic)){ ' + AQuebraLinhaJsZN +<br /> ' alert("CPF inválido"); ' + AQuebraLinhaJsZN +<br /> ' return false; ' + AQuebraLinhaJsZN +<br /> ' ;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' else { ' + AQuebraLinhaJsZN +<br /> ' CicValidoZn = ZnVerificaCnpj(ZnNumCic); ' + AQuebraLinhaJsZN +<br /> ' if(CicValidoZn){ ' + AQuebraLinhaJsZN +<br /> ' return true;} ' + AQuebraLinhaJsZN +<br /> ' else{ ' + AQuebraLinhaJsZN +<br /> ' CicValidoZn = ZnVerificaCPF(ZnNumCic); ' + AQuebraLinhaJsZN +<br /> ' if(!CicValidoZn){ ' + AQuebraLinhaJsZN +<br /> ' alert("CIC Inválido") ' + AQuebraLinhaJsZN +<br /> ' return false;} ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' } ' + AQuebraLinhaJsZN +<br /> ' var ZnMsg = ""; ' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CPJ ou CNPJ"; }' + AQuebraLinhaJsZN +<br /> ' if (ZnCnpjBool && !ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CNPJ"; }' + AQuebraLinhaJsZN +<br /> ' if (!ZnCnpjBool && ZnCpfBool) { ' + AQuebraLinhaJsZN +<br /> ' ZnMsg = "CPF"; }' + AQuebraLinhaJsZN +<br /> ' alert("Valor Validado Ok, " +ZnMsg + ": " + ZnNumCic.value);' + AQuebraLinhaJsZN +<br /> ' return true;} ' + AQuebraLinhaJsZN;<br /><br />procedure TIWForm1.IWAppFormCreate(Sender: TObject);<br />begin<br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(AFncCriticaCPF);<br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(AFncCriticaCNPJ);<br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(AFncCriticaCIC);<br /> Self.JavaScript.Add('');<br /> // O IWButton1 vai validar as duas opções CPF e CNPJ<br /> IWButton1.Caption := 'Valida CPF e CNPJ';<br /> IWButton1.Width := 200;<br /> IWButton1.ExtraTagParams.Add(<br /> Format('onClick=CriticaCIC(%s, %s, %s)', [UpperCase(IWEdit1.Name),<br /> 'true', 'true']));<br /> //O IWButton2 vai validar apenas CPF<br /> IWButton2.Caption := 'Valida CPF';<br /> IWButton2.Width := 200;<br /> IWButton2.ExtraTagParams.Add(<br /> Format('onClick=CriticaCIC(%s, %s, %s)', [UpperCase(IWEdit1.Name),<br /> 'false', 'true']));<br /> //O IWButton3 vai validar apenas CNPJ<br /> IWButton3.Caption := 'Valida CNPJ';<br /> IWButton3.Width := 200;<br /> IWButton3.ExtraTagParams.Add(<br /> Format('onClick=CriticaCIC(%s, %s, %s)', [UpperCase(IWEdit1.Name),<br /> 'true', 'false']));<br /><br /> (* segunda parte do artigo:<br /> OnClick do IWButton chamar mais de uma função Javascript *)<br /> IWEdit1.FriendlyName := 'CIC: CNPJ ou CPF';<br /> Self.JavaScript.Add('//**************************************');<br /> Self.JavaScript.Add('//segunda parte do artigo:' + #13 +<br /> '// OnClick do IWButton chamar mais de uma função Javascript');<br /> Self.JavaScript.Add(Format(AFncCriticaCIC2, [UpperCase(IWEdit1.Name)]));<br /> Self.JavaScript.Add('');<br /><br /> Self.JavaScript.Add('');<br /> Self.JavaScript.Add(Format(AFncValorRequerido, [UpperCase(IWEdit1.Name),<br /> IWEdit1.FriendlyName]));<br /> Self.JavaScript.Add('//*******www.estacaozn.blogspot.com**********');<br /><br /> IWButton4.Caption := 'Valor Obrigatório & Valida CIC';<br /> IWButton4.Width := 360;<br /> IWButton4.ScriptEvents.Add('onClick').EventCode.Add(<br /> 'return ValorRequerido() && CriticaCIC2(true, true)');<br /><br /> (* testando chamar duas funções Javascript na propriedade ExtraTagParams *)<br /><br /> (* IWButton5.ExtraTagParams.Add(<br /> Format('onClick=return ValorRequerido() && CriticaCIC(%s, %s, %s)', [UpperCase(IWEdit1.Name),<br /> 'true', 'true'])); *)<br /><br /> IWButton5.ExtraTagParams.Add(<br /> Format('onClick=return ValorRequerido() && CriticaCIC2(true, true)',<br /> [UpperCase(IWEdit1.Name)]));<br />end;<br /><br />procedure TIWForm1.IWButton4Click(Sender: TObject);<br />begin<br /> IWLabel1.Font.Size := 16;<br /> IWLabel1.Caption := Format('Valor digitado válido: %s', [IWEdit1.Text]); ;<br />end;<br /><br />procedure TIWForm1.IWButton5Click(Sender: TObject);<br />begin<br /> IWLabel1.Caption := IWEdit1.Text;<br /> WebApplication.ShowMessage('Se você esta codificando esse exemplo corretamente, '+<br /> 'essa mensagem nunca não vai ser exibida. Jamais será! Garanto (heheh ..).');<br />end;<br />(* esse trecho para Intrweb 8*)<br />initialization<br /> TIWForm1.SetAsMainForm;<br /></pre><br /><div style="text-align: justify;"><br />Abaixo, trecho código Javascript gerado pelo Intraweb como resultado do processamento do que implementamos em Delphi.</div><br /><br /><pre name="code" class="javascript"><br />function ZnVerificaCPF (ZnCpfObj){ <br /> var gmSort = new Array(ZnCpfObj.value.length); <br /> for (i=0; i< ZnCpfObj.value.length; i++){gmSort[i] = ZnCpfObj.value.charAt(i);} <br /> gmSort.sort(); <br /> if (gmSort[0] == gmSort[gmSort.length -1]){ <br /> alert("www.estacaozn.blogspot.com: Os números são iguais: " + ZnCpfObj.value); <br /> return false; <br /> } <br /> ZnAuxCal = 0; <br /> for (ZnCont = 0; ZnCont < 9; ZnCont ++) <br /> ZnAuxCal += parseInt(ZnCpfObj.value.charAt(ZnCont)) * (10 - ZnCont); <br /> DgVZn = 11 - (ZnAuxCal % 11); <br /> if (DgVZn == 10 || DgVZn == 11) <br /> DgVZn = 0; <br /> if (DgVZn != parseInt(ZnCpfObj.value.charAt(9))) <br /> return false; <br /> ZnAuxCal = 0; <br /> for (ZnCont = 0; ZnCont < 10; ZnCont ++) <br /> ZnAuxCal += parseInt(ZnCpfObj.value.charAt(ZnCont)) * (11 - ZnCont); <br /> DgVZn = 11 - (ZnAuxCal % 11); <br /> if (DgVZn == 10 || DgVZn == 11) <br /> DgVZn = 0; <br /> if (DgVZn != parseInt(ZnCpfObj.value.charAt(10))){ <br /> return false;} <br /> //alert("O CPF INFORMADO É VÁLIDO."); <br /> return true; <br />} <br /><br /><br /> function ZnVerificaCnpj(ZNObjInput){<br /> var ZnDigitos, ZnDg, ZnSum, ZnCount;<br /> var ZnResult, ZnPos, tamanho;<br /> var ZnAuxCNPJ = ZNObjInput.value.replace(/\D+/g, "");<br /><br /> if (ZnAuxCNPJ.length != 14){<br /> ZNObjInput.focus();<br /> return false;<br /> }<br /> var gmSort = new Array(ZNObjInput.value.length); <br /> for (i=0; i< ZNObjInput.value.length; i++){gmSort[i] = ZNObjInput.value.charAt(i);} <br /> gmSort.sort(); <br /> if (gmSort[0] == gmSort[gmSort.length -1]){ <br /> alert("www.estacaozn.blogspot.com: Os números são iguais: " + ZNObjInput.value); <br /> return false; <br /> } <br /><br /> ZnAuxTamanho = ZnAuxCNPJ.length - 2<br /> ZnDigitos = ZnAuxCNPJ.substring(0,ZnAuxTamanho);<br /> ZnDg = ZnAuxCNPJ.substring(ZnAuxTamanho);<br /> ZnSum = 0;<br /> ZnPos = ZnAuxTamanho - 7;<br /> for (ZnCount = ZnAuxTamanho; ZnCount >= 1; ZnCount--){<br /> ZnSum += ZnDigitos.charAt(ZnAuxTamanho - ZnCount) * ZnPos--;<br /> if (ZnPos < 2)<br /> ZnPos = 9;<br /> }<br /> ZnResult = ZnSum % 11 < 2 ? 0 : 11 - ZnSum % 11;<br /> if (ZnResult != ZnDg.charAt(0)){<br /> ZNObjInput.focus();<br /> return false;<br /> }<br /><br /> ZnAuxTamanho = ZnAuxTamanho + 1;<br /> ZnDigitos = ZnAuxCNPJ.substring(0,ZnAuxTamanho);<br /> ZnSum = 0;<br /> ZnPos = ZnAuxTamanho - 7;<br /> for (ZnCount = ZnAuxTamanho; ZnCount >= 1; ZnCount--){<br /> ZnSum += ZnDigitos.charAt(ZnAuxTamanho - ZnCount) * ZnPos--;<br /> if (ZnPos < 2)<br /> ZnPos = 9;}<br /><br /> ZnResult = ZnSum % 11 < 2 ? 0 : 11 - ZnSum % 11;<br /> if (ZnResult != ZnDg.charAt(1)){<br /> ZNObjInput.focus();<br /> return false;}<br /> else {<br /> return true;<br /> }<br /> }<br /><br /><br /> function CriticaCIC(ZnNumCic, ZnCnpjBool, ZnCpfBool){ <br /> alert("www.estacaozn.blogspot.com verifica CPF/CNPJ");<br /> var CicValidoZn = false; <br /> <br /> if (ZnCnpjBool && !ZnCpfBool) { <br /> if(!ZnVerificaCnpj(ZnNumCic)){ <br /> alert("CNPJ Inválido"); <br /> return false;} <br /> } <br /> else if (!ZnCnpjBool && ZnCpfBool){ <br /> if (!ZnVerificaCPF(ZnNumCic)){ <br /> alert("CPF inválido"); <br /> return false; <br /> ;} <br /> } <br /> else { <br /> CicValidoZn = ZnVerificaCnpj(ZnNumCic); <br /> if(CicValidoZn){ <br /> return true;} <br /> else{ <br /> CicValidoZn = ZnVerificaCPF(ZnNumCic); <br /> if(!CicValidoZn){ <br /> alert("CIC Inválido") <br /> return false;} <br /> } <br /> } <br /> var ZnMsg = ""; <br /> if (ZnCnpjBool && ZnCpfBool) { <br /> ZnMsg = "CPJ ou CNPJ"; }<br /> if (ZnCnpjBool && !ZnCpfBool) { <br /> ZnMsg = "CNPJ"; }<br /> if (!ZnCnpjBool && ZnCpfBool) { <br /> ZnMsg = "CPF"; }<br /> alert("Valor Validado Ok, " +ZnMsg + ": " + ZnNumCic.value);<br /> return true;} <br /><br /><br />//**************************************<br />//segunda parte do artigo:<br />// OnClick do IWButton chamar mais de uma função Javascript<br /> function CriticaCIC2(ZnCnpjBool, ZnCpfBool){ <br /> var ZnNumCic = document.getElementById("IWEDIT1"); <br /> alert("www.estacaozn.blogspot.com verifica CPF/CNPJ");<br /> var CicValidoZn = false; <br /> <br /> if (ZnCnpjBool && !ZnCpfBool) { <br /> if(!ZnVerificaCnpj(ZnNumCic)){ <br /> alert("CNPJ Inválido"); <br /> return false;} <br /> } <br /> else if (!ZnCnpjBool && ZnCpfBool){ <br /> if (!ZnVerificaCPF(ZnNumCic)){ <br /> alert("CPF inválido"); <br /> return false; <br /> ;} <br /> } <br /> else { <br /> CicValidoZn = ZnVerificaCnpj(ZnNumCic); <br /> if(CicValidoZn){ <br /> return true;} <br /> else{ <br /> CicValidoZn = ZnVerificaCPF(ZnNumCic); <br /> if(!CicValidoZn){ <br /> alert("CIC Inválido") <br /> return false;} <br /> } <br /> } <br /> var ZnMsg = ""; <br /> if (ZnCnpjBool && ZnCpfBool) { <br /> ZnMsg = "CPJ ou CNPJ"; }<br /> if (ZnCnpjBool && !ZnCpfBool) { <br /> ZnMsg = "CNPJ"; }<br /> if (!ZnCnpjBool && ZnCpfBool) { <br /> ZnMsg = "CPF"; }<br /> alert("Valor Validado Ok, " +ZnMsg + ": " + ZnNumCic.value);<br /> return true;} <br /><br /><br /><br /> function ValorRequerido(){ <br /> var ObjInput = document.getElementById("IWEDIT1"); <br /> var AFriendlyName = "CIC: CNPJ ou CPF"; <br /> if (ObjInput.value == ""){ <br /> alert("É obrigatório o valor para o campo: " + AFriendlyName); <br /> ObjInput.style.backgroundColor = "#FD88AA"; <br /> ObjInput.focus(); <br /> return false; <br /> }<br /> else { <br /> ObjInput.style.backgroundColor = "#FFFFFF"; <br /> }<br /> return true;}<br /><br />//*******www.estacaozn.blogspot.com**********<br /><br />function Validate() {<br /> return true;<br />}<br /><br /></pre><br /><br /></span>GMotta ZNhttp://www.blogger.com/profile/14738149386892914626noreply@blogger.com4tag:blogger.com,1999:blog-1939219507308718594.post-21648425462456029172009-03-28T10:07:00.003-03:002009-03-28T10:17:16.826-03:00Ajax-enabled Web Services with ScriptManager<a href="http://estacaozn.blogspot.com/2009/03/web-services-em-ajax-com-scriptmanager.html">Clique aqui para ver este post em Português</a><br /><br />In this post I'll show an incredible ASP.Net feature I've learned recently: Ajax-enabled Web Services.<br /><br />With the ScriptManager component (that we've already seen in <a href="http://estacaozn.blogspot.com/2009/03/ajax-in-simple-way-with-aspnet.html">this post</a>) we're able to consume a Web Service in our Web Site and use the results in JavaScript with little to none specific programming effort. With this component, the Web Service looks like it's a client script object.<br /><br /><span class='fullpost'><br />Let's start with a new Web Site in Visual Studio (the Visual Web Developer express edition works fine, too). Choose a folder to save the Web Site (you don't need the IIS installed in order to test de project). Now we'll create the Web Service.<br /><br />Right-click the Web Site's root directory and choose Add New Item. In the dialog box select Web Service. Name it AjaxWs.asmx and click Ok. The IDE should open the file App_Code/AjaxWs.cs. This is where we're gonna work.<br /><br />Let's leave its implementation as it is for now. It should come with a sample method HelloWorld. The only thing we'll do is "enable" the client script calls. To do that find the class definition:<br /><br /><pre name="code" class="csharp">public class AjaxWs : System.Web.Services.WebService</pre><br /><br />In the line above there's a commented class decoration that we only need to remove the comment bars to enable this feature:<br /><br /><pre name="code" class="csharp">// [System.Web.Script.Services.ScriptService]</pre><br /><br />So, remove the comment and save the file and click the menu Build > Build Web Site.<br /><br />The Web Service part is done (for now). Now we're gonna code the Web Form that calls the Web Service. Open the Default.aspx file and go to the visualization "Source" or "Split". Below the form tag<br /><br /><pre name="code" class="xml"><form id="form1" runat="server"></pre><br /><br />We're gonna add a ScriptManager component. You can drag it from the toolbox or simply type manually the asp:ScriptManager tag. The VS makes the effort of type the tags manually very smooth, even if it may not seem that way. After done the tag looks like this:<br /><br /><pre name="code" class="xml"><asp:ScriptManager runat="server" ID="ScriptMngr"><br /> <Services><br /> <asp:ServiceReference Path="~/AjaxWs.asmx" /><br /> </Services><br /></asp:ScriptManager></pre><br /><br />We'll now create a client script block in our Web Form. Find the head section and add a script block inside. Here's the code:<br /><br /><pre name="code" class="xml"><head runat="server"><br /> <title>Untitled Page</title><br /> <script type="text/javascript"><br /> function executarWs() {<br /> AjaxWs.HelloWorld(<br /> function(resultado) {<br /> alert(resultado)<br /> }<br /> )<br /> }<br /> </script><br /></head></pre><br /><br />I'll give a brief explanation about this script:<br /><br />AjaxWs - Our Web Service - was created by VS when we added the ScriptManager component and referenced the ~/AjaxWs.asmx Web Service. We're coding a method call to Hello World and pass a function as an argument - more precisely a callback. A callback is a function definition that is called when the function that took is as an argument needs. Think of it as some sort of event handler. But it's subject for another post.<br /><br />Now we need to call this method. We've seen "new feature" part. Now we're gonna call our Web Service's methods as an ordinary JavaScript call. We'll create a HTML button to call the JavaScript function:<br /><br /><pre name="code" class="xml"><button onclick="executarWs()">Clique aqui</button></pre><br /><br />Here goes the complete WebForm's code:<br /><br /><pre name="code" class="xml"><%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %><br /><br /><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><br /><br /><html xmlns="http://www.w3.org/1999/xhtml"><br /><head runat="server"><br /> <title>Untitled Page</title><br /> <script type="text/javascript"><br /> function executarWs() {<br /> AjaxWs.HelloWorld(<br /> function(resultado) {<br /> alert(resultado)<br /> }<br /> )<br /> }<br /> </script><br /></head><br /><body><br /> <form id="form1" runat="server"><br /> <asp:ScriptManager runat="server" ID="ScriptMngr"><br /> <Services><br /> <asp:ServiceReference Path="~/AjaxWs.asmx" /><br /> </Services><br /> </asp:ScriptManager><br /> <div><br /> <button onclick="executarWs()">Clique aqui</button><br /> </div><br /> </form><br /></body><br /></html></pre><br /><br />Now run the Web Site (F5) to see what we've done in action. When we click the button the message "Hello World" will pop up. This alone is very nice already; but, what if we could return objects with properties instead of pure strings and ints? Well, we can!<br /><br />First, let's create a class in our Web Site. Right click in the App_Code folder below the root folder and choose Add New Item. In the dialog box choose Class. Name it Pessoa.cs and click Ok. Here's the complete code:<br /><br /><pre name="code" class="csharp">public class Pessoa {<br /><br /> public string Nome { get; set; }<br /> public string Sobrenome { get; set; }<br /><br />}</pre><br /><br />Now let's get back to our Web Service and create a new method that take two parameters and returns an instance of Pessoa. Open the AjaxWs.cs again and add the following code under the HelloWorld method:<br /><br /><pre name="code" class="csharp">[WebMethod]<br />public Pessoa ObterPessoa(string nome, string sobrenome) {<br /> return new Pessoa { Nome = nome, Sobrenome = sobrenome };<br />}</pre><br /><br />Now get back to Default.aspx and modify the HelloWorld method call to ObetrPessoa, giving the nome and sobrenome arguments before the callback argument:<br /><br /><pre name="code" class="csharp">function executarWs() {<br /> AjaxWs.ObterPessoa(<br /> "Estação",<br /> "ZN",<br /> function(resultado) {<br /> alert(resultado.Nome + " " + resultado.Sobrenome)<br /> }<br /> )<br />}</pre><br /><br />Now run the Web Site again and see the result. Awesome! We had nearly zero effort and the possibilities are many with this technology. Thank you and take care.<br /></span>Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-61573724325374775702009-03-28T09:54:00.002-03:002009-03-28T10:06:26.925-03:00Web Services em Ajax com ScriptManager<a href="#">Click here to see this post in English</a><br /><br />Neste post eu mostro uma facilidade incrível do ASP.Net que eu aprendi: Acessar Web Services via Ajax.<br /><br />Com o componente ScriptManager - é o mesmo <a href="http://estacaozn.blogspot.com/2009/03/ajax-de-um-jeito-simples-em-aspnet.html">daquele post sobre ASP.Net e Ajax</a> - podemos incluir referência para um Web Service criado no nosso WebSite, executá-lo e recuperar o resultado com um esforço mínimo de código. Com este componente parece que o Web Service é um objeto do próprio Script cliente da nossa página.<br /><br /><span class='fullpost'><br />Bem, vamos começar criando projeto WebSite no Visual Studio (pode ser o Visual Web Developer Express Edition também). Escolham uma pasta para abrigar o WebSite (lembrando que para testar o VS inicia um servidor Web virtual com o nosso site) e pronto. Agora vamos criar nosso Web Service.<br /><br />Clique com o botão direito na raiz do WebSite e selecione Add New Item. Na janela de New Item escolha Web Service. Chame de AjaxWs.asmx e clique Ok. A IDE vai abrir o arquivo App_Code/AjaxWs.cs. É nele que vamos trabalhar<br /><br />Vamos Deixar a implementação dele como está por enquanto. Ele já vem com um método de exemplo HelloWorld. A única coisa que vamos fazer é "habilitar" que ele seja chamado por Script cliente. Para isso procure a definição da classe:<br /><br /><pre name="code" class="csharp">public class AjaxWs : System.Web.Services.WebService</pre><br /><br />Na linha acima desta há uma decoração comentada que nós só precisamos descomentar para adicionar esta funcionalidade:<br /><br /><pre name="code" class="csharp">// [System.Web.Script.Services.ScriptService]</pre><br /><br />Portanto descomente esta linha e salve o arquivo e chame o menu Build > Build Web Site.<br /><br />A parte do Web Service está pronte (por enquanto). Agora vamos trabalhar no nosso WebForm para chamar este Web Service. Abra o arquivo Default.aspx e vá para a visualização "Source" ou "Split". Abaixo da tag do form<br /><br /><pre name="code" class="xml"><form id="form1" runat="server"></pre><br /><br />vamos colocar um componente ScriptManager. Você pode arrastar da toolbox ou simplesmente digitar a tag. O VS deixa o tabalhar de digitar os componentes muito rápido e produtivo, apesar de parecer o contrário. Enfim, a tag fica assim depois de pronta:<br /><br /><pre name="code" class="xml"><asp:ScriptManager runat="server" ID="ScriptMngr"><br /> <Services><br /> <asp:ServiceReference Path="~/AjaxWs.asmx" /><br /> </Services><br /></asp:ScriptManager></pre><br /><br />Com ele aí vamos criar um bloco de script na nossa página. Procure a seção <header> do WebForm e crie um bloco de script dentro. Abaixo está o código:<br /><br /><pre name="code" class="xml"><head runat="server"><br /> <title>Untitled Page</title><br /> <script type="text/javascript"><br /> function executarWs() {<br /> AjaxWs.HelloWorld(<br /> function(resultado) {<br /> alert(resultado)<br /> }<br /> )<br /> }<br /> </script><br /></head></pre><br /><br />Vou dar uma breve explicação sobre este script:<br /><br />AjaxWs - que é o nome do nosso Web Service - foi definido automaticamente pelo VS quando nós colocamos o ScriptManager no WebForm. Estamos chamando o método HelloWorld do nosso Web Service e passando como argumento uma função - mais precisamente um callback. Um callback é uma definição de função que será chamado pela função que nós invocamos quando necessário. É um conceito semelhante ao de manipuladores de eventos. Em outro post eu me dedico somente a JavaScript.<br /><br />Agora precisamos executar esta função de alguma maneira. A novidade da tecnologia já passou; agora podemos fazer como uma chamada normal de alguma função JavaScript. Para este exemplo vou criar um botão HTML no WebForm:<br /><br /><pre name="code" class="xml"><button onclick="executarWs()">Clique aqui</button></pre><br /><br />Abaixo segue o WebForm completo:<br /><br /><pre name="code" class="xml"><%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %><br /><br /><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><br /><br /><html xmlns="http://www.w3.org/1999/xhtml"><br /><head runat="server"><br /> <title>Untitled Page</title><br /> <script type="text/javascript"><br /> function executarWs() {<br /> AjaxWs.HelloWorld(<br /> function(resultado) {<br /> alert(resultado)<br /> }<br /> )<br /> }<br /> </script><br /></head><br /><body><br /> <form id="form1" runat="server"><br /> <asp:ScriptManager runat="server" ID="ScriptMngr"><br /> <Services><br /> <asp:ServiceReference Path="~/AjaxWs.asmx" /><br /> </Services><br /> </asp:ScriptManager><br /> <div><br /> <button onclick="executarWs()">Clique aqui</button><br /> </div><br /> </form><br /></body><br /></html></pre><br /><br />Agora execute o programa (F5) para ver o que nós fizemos em ação. Quando clicamos no botão a mensagem "Hello World" aparece. Isso por si só já é muito legal, mas imagine se, em vez de retornar somente uma string, pudéssemos retornar objetos com propriedades? Mas só pode!<br /><br />Primeiro vamos criar uma classe no Web Site. Clique com o botão direito na pasta App_Code dentro da raiz do Web Site e clique Add New Item. Na janela selecione Class. chame o arquivo de Pessoa.cs e clique Ok. abaixo segue a classe pronta:<br /><br /><pre name="code" class="csharp">public class Pessoa {<br /><br /> public string Nome { get; set; }<br /> public string Sobrenome { get; set; }<br /><br />}</pre><br /><br />Agora vamos voltar no nosso Web Service e criar um novo método que pegue dois parâmetros e retorne uma instância de PEssoa. Abra o AjaxWs.cs outra vez e adicione o seguinte método abaixo do HelloWorld:<br /><br /><pre name="code" class="csharp">[WebMethod]<br />public Pessoa ObterPessoa(string nome, string sobrenome) {<br /> return new Pessoa { Nome = nome, Sobrenome = sobrenome };<br />}</pre><br /><br />Agora volte no Default.aspx e modifique a chamada do método HelloWorld para ObterPessoa, passando agora os argumentos nome e sobrenome antes da função de callback:<br /><br /><pre name="code" class="csharp">function executarWs() {<br /> AjaxWs.ObterPessoa(<br /> "Estação",<br /> "ZN",<br /> function(resultado) {<br /> alert(resultado.Nome + " " + resultado.Sobrenome)<br /> }<br /> )<br />}</pre><br /><br />Agora execute novamente e veja o resultado. Demais! Nosso esforço foi praticamente zero o as possibilidades são muitas com esta tecnologia. Um grande abraço a todos e até a próxima!<br /></span>Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com0tag:blogger.com,1999:blog-1939219507308718594.post-68078369033080629282009-03-28T09:36:00.003-03:002009-03-28T09:47:33.435-03:00Ajax in a Simple way with ASP.NET<a href="http://estacaozn.blogspot.com/2009/03/ajax-de-um-jeito-simples-em-aspnet.html">Clique aqui para ver este post em Português</a><br /><br />Hello. In this post I'll show a very nice way to enable Ajax in our ASP.NET WebForms I learned.<br /><br />When I (and most people) learned Ajax, the solution was to use a javascript object (XmlHttpRequest), create a separate script to process the request and write code to display the results that come in XML or plain text. I must confess that I always liked to work with Ajax, even with all that code effort xD<br /><br />Another interesting point is the debugging and the error tracking.<br /><br /><span class='fullpost'><br />In VS 2008 there are a couple of simple, but very useful components that allows us to work with Ajax in an easy and transparent way: ScriptManager and UpdatePanel.<br /><br />To demonstrate the use of these components I'll create an ASP.NET WebForm that searches an object collection, and next add these componentes to enable Ajax. So, Let's start with an ASP.NET WebSite and edit the Default.aspx. Here goes the Markup source code:<br /><br /><pre name="code" class="xml"><%@ Page Language="C#" AutoEventWireup="true"<br /> CodeFile="Default.aspx.cs" Inherits="_Default" %><br /><br /><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"<br /> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><br /><br /><html xmlns="http://www.w3.org/1999/xhtml"><br /><head runat="server"><br /> <title>Ajax com ASP.NET</title><br /></head><br /><body><br /> <form id="form1" runat="server"><br /> <div><br /> <p><br /> Busca: <asp:TextBox runat="server" ID="BuscaTxt" Width="200" /> <br /> <asp:Button runat="server" ID="BuscaBtn" Text="Buscar"<br /> onclick="BuscaBtn_Click" /><br /> </p><br /> <br /> <div><br /> <asp:GridView runat="server"<br /> ID="PessoasGridView"<br /> AutoGenerateColumns="false"<br /> CellPadding="4"<br /> CellSpacing="0"><br /> <Columns><br /> <asp:BoundField DataField="Nome"<br /> HeaderText="Nome"<br /> HeaderStyle-Width="200" /><br /> <asp:BoundField DataField="Sobrenome"<br /> HeaderText="Sobrenome"<br /> HeaderStyle-Width="200" /><br /> </Columns><br /> </asp:GridView><br /> </div><br /> </div><br /> </form><br /></body><br /></html></pre><br /><br />Now the source code of Default.aspx.cs:<br /><br /><pre name="code" class="csharp">using System;<br />using System.Collections.Generic;<br />using System.Linq;<br /><br />public partial class _Default : System.Web.UI.Page {<br /><br /> class Pessoa {<br /> public string Nome { get; set; }<br /> public string Sobrenome { get; set; }<br /> }<br /><br /> private List<Pessoa> Pessoas = new List<Pessoa>{<br /> new Pessoa { Nome = "Felipe", Sobrenome = "Guerço" },<br /> new Pessoa { Nome = "Gerson", Sobrenome = "Motta" },<br /> new Pessoa { Nome = "Joaquim", Sobrenome = "José" },<br /> new Pessoa { Nome = "João", Sobrenome = "Silva" },<br /> new Pessoa { Nome = "Aristarco", Sobrenome = "Pederneiras" },<br /> };<br /><br /> protected void Consultar() {<br /> PessoasGridView.DataSource =<br /> from p in Pessoas<br /> where p.Nome.Contains(BuscaTxt.Text)<br /> orderby p.Nome<br /> select p;<br /> PessoasGridView.DataBind();<br /> }<br /><br /> protected void Page_Load(object sender, EventArgs e) {<br /><br /> }<br /> protected void BuscaBtn_Click(object sender, EventArgs e) {<br /> Consultar();<br /> }<br />}</pre><br /><br />With that we can query the private member Pessoas according to the filter criteria in the textbox. But this way each request will produce a full round trip just to update the grid contents. Let's see how to avoid this with the Ajax components.<br /><br />We'll add the ScriptManager component in our WebForm in order to enable Ajax. Next we'll add the UpdatePanel and put the grid "inside" it.<br /><br />The UpdatePanel is a very interesting component. It represents a "piece" of the WebForm that is updated when certain events are fired up. But which events? Here comes the interesting part: We configure which component's events we want to "trigger" the update panel. In other words: When that action fires up the only part updated is the content inside the UpdatePanel. Let's see the markup here:<br /><br /><pre name="code" class="xml"><asp:UpdatePanel runat="server" ID="GridUpdatePanel"><br /> <Triggers><br /> <asp:AsyncPostBackTrigger<br /> ControlID="BuscaBtn" EventName="Click" /><br /> </Triggers><br /> <ContentTemplate><br /> <asp:GridView runat="server"<br /> ID="PessoasGridView"<br /> AutoGenerateColumns="false"<br /> CellPadding="4"<br /> CellSpacing="0"><br /> <Columns><br /> <asp:BoundField DataField="Nome"<br /> HeaderText="Nome"<br /> HeaderStyle-Width="200" /><br /> <asp:BoundField DataField="Sobrenome"<br /> HeaderText="Sobrenome"<br /> HeaderStyle-Width="200" /><br /> </Columns><br /> </asp:GridView><br /> </ContentTemplate><br /></asp:UpdatePanel></pre><br /><br />Now the entire WebForm markup:<br /><br /><pre name="code" class="xml"><%@ Page Language="C#" AutoEventWireup="true"<br /> CodeFile="Default.aspx.cs" Inherits="_Default" %><br /><br /><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"<br /> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><br /><br /><html xmlns="http://www.w3.org/1999/xhtml"><br /><head runat="server"><br /> <title>Ajax com ASP.NET</title><br /></head><br /><body><br /> <form id="form1" runat="server"><br /> <asp:ScriptManager runat="server" ID="AjaxScriptManager" /><br /> <div><br /> <p><br /> Busca: <asp:TextBox runat="server" ID="BuscaTxt" Width="200" /> <br /> <asp:Button runat="server" ID="BuscaBtn" Text="Buscar"<br /> onclick="BuscaBtn_Click" /><br /> </p><br /> <br /> <div><br /> <asp:UpdatePanel runat="server" ID="GridUpdatePanel"><br /> <Triggers><br /> <asp:AsyncPostBackTrigger<br /> ControlID="BuscaBtn" EventName="Click" /><br /> </Triggers><br /> <ContentTemplate><br /> <asp:GridView runat="server"<br /> ID="PessoasGridView"<br /> AutoGenerateColumns="false"<br /> CellPadding="4"<br /> CellSpacing="0"><br /> <Columns><br /> <asp:BoundField DataField="Nome"<br /> HeaderText="Nome"<br /> HeaderStyle-Width="200" /><br /> <asp:BoundField DataField="Sobrenome"<br /> HeaderText="Sobrenome"<br /> HeaderStyle-Width="200" /><br /> </Columns><br /> </asp:GridView><br /> </ContentTemplate><br /> </asp:UpdatePanel><br /> </div><br /> </div><br /> </form><br /></body><br /></html></pre><br /><br />Try to run the WebSite and notice that the page doesn't refresh anymore. And the best part is that we didn't need to write any javascript code and create any "support" files.<br /><br />Thank you for the support and until next time.<br /></span>Felipe Guerçohttp://www.blogger.com/profile/05585381954892986721noreply@blogger.com0