<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Programação &#8211; Velho Bit</title>
	<atom:link href="https://velhobit.com.br/programacao/feed" rel="self" type="application/rss+xml" />
	<link>https://velhobit.com.br</link>
	<description>Artigos, Notícias e Tutoriais sobre Web Design, Design Gráfico, Desenvolvimento e Programação Web... e um tico de games</description>
	<lastBuildDate>Fri, 25 Apr 2025 13:14:17 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://velhobit.com.br/wp-content/uploads/2024/10/cropped-minieu-32x32.png</url>
	<title>Programação &#8211; Velho Bit</title>
	<link>https://velhobit.com.br</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Como adicionar e remover dinamicamente campos HTML em um Formulário? (Javascript puro)</title>
		<link>https://velhobit.com.br/programacao/como-adicionar-e-remover-dinamicamente-um-elemento-html-a-partir-de-um-input-javascript-puro.html</link>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Sun, 14 Feb 2021 21:47:36 +0000</pubDate>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[dinâmico]]></category>
		<category><![CDATA[dinamismo]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[formulário]]></category>
		<category><![CDATA[front-end]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[javascript puro]]></category>
		<category><![CDATA[programação]]></category>
		<guid isPermaLink="false">https://velhobit.com.br/?p=2099</guid>

					<description><![CDATA[Adicione ou remova dinamicamente um ou mais campos em seu formulário, usando Javascript puro]]></description>
										<content:encoded><![CDATA[
<p>O Javascript nos permite criar conteúdos dinâmicos e podemos usar isso para adicionar remover e adicionar elementos de acordo com as opções do usuário. Dados como informações sobre dependentes,  links de mídias sociais, e-mails adicionais, etc. são curtos e não fazem sentido criarmos um formulário separado apenas para estes. Por isso, é interessante incluirmos a opção de adicionar diretamente esses campos em um subformulário dinâmico.</p>



<p class="has-black-color has-text-color has-background" style="background-color:#f3f3f3">Obs. Se quiser ir direto para o código final, procure o link do JsFiddle no final do post.</p>



<div class="dependentes">
  <button id="btnAdicionarDependentes">
  <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4dd.png" alt="📝" class="wp-smiley" style="height: 1em; max-height: 1em;" />Adicionar Dependentes
  </button>
  <div class="container" id="dependentesContainer">
  </div>
  <button class="green" id="btnCapturarDados">
  <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Capturar Dados
  </button>
</div>
<pre id="containerDados">  
</pre>



<h2 class="wp-block-heading">HTML</h2>



<p>Para iniciarmos, basta criar um container no HTML onde você quer que os elementos sejam exibidos, além do botão simples de adição e um botão de captura de dados, para que, desta forma, possamos enviar o JSON resultante para o back-end.</p>



<p>A organização dos containers é sempre muito importante quando trabalhamos com Javascript e nos dedicamos ao uso correto da web semântica.</p>



<div class="my-syntax-highlighter"><pre><textarea id="mshighlighter" class="mshighlighter" language="html" name="mshighlighter" >
<div class="dependentes">
  <button id="btnAdicionarDependentes">
  &#x1f4dd;Adicionar Dependentes
  </button>
  <div class="container" id="dependentesContainer">
  </div>
  <button class="green" id="btnCapturarDados">
  &#x2705; Capturar Dados
  </button>
</div>
<pre id="containerDados"></pre></textarea></pre></div>



<h2 class="wp-block-heading">Javascript</h2>



<p>Como de praxe, usaremos o Javascript puro para realizar essa tarefa, dessa forma você poderá usar em qualquer lugar o que aprender aqui.</p>



<p>Para poder capturar e devolver os dados, usaremos um objeto JSON, dessa forma fica fácil remontar, tanto no <em>back-end</em>, quando no <em>front-end</em>, os dados nas formatações e/ou elementos que precisamos.</p>



<p>Vamos criar, como exemplo, o JSON abaixo, e vamos declará-lo em uma variável global chamada dependentes, seguindo a ideia de um cadastro de lista de dependentes, então temos:</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >
var dependentes = [{
  identificador: 13,
  nome: "Joana da Silva",
  idade: 12,
}];</textarea></pre>
</div>



<p>Agora vamos nos focar nas funções. A primeira coisa que vamos fazer é criar um método que pegue os dados do JSON e o converta para elementos HTML renderizados na tela. Dessa forma, usaremos um laço para ler o JSON e aplicamos seus dados em uma <em>template string</em> e o adicionamos no container específico:</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >
function carregarDependentes() {
  let dependentes_container = document.querySelector("#dependentesContainer");
  dependentes_container.innerHTML = "";
  dependentes.forEach((el) =&gt; {
    let identificador = el.identificador;
    let nome = el.nome;
    let idade = el.idade;
    let dependente_container = `<div class="dependente" data-id="${identificador}">
    								<input class="nome" placeholder="Digite o nome" type="text" value="${nome}">
                                    <input class="idade" placeholder="Digite a idade" type="number" value="${idade}">
                                    <div class="action">
                                        <a href="#" class="salvar">salvar &#x1f4be;</a>
                                        <a href="#" class="remover">&#x274c;</a>
									</div>
                                </div>`;
    dependentes_container.innerHTML += dependente_container;
  });
}</textarea></pre>
</div>



<p>Agora vem o segredo que facilita o processo e o deixa mais organizado. Ao invés de remover e adicionar os elementos na tela, iremos nos focar em remover e adicionar do JSON e, em seguida, regenerar os elementos a partir desse objeto. Ficando, assim, com um código mais limpo. Outro motivo pelo qual usamos a regeneração dos elementos é para evitar criarmos IDs únicos temporários. Ao regenerar, podemos usar os índices do próprio <em>array </em>como identificador.</p>



<p>Para adicionar um novo item, basta incluirmos um dado vazio no JSON, porém, seguindo nosso modelo, e mandamos gerar novamente os elementos:</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >function adicionarDependentes() {
  dependentes.push({ identificador: "", nome: "", idade: "" });
  carregarDependentes();
}</textarea></pre>
</div>



<p>Para remover, similar a criação de um novo, vamos usar um laço, porém para adicionar o evento aos botões de excluir. Usaremos então o método <em>splice </em>para remover o <em>array</em>. Depois, obviamente, vamos regenerar os elementos a partir da função carregarDependentes():</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >function removerDependentes() {
  document
    .querySelectorAll("#dependentesContainer .remover")
    .forEach((el, i) =&gt; {
      el.addEventListener("click", () =&gt; {
        dependentes.splice(i, 1); // O splice vai remover um item do array no JSON
        carregarDependentes(); // E chamamos o método para regenerar os elementos
      });
    });
}</textarea></pre>
</div>



<p>Uma vez que adicionamos uma nova linha em branco precisamos salvar seu preenchimento e aí iremos usar a mesma lógica de remoção, mas usaremos o <em>splice </em>para substituir e não para remover um dado do JSON. Porém, adicionaremos uma pequena validação para evitar entrar dados incompletos:</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >function salvarDependentes() {
  document
    .querySelectorAll("#dependentesContainer .salvar")
    .forEach((el, i) =&gt; {
      el.addEventListener("click", () =&gt; {
        let identificador = el.parentElement.parentElement.getAttribute(
          "data-id"
        );
        let nome = el.parentElement.parentElement.querySelector(".nome").value;
        let idade = el.parentElement.parentElement.querySelector(".idade")
          .value;

        if (!nome.length || !idade.length) { // Verifica se nome e idade foram preenchidos
          alert("Nome e idade precisam ser preenchidos para salvar.");
          return false;
        }
        dependentes.splice(i, 1, {
          identificador: identificador,
          nome: nome,
          idade: idade,
        }); // Substitui o dado no JSON
        carregarDependentes(); //  E chamamos o método para regenerar os elementos
      });
    });
}</textarea></pre>
</div>



<p>Um outro método que precisamos adicionar é uma forma de <strong>bloquear </strong>para que um usuário consiga clicar em outros elementos ao redor, sem antes finalizar a edição do item. Para isso, iremos fazer um laço que adiciona uma classe de CSS, que vamos chamar de <em>disabled</em>, em todos os elementos, exceto o que está sendo editado. Essa classe possui um <strong><em>point-events: 0</em></strong> e um <strong><em>opacity: 0.5</em></strong>. Para demonstrar que está desativado, você pode ainda adicionar outros efeitos, como filtros de baixo contraste ou escala de cinza.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >function travarOutros(element) {
  if (element == false) { // Passar false como parâmetro para que todos os elementos fiquem habilitados novamente, ao invés de apenas o elemento que queremos liberar
    document
      .querySelectorAll(".dependentes button, .dependentes .container &gt; div")
      .forEach((el) =&gt; {
        el.classList.remove("disabled");
      });
    document.querySelector("#containerDados").innerHTML = "";
    return false;
  }
  document
    .querySelectorAll(".dependentes button, .dependentes .container &gt; div")
    .forEach((el) =&gt; {
      if (el != element) {  // Verifica se o elemento no laço é o que está sendo editado
        el.classList.add("disabled");
      }
    });
}</textarea></pre>
</div>



<p>Agora, antes de continuarmos, vamos revisitar as funções acima para chamar, quando necessário, uma função dentro da outra (leia os comentários no código para entender), ficando assim:</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >
function carregarDependentes() {
  let dependentes_container = document.querySelector("#dependentesContainer");
  dependentes_container.innerHTML = "";
  dependentes.forEach((el) =&gt; {
    let identificador = el.identificador;
    let nome = el.nome;
    let idade = el.idade;
    let dependente_container = `<div class="dependente" data-id="${identificador}">
    															<input class="nome" placeholder="Digite o nome" type="text" value="${nome}">
                                  <input class="idade" placeholder="Digite a idade" type="number" value="${idade}">
                                  <div class="action">
                                  	<a href="#" class="salvar">salvar &#x1f4be;</a>
                                    <a href="#" class="remover">&#x274c;</a>
																	</div>
															  </div>`;
    dependentes_container.innerHTML += dependente_container;
  });
  salvarDependentes(); // Adicionamos o método aqui para que o laço seja aplicado nos novos items adicionados
  removerDependentes(); // Adicionamos o método aqui para que o laço seja aplicado nos novos items adicionados
  travarOutros(false); // Adicionamos para destravar tudo
}

function removerDependentes() {
  document
    .querySelectorAll("#dependentesContainer .remover")
    .forEach((el, i) =&gt; {
      el.addEventListener("click", () =&gt; {
        dependentes.splice(i, 1);
        carregarDependentes(); // Regenerar os elementos HTML após remover do JSON
      });
    });
}

function adicionarDependentes() {
  dependentes.push({ identificador: "", nome: "", idade: "" });
  carregarDependentes(); // Regenerar os elementos HTML após remover do JSON
  travarOutros(
    document.querySelector("#dependentesContainer &gt; div:last-child")
  ); // Desabilitar todos os outros elementos, exceto o que acabou de ser adicionado
}

function salvarDependentes() {
  document
    .querySelectorAll("#dependentesContainer .salvar")
    .forEach((el, i) =&gt; {
      el.addEventListener("click", () =&gt; {
        let identificador = el.parentElement.parentElement.getAttribute(
          "data-id"
        );
        let nome = el.parentElement.parentElement.querySelector(".nome").value;
        let idade = el.parentElement.parentElement.querySelector(".idade")
          .value;

        if (!nome.length || !idade.length) {
          alert("Nome e idade precisam ser preenchidos para salvar.");
          return false;
        }
        dependentes.splice(i, 1, {
          identificador: identificador,
          nome: nome,
          idade: idade,
        });
        carregarDependentes(); // Regenerar os elementos HTML após remover do JSON
        travarOutros(false); // Liberar todos os elementos novamente
      });
    });
}

function travarOutros(element) {
  if (element == false) {
    document
      .querySelectorAll(".dependentes button, .dependentes .container &gt; div")
      .forEach((el) =&gt; {
        el.classList.remove("disabled");
      });
    document.querySelector("#containerDados").innerHTML = "";
    return false;
  }
  document
    .querySelectorAll(".dependentes button, .dependentes .container &gt; div")
    .forEach((el) =&gt; {
      if (el != element) {
        el.classList.add("disabled");
      }
    });
}</textarea></pre>
</div>



<p>Agora, tudo o que precisamos fazer é incluir os comandos de inicialização, onde aplicamos o método de adição ao evento de clique do botão e carregamos os dados iniciais do JSON:</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >
//init
document.querySelector("#btnAdicionarDependentes").addEventListener("click", adicionarDependentes);
carregarDependentes();</textarea></pre>
</div>



<p>Por fim, vamos criar uma função para o botão de capturar dados apenas para extrair e mostrar os dados em JSON. Você pode, eventualmente, usar esses dados e enviar via POST, por AJAX ou via campo oculto, e pegar no back-end para guardar ou processar os dados (como com um json_decoder, do PHP):</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >
//capturarDados
document.querySelector("#btnCapturarDados").addEventListener("click", ()=&gt;{
	document.querySelector("#containerDados").innerHTML = JSON.stringify(dependentes, undefined, 4);
});</textarea></pre>
</div>



<h2 class="wp-block-heading">CSS</h2>



<p>O único CSS que precisaremos usar é para aplicar a classe <em>disabled</em>. Se por acaso você está usando algum <em>framework </em>CSS, recomendo que você use o relativo a esta classe deste. Consulte a documentação, onde geralmente está relacionado aos <em>helpers</em>:</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="css" name="mshighlighter" >
.disabled{
  pointer-events: none;
  opacity: .5;
}</textarea></pre>
</div>



<p>Se você quer usar o CSS mais elaborado que usei aqui, veja abaixo o link do JsFiddle.</p>



<h2 class="wp-block-heading">Finalizando</h2>



<p>Criar formulários dinâmicos auxilia a usabilidade à medida que permite que o usuário adicione dados de forma mais rápida e com respostas visuais imediatas. O uso aqui do Javascript puro visa a facilidade para que você possa implementar em quaisquer projetos, incluindo os com Typescript. Trabalhe um pouco no código para adequá-lo à sua necessidade. E, como sempre, você poderá puxar o código e testar direto do JsFiddle.</p>



<script async src="//jsfiddle.net/velhobit/mwh8f2o1/embed/"></script>



<p>Aproveite e entre para nosso grupo de discussão no <a href="https://t.me/designprogramacao" target="_blank" rel="noreferrer noopener">Telegram</a>.</p>


]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Fim do Flash &#8211; O que fazer com minha aplicação Flash?</title>
		<link>https://velhobit.com.br/programacao/fim-do-flash-o-que-fazer-com-minha-aplicacao-flash.html</link>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Mon, 18 Jan 2021 19:38:15 +0000</pubDate>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Programação]]></category>
		<guid isPermaLink="false">https://velhobit.com.br/?p=2090</guid>

					<description><![CDATA[Infelizmente o Flash acabou. Mas O que fazer com minha aplicação? Como vou atender meu cliente? Como transformar em Javascript?]]></description>
										<content:encoded><![CDATA[
<p>Vou entrar neste assunto apenas uma vez porque eu vi muitos coleguinhas stressados com isso. Contantemente eu tenho visto perguntas como: &#8220;Qual navegador ainda vai rodar Flash?&#8221;, &#8220;Como faço com a minha aplicação Flex?&#8221;, &#8220;Tem como converter Flex ou Flash para Javascript&#8221;?</p>



<h2 class="wp-block-heading"><strong>O que fazer com meu sistema?</strong></h2>



<p>Como você, caro leitor, deve saber, o Flash foi descontinuado de forma pesada e forte em 2021. E não adianta xingar, ficar irritado, ou gritar com a Adobe. O fato é que o ambiente ficou insustentável para a plataforma e correções foram abandonadas já a alguns anos e o suporte oficial também. Como o Flex foi uma plataforma extremamente forte em meados dos anos 2000, muitas aplicações, algumas nem tão antigas assim, e extremamente robustas, foram construídas em cima dele. Isso fez com que, mesmo diante de tanto aviso, muitas desenvolvedoras e desenvolvedores acabaram por não ter condições de desenvolver novas soluções completas que compensassem o fim da tecnologia. Por isso, para ajudar, vou sugerir duas soluções, uma de médio e outra de curto prazo, que pode auxiliar a você resolver seus problemas e continuar mantendo um suporte até ter condições de desenvolver uma solução definitiva.</p>



<h3 class="wp-block-heading"><strong>Solução 1 &#8211; Médio Prazo</strong></h3>



<p>Em 2011, a Adobe doou o Flex para o Apache, então, desde 2014-2016, eles trabalharam em uma forma de portar o Flex para JS, através do FlexJS. Porém, o projeto do Flex não morreu, ele foi convertido para o Apache Royale. Essa pode ser uma solução a médio prazo para a maioria de vocês que estão tendo essa dificuldade. Pode ser uma solução em curto prazo também, se seu projeto foi bem desenvolvido. Ele usa MXML e AS3 e transpila para Javascript e HTML5 ao invés de Flash.</p>



<p>A página do Apache Royale, junto com seus links, pode ser encontrada aqui:</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="561" height="165" src="https://velhobit.com.br/wp-content/uploads/2021/01/apache-royale.png" alt="" class="wp-image-2091" srcset="https://velhobit.com.br/wp-content/uploads/2021/01/apache-royale.png 561w, https://velhobit.com.br/wp-content/uploads/2021/01/apache-royale-400x118.png 400w" sizes="(max-width: 561px) 100vw, 561px" /></figure>



<h3 class="wp-block-heading"><strong>Solução 2 &#8211; CurtoPrazo</strong></h3>



<p>O Adobe AIR permite executar Flash em plataforma desktop. Ele teve seus esforços transferidos para o HARMAN, em 2019, uma empresa da SAMSUNG. Você pode simplesmente compilar sua aplicação Flex baixando o SDK do AIR através do link abaixo:</p>



<figure class="wp-block-image size-large"><a href="https://airsdk.harman.com/download"><img decoding="async" width="561" height="165" src="https://velhobit.com.br/wp-content/uploads/2021/01/harman-adobe-air.png" alt="" class="wp-image-2092" srcset="https://velhobit.com.br/wp-content/uploads/2021/01/harman-adobe-air.png 561w, https://velhobit.com.br/wp-content/uploads/2021/01/harman-adobe-air-400x118.png 400w" sizes="(max-width: 561px) 100vw, 561px" /></a></figure>



<p>Basta aceitar os termos e baixar. A plataforma continuará sendo mantida pela empresa. Porém, é necessário ficar atento a licença. Em geral, para a maioria dos usuários, a licença gratuita resolverá e sua dependência é por valor de receita.</p>



<h2 class="wp-block-heading">Update &#8211; Solução 3 &#8211; Ruffle</h2>



<figure class="wp-block-image size-large"><a href="https://ruffle.rs/" target="_blank" rel="noopener"><img decoding="async" width="518" height="182" src="https://velhobit.com.br/wp-content/uploads/2021/05/image.png" alt="" class="wp-image-2143" srcset="https://velhobit.com.br/wp-content/uploads/2021/05/image.png 518w, https://velhobit.com.br/wp-content/uploads/2021/05/image-400x141.png 400w" sizes="(max-width: 518px) 100vw, 518px" /></a></figure>



<p>Uma solução que tem tudo para ser permanente e até, quem sabe, dar uma sobrevida ao Flash, é o Ruffle. O Ruffle é um emulador de flash player construído em Rust, que pode ser usado para animações e aplicações. O mais legal é que ele pode ser usado não apenas em seu servidor, mas como extensão do navegador ou para quem possui aplicações desktop e não queiram usar o Adobe AIR da HARMAN.</p>



<p><strong><em>OBS: Eu não tenho NADA a ver com a Adobe, nem a Harman, mas trabalhei por muitos anos com a plataforma Flex e compreendo sua enorme importância e contribuição para o que temos hoje em termos de front-end e UX. Estou postando isso apenas para ajudar.</em></strong></p>



<p><strong>Caso eu saiba de mais alguma solução, eu vou atualizar este poste. Fica de olho no Facebook / Instagram ou no grupo, que eu sempre atualizo as coisas por lá.</strong></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Como criar um uploader drag &#038; drop, AJAX com porcentagem e Javascript puro?</title>
		<link>https://velhobit.com.br/programacao/como-criar-um-uploader-drag-drop-ajax-com-porcentagem-e-javascript-puro.html</link>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Fri, 01 Feb 2019 05:19:03 +0000</pubDate>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[componentes]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[drag]]></category>
		<category><![CDATA[drop]]></category>
		<category><![CDATA[efeito]]></category>
		<category><![CDATA[front-end]]></category>
		<category><![CDATA[frontend]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[upload]]></category>
		<category><![CDATA[uploader]]></category>
		<guid isPermaLink="false">https://velhobit.com.br/?p=1806</guid>

					<description><![CDATA[Um breve tutorial para mostrar como fazer um uploader HTML5 de múltiplos, com porcentagem, drag 'n drop e, o melhor, com Javascript puro!]]></description>
										<content:encoded><![CDATA[
<p>Eu sei, o título é grande, mas trata-se de uma tecnologia muito útil quanto a usabilidade. A ideia é criar, da forma mais simples possível um <em>uploader</em> que mostre a porcentagem do que está sendo enviado, com múltiplos arquivos. Porém, não apenas isso, mas da forma mais pura possível, sem a necessidade de <em>frameworks</em>, bibliotecas de terceiros ou pre-processadores.  <strong>Em nosso tutorial, usaremos PHP no back-end, mas você pode usar a linguagem que melhor lhe adequar</strong>. Abaixo você pode testar um exemplo:</p>



<div class="area-upload">
			<label for="upload-file" class="label-upload">
				<i class="fas fa-cloud-upload-alt"></i>
				<div class="texto">Clique ou arraste o arquivo</div>
			</label>
			<input type="file" accept="image/jpg,image/png" id="upload-file" multiple="">
			
			<div class="lista-uploads">
			</div>
		</div>



<p style="background-color:#fff4d4" class="has-text-color has-background has-vivid-red-color">DISCLAIMER: Para preservar você, o blog e a mim, o upload.php do exemplo não está fazendo upload de verdade, então você não vai ter acesso ao arquivo no final, porém, no link do github está o código funcional.</p>



<!-- Place this tag where you want the button to render. -->
<center><a class="github-button" href="https://github.com/velhobit/upload-html/archive/master.zip" data-size="large" aria-label="Download velhobit/upload-html on GitHub">Download</a></center>



<h2 class="wp-block-heading">HTML</h2>



<p>Antes de prosseguir, vou alertar que estou usando o <em><a rel="noreferrer noopener" aria-label="font-awesome  (abre em uma nova aba)" href="https://velhobit.com.br/design/como-criar-sua-propria-fonte-e-a-usar-como-icone.html" target="_blank">font-awesome</a></em><a rel="noreferrer noopener" aria-label="font-awesome  (abre em uma nova aba)" href="https://velhobit.com.br/design/como-criar-sua-propria-fonte-e-a-usar-como-icone.html" target="_blank"> </a>no exemplo, apenas para não ter que fazer nenhum <em>upload</em> de imagens por hora, mas ele não é obrigado para o que vamos fazer.</p>



<p>Iniciaremos com um HTML bem simples. Vamos definir apenas a área de <em>upload</em>, da lista e uma área onde ficará o <em>input</em>. Esse input deve ser do tipo file e deve estar com o atributo <em>mutiple</em> definido. Nada muito especial por enquanto, pois nosso trunfo está mais no CSS e Javascript.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="html" name="mshighlighter" ><div class="area-upload">
			<label for="upload-file" class="label-upload">
				<i class="fas fa-cloud-upload-alt"></i>
				<div class="texto">Clique ou arraste o arquivo</div>
			</label>
			<input type="file" accept="image/jpg,image/png" id="upload-file" multiple/>
			
			<div class="lista-uploads">
			</div>
		</div></textarea></pre>
</div>



<h2 class="wp-block-heading">CSS3</h2>



<p>O CSS que usaremos tem pontos específicos aos quais devemos prestar atenção. Por isso, vamos ver por trechos:</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="css" name="mshighlighter" >.area-upload{
	box-shadow: 0 5px 20px rgba(0,0,0,.2);
	margin: 20px auto;
	padding: 20px;
	box-sizing: border-box;
	
	width: 100%;
	max-width: 700px;
	position: relative;
}

.area-upload label.label-upload{
	border: 2px dashed #0d8acd;
	min-height: 200px;
	text-align: center;
	width: 100%;
	
	display: flex;
	justify-content: center;
	flex-direction: column;
	color: #0d8acd;
	position: relative;
	
	-webkit-transition: .3s all;
	-moz-transition: .3s all;
	-o-transition: .3s all;
	transition: .3s all;
}

.area-upload label.label-upload.highlight{
	background-color: #fffdaa;
}

.area-upload label.label-upload *{
	pointer-events: none;
}</textarea></pre>
</div>



<p>A área de <em>upload</em> é definida pelo CSS a partir de um espaço abrangente. O <em>label</em>, vai ser a referência que vamos usar para atingir toda a área pré-determinada e é o que vai também receber o estilo que indicará onde e quando pode soltar o objeto. Dessa forma, deve estar com um <em>position: absolute</em>, pegando toda a área do <em>upload</em>. Um detalhe importante é que esse label não pode possuir filhos com eventos do mouse, pois isso pode acarretar em funcionamento inadequado ao fazer um <em>hover</em> em uma área não indicada.</p>



<p>A área marcada como <em>hightlight</em> é justamente para demonstrar ao usuário que ele já pode soltar o arquivo.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="css" name="mshighlighter" >
.area-upload input{
	position: absolute;
	left: 0;
	top: 0;
	right: 0;
	bottom: 0;
	width: 100%;
	-webkit-appearance: none;
	opacity: 0;
}</textarea></pre>
</div>



<p>O <em>input</em> vai nos servir de área de <em>drop</em>. Isso já é um padrão tanto para <em>Windows</em>, <em>MacOS</em> e <em>Linux</em> – de receber um (ou mais arquivos) arrastando os dados para o botão. Retirando a aparência padrão, podemos nos aproveitar dessa função e economizar várias linhas de código do <em>Javascript</em>. Não havendo a necessidade de configurarmos eventos de arquivos.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="css" name="mshighlighter" >.area-upload .lista-uploads .barra{
	background-color: #e6e6e6;
	margin: 10px 0;
	width: 100%;
	position: relative;
}

.area-upload .lista-uploads .barra .fill{
	background-color: #a1f7ff;
	position: absolute;
	top: 0;
	left: 0;
	bottom: 0;
	min-width: 0;
	
	-webkit-transition: .2s all;
	-moz-transition: .2s all;
	-o-transition: .2s all;
	transition: .2s all;
}

.area-upload .lista-uploads .barra.complete .fill{
	background-color: #bcffdf;
}

.area-upload .lista-uploads .barra .text{
	z-index: 10;
	text-align: center;
	padding: 3px 5px;
	box-sizing: border-box;
	position: relative;
	width: 100%;
	color: black;
	font-size: 12px;
}
.area-upload .lista-uploads .barra .text a{
	color: black;
	font-weight: bold;
}

.area-upload .lista-uploads .barra.error .fill{	
	background-color: #c02929;
	color: white;
	min-width: 100%;
}

.area-upload .lista-uploads .barra.error .text{
	color: white;
}</textarea></pre>
</div>



<p>Talvez a área que possa confundir um pouco mais, principalmente os mais novatos, seja o CSS referente as barras de <em>loading</em>. As barras são definidas como <em>relative</em> e seu conteúdo como <em>absolute</em>. Dessa forma, podemos herdar a porcentagem do <em>upload</em> e usá-la diretamente no <em>min-width</em> do elemento. Usamos <em>min-width</em>, ao invés de <em>width</em> para utilizar o <em>transition</em>, dando uma leveza no <em>upload</em> ao invés de pequenos estalos.</p>



<h2 class="wp-block-heading">Javascript</h2>



<p>Inicialmente iremos definir os efeitos de <em>drag</em> and <em>drop</em>. Utilizaremos os eventos específicos para adicionar ou retirar o css de <em>hightlight</em>. Aquele que falamos acima ao montar o CSS.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >let drop_ = document.querySelector('.area-upload #upload-file');
drop_.addEventListener('dragenter', function(){
	document.querySelector('.area-upload .label-upload').classList.add('highlight');
});
drop_.addEventListener('dragleave', function(){
	document.querySelector('.area-upload .label-upload').classList.remove('highlight');
});
drop_.addEventListener('drop', function(){
	document.querySelector('.area-upload .label-upload').classList.remove('highlight');
});</textarea></pre>
</div>



<p>Agora precisamos validar os dados antes de colocar em nosso servidor. Compusemos uma validação que verifica o tipo de arquivo e a quantidade máxima de 2MB. Essa validação é totalmente no <em>front-end</em>. É recomendado que você também faça uma validação posterior no <em>back-end</em> para evitar fraudes. Essa função receberá como parâmetro um arquivo, o qual faremos a validação.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >function validarArquivo(file){
	console.log(file);
	// Tipos permitidos
	var mime_types = [ 'image/jpeg', 'image/png' ];
	
	// Validar os tipos
	if(mime_types.indexOf(file.type) == -1) {
		return {"error" : "O arquivo " + file.name + " não permitido"};
	}

	// Apenas 2MB é permitido
	if(file.size > 2*1024*1024) {
		return {"error" : file.name + " ultrapassou limite de 2MB"};
	}

	// Se der tudo certo
	return {"success": "Enviando: " + file.name};
}</textarea></pre>
</div>



<p>Para enviar os arquivos, usaremos uma função AJAX simples. Fazemos um <em>request</em> no método POST. Nesta função, iremos capturar também a porcentagem do <em>upload</em> e atualizaremos a barra a partir desta, através do evento <em>progress</em>. Essa nossa função receberá o índice, para identificar o arquivo que está sendo enviado e a barra que será modificada.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >function enviarArquivo(indice, barra){
	var data = new FormData();
	var request = new XMLHttpRequest();
	
	//Adicionar arquivo
	data.append('file', document.querySelector('#upload-file').files[indice]);
	
	// AJAX request finished
	request.addEventListener('load', function(e) {
		// Resposta
		if(request.response.status == "success"){
			barra.querySelector(".text").innerHTML = "<a href=\"" + request.response.path + "\" target=\"_blank\">" + request.response.name + "</a> <i class=\"fas fa-check\"></i>";
			barra.classList.add("complete");
		}else{
			barra.querySelector(".text").innerHTML = "Erro ao enviar: " + request.response.name;
			barra.classList.add("error");
		}
	});
	
	// Calcular e mostrar o progresso
	request.upload.addEventListener('progress', function(e) {
		var percent_complete = (e.loaded / e.total)*100;
		
		barra.querySelector(".fill").style.minWidth = percent_complete + "%"; 
	});
	
	//Resposta em JSON
	request.responseType = 'json';
	
	// Caminho
	request.open('post', 'upload.php'); 
	request.send(data);
}</textarea></pre>
</div>



<p>Por fim, iremos juntar um pouco de cada coisa que fizemos, adicionando uma função em um evento <em>change</em> do <em>input</em> do upload. Neste momento, também é feito o laço dentre o(s) arquivo(s) selecionado(s) para validar e, se for válido, fazer o <em>upload</em>, utilizando os outros métodos acima mencionados. É neste momento também que serão criadas dinamicamente as barras: uma para cada arquivo.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >
document.querySelector('#upload-file').addEventListener('change', function() {
var files = this.files;
for(var i = 0; i &lt; files.length; i++){
var info = validarArquivo(files[i]);
    //Criar barra
    var barra = document.createElement("div");
    var fill = document.createElement("div");
    var text = document.createElement("div");
    barra.appendChild(fill);
    barra.appendChild(text);

    barra.classList.add("barra");
    fill.classList.add("fill");
    text.classList.add("text");

    if(info.error == undefined){
        text.innerHTML = info.success;
        enviarArquivo(i, barra); //Enviar
    }else{
        text.innerHTML = info.error;
        barra.classList.add("error");
    }

    //Adicionar barra
    document.querySelector('.lista-uploads').appendChild(barra);
};
});</textarea></pre>
</div>



<h2 class="wp-block-heading">PHP</h2>



<p>E pra terminar com chave de ouro, um <em>PHPzinho</em> que receberá esses arquivos e retornará um <em>json</em> com a confirmação de sucesso ou erro. Não aplicamos muitas validações nesse PHP pois nosso foco era neste exemplo está no <em>front-end</em>, mas é suficiente para que você compreenda sua funcionalidade.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="php" name="mshighlighter" ><?php
ini_set('upload_max_filesize', '2M');
header('Content-Type: application/json');
$file = $_FILES['file'];

$ret = [];

if(move_uploaded_file($file['tmp_name'],'uploads/'.$file['name'])){
    $ret["status"] = "success";
    $ret["path"] = 'uploads/'. $file['name'];
    $ret["name"] = $file['name'];
}else{
    $ret["status"] = "error";
    $ret["name"] = $file['name'];
}

echo json_encode($ret, JSON_PRETTY_PRINT);
?></textarea></pre>
</div>



<p>E, como sempre, você pode baixar o código inteiro no <em>Github</em> e usar direto na sua aplicação.</p>



<!-- Place this tag where you want the button to render. -->
<center><a class="github-button" href="https://github.com/velhobit/upload-html/archive/master.zip" data-size="large" aria-label="Download velhobit/upload-html on GitHub">Download</a></center>



<p>Gostou? Se sim, compartilha com seus amiguinhos interessados na área e curte a página no <strong><em><a rel="noreferrer noopener" href="https://www.facebook.com/velhobit/" target="_blank">Facebook</a></em></strong>. O exemplo acima está levemente modificado para que funcione melhor aqui no site. Entre também no grupo de Design e Desenvolvimento. O <em>link</em> está abaixo do post.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Como destacar (hightlight) uma célula de uma Tabela HTML após uma busca</title>
		<link>https://velhobit.com.br/programacao/como-destacar-hightlight-uma-celula-de-uma-tabela-html-apos-uma-busca.html</link>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Sun, 20 Jan 2019 23:38:57 +0000</pubDate>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Programação]]></category>
		<guid isPermaLink="false">https://velhobit.com.br/?p=1771</guid>

					<description><![CDATA[Como fazer uma busca em uma tabela e destacar a célula e coluna do resultado]]></description>
										<content:encoded><![CDATA[
<p>Melhorar a experiência do usuário é sempre importante. E, muitas vezes, resultados de pesquisas tendem a ser muito grandes, principalmente em pesquisas semânticas. Por que então não destacar o elemento buscado para facilitar que o usuário saiba a linha e/ou coluna correta? E, como sempre, Javascript puro.</p>



<h2 class="wp-block-heading">Exemplo</h2>



<form id="search" onsubmit="highlightColumn();return false">
  <input type="text" id="word"/>
  <button>
  Buscar Palavra
  </button>
</form>


<div id="areaTabela" class="area-tabela">
  <table>
    <thead>
      <tr>
        <th>Coluna A</th>
        <th>Coluna B</th>
        <th>Coluna C</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>abacaxi</td>
        <td>manga</td>
        <td>limão</td>
      </tr>
      <tr>
        <td>coelho</td>
        <td>espinafre</td>
        <td>jerimum</td>
      </tr>
      <tr>
        <td>tomate</td>
        <td>cebola</td>
        <td>rapadura</td>
      </tr>
    </tbody>
  </table>
</div>



<h2 class="wp-block-heading">HTML</h2>



<p>Para começar, vamos criar o form e a tabela. Nada complicado e semanticamente correto.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="html" name="mshighlighter" ><form id="search" onsubmit="highlightColumn();return false">
  <input type="text" id="word"/>
  <button>
  Buscar Palavra
  </button>
</form>


<div id="areaTabela" class="area-tabela">
  <table>
    <thead>
      <tr>
        <th>Coluna A</th>
        <th>Coluna B</th>
        <th>Coluna C</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>abacaxi</td>
        <td>manga</td>
        <td>limão</td>
      </tr>
      <tr>
        <td>coelho</td>
        <td>espinafre</td>
        <td>jerimum</td>
      </tr>
      <tr>
        <td>tomate</td>
        <td>cebola</td>
        <td>rapadura</td>
      </tr>
    </tbody>
  </table>
</div></textarea></pre>
</div>



<h2 class="wp-block-heading">CSS</h2>



<p>Precisamos fazer o CSS. De forma geral, não precisamos criar tantas opções. O importante é você criar as classes referentes ao <em>highlight</em> e ao <em>highlight</em> da coluna. Tem um charminho de escala e sombra, mas você faz como achar melhor.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="css" name="mshighlighter" >.area-tabela table{
  margin-top:20px;
  border-spacing: 0;
  border: 1px solid grey;
  width: 100%;
}

.area-tabela table td, .area-tabela table th{
  width:80px;
  padding: 5px 10px;
  font-size: 14px;
  
  transition: all .3s linear;
  -moz-transition: all .3s linear;
  -webkit-transition: all .3s linear;
}

.area-tabela table th{
  background-color: grey;
  color: white;
  font-weight: normal;
}

.area-tabela table tr:nth-child(even) td{
  background-color: #efefef;
}

.area-tabela table tr td.high_col{
  background-color: #e5f7f8;
}
.area-tabela table tr:nth-child(even) td.high_col{
  background-color: #d1eff0;
}

.area-tabela table tr th.high_col{
  background-color: #063b5a;
}

.area-tabela table tr td.high_col.high{
  background-color: #93fffc;
  font-weight: bold;
  transform: scale(1.05);
  box-shadow: 0 3px 5px rgba(0,0,0,.5);
}</textarea></pre>
</div>



<h2 class="wp-block-heading">Javascript</h2>



<p>Agora vem a parte que pode complicar um pouco. A primeira coisa que precisamos fazer é certificar-se, em um laço, que limparemos as classes <em>high_col</em> e <em>high</em> dos outros elementos. Em seguida, iremos usar a função <em>evaluate</em> para verificar se o texto digitado está contido em uma das células. Para capturar os <em>td&#8217;s</em> da coluna ativa, iremos verificar o índice da célula encontrada e usaremos isso para colocar a classe nas outras células e cabeçalho dessa coluna.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >function highlightColumn(){
	//Clear
  document.querySelectorAll("#areaTabela table tr td").forEach((item)=>{
	item.classList.remove("high");
  item.classList.remove("high_col");
});
  document.querySelectorAll("#areaTabela table tr th").forEach((item)=>{
	item.classList.remove("high_col");
});
  
	var word = document.querySelector("#word").value;
 	
  if(word == ""){
  	return false;
  }
  
  //pegar o elemento
  var el = document.evaluate("//td[contains(.,'" + word + "')]", document.querySelector("#areaTabela"), null, XPathResult.ANY_TYPE, null ).iterateNext();
 
  //Se quiser a palavra completa e não trecho dela, troque a linha acima por:
  //var el = document.querySelector("td[text()='"+word+"']");
  
  //Check if el exists
  if(el == undefined){
    return false;
  }
  
  //Highlight column
  var index = (Array.prototype.slice.call(el.parentNode.children).indexOf(el));
  
  document.querySelectorAll("#areaTabela table tr td:nth-child("+(index+1)+"), #areaTabela table tr th:nth-child("+(index+1)+")").forEach((item)=>{
    item.classList.add("high_col");
  });
  
  //Highlight Element
  el.classList.add("high");
  
  return false;
}</textarea></pre>
</div>



<p class="has-text-color has-vivid-red-color">Obs. Se você quiser buscar pelo valor específico, substitua o evaluate por <strong><em>document.querySelector(&#8220;td[text()='&#8221;+word+&#8221;&#8216;]&#8221;)</em></strong>. Dessa forma não será selecionado  nenhuma célula a menos que o valor seja exato.</p>



<p>Simples não é?</p>



<p>Como sempre, o exemplo e código completo está disponível abaixo, desta vez no jsFiddle. Basta copiar o código se quiser usar diretamente em seu projeto.</p>



<script async src="//jsfiddle.net/velhobit/beu4xt69/2/embed/result,js,html,css/dark/"></script>



<p>Se gostou, compartilhe e <a href="https://facebook.com/velhobit/" target="_blank" rel="noreferrer noopener" aria-label="curta a página no Facebook. (abre em uma nova aba)">curta a página no Facebook.</a> Entre também no grupo através do link abaixo.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Como tirar uma foto usando a Webcam (Javascript + HTML)?</title>
		<link>https://velhobit.com.br/programacao/como-tirar-uma-foto-usando-a-webcam-javascript-html.html</link>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Sat, 19 Jan 2019 20:07:22 +0000</pubDate>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[biometria]]></category>
		<category><![CDATA[camera]]></category>
		<category><![CDATA[foto]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[identificação]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[registro]]></category>
		<category><![CDATA[rosto]]></category>
		<category><![CDATA[screenshot]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[webcam]]></category>
		<guid isPermaLink="false">https://velhobit.com.br/?p=1748</guid>

					<description><![CDATA[Com o HTML5 podemos utilizar recursos de hardware em nossas páginas. Este tutorial mostra como usar Javascript e PHP para salvar screenshots da webcam.]]></description>
										<content:encoded><![CDATA[
<p class="has-very-light-gray-background-color has-background"><strong><em>Disclaimer:</em></strong> Provavelmente a funcionalidade de webcam não está acessível via navegador interno de aplicativo (como o navegador interno do app do Facebook ou outro app mobile). Experimente direto em um navegador (mobile ou desktop).</p>



<p>O HTML5 nos trouxe diversas opções interessantes para desenvolvimento de RIAs (<em>Rich Internet Applications</em>). Em diversos sistemas online, precisamos de uma foto da pessoa que está sendo cadastrada. Para sistemas de hotéis, saúde, academias, dentre outros, que precisam de maior identificação, podemos usar a <em>webcam</em> para fazer a foto na hora que poderá ser usada em posterior conferência. Recurso esse que também está disponível em dispositivos móveis.</p>



<p>A ideia é transformar a imagem corrente da <em>webcam</em> em uma imagem <em>base64</em>. Após isso, converter essa codificação em uma imagem JPG e devolver o caminho – quase como se fosse um upload. Dessa forma você poderá salvar apenas o caminho da imagem no seu banco de dados, sem ficar um campo muito extenso ou que possa falhar em dispositivos móveis. Neste exemplo, será usado Javascript puro, a fim de universalizar para quem quiser utilizar em sua aplicação web.</p>



<h2 class="wp-block-heading">Exemplo:</h2>



<button onclick="loadCamera()" class="cute-button"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4f8.png" alt="📸" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Clique aqui para visualizar a Webcam</button>
<div class="area-do-video">

<video autoplay="true" id="webCamera"></video>

<textarea type="text" id="base_img" name="base_img"></textarea>
<button type="button" onclick="takeSnapShot()">Tirar foto e salvar</button>
<img id="imagemConvertida">
<p id="caminhoImagem" class="caminho-imagem"><a href="" target="_blank" rel="noopener"></a></p>
</div>



<h2 class="wp-block-heading">HTML5</h2>



<p>Vamos começar criando nosso exemplo com os elementos HTML. Tudo o que realmente precisamos é de uma tag <em>button</em> e uma tag <em>video</em>, mas para poder visualizar o exemplo, vamos colocar o retorno em um <em>img</em>, link da imagem gerada e um <em>textarea</em> para vermos o <em>base64</em>.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="html" name="mshighlighter" ><div class="area">
			<video autoplay="true" id="webCamera">
			</video>
	
			<input type="text" id="base_img" name="base_img">
			<button type="button" onclick="takeSnapShot()">Tirar foto e salvar</button>
	
			<img id="imagemConvertida">
			<p id="caminhoImagem" class="caminho-imagem"><a href="" target="_blank" rel="noopener"></a></p>
			<script src="script.js"></script>
</div></textarea></pre>
</div>



<p>Não precisamos necessariamente de um CSS para poder funcionar, mas, apenas para exemplo, vamos colocar um <em>CSSzinho</em>&#8230;</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="css" name="mshighlighter" >body{
	font-family: sans-serif;
	margin: 0;
}

.area{
	margin: 10px auto;
	box-shadow: 0 10px 100px #ccc;
	padding: 20px;
	box-sizing: border-box;
	max-width: 500px;
}

.area video{
	width: 100%;
	height: auto;
	background-color: whitesmoke;
}

.area textarea{
	width: 100%;
	margin-top: 10px;
	height: 80px;
	box-sizing: border-box;
}

.area button{
	-webkit-appearance: none;
	width: 100%;
	box-sizing: border-box;
	padding: 10px;
	text-align: center;
	background-color: #068c84;
	color: white;
	text-transform: uppercase;
	border: 1px solid white;
	box-shadow: 0 1px 5px #666;
}

.area button:focus{
	outline: none;
	background-color: #0989b0;
}

.area img{
	max-width: 100%;
	height: auto;
}

.area .caminho-imagem{
	padding: 5px 10px;
	border-radius: 3px;
	background-color: #068c84;
	text-align: center;
}

.area .caminho-imagem a{
	color: white;
	text-decoration: none;
}

.area .caminho-imagem a:hover{
	color: yellow;
}</textarea></pre>
</div>



<h2 class="wp-block-heading">Javascript</h2>



<p>Agora vamos para a parte divertida. Basicamente vamos dividir nosso código em 3 partes: Chamar a webcam, tirar o instantâneo, e enviar/receber os dados do PHP. Criaremos o arquivo <strong><em>script.js</em></strong>.</p>



<p>A função <em>LoadCamera</em>, irá transformar a webcam em uma espécie de <em>streamming</em> local. Para isso, é necessário que o navegador tenha suporte a isso, logo, precisamos de um navegador moderno com total compatibilidade a HTML5. Basicamente, todos os navegadores modernos, então não pense em compatibilidade com <em>Internet Explorer</em>.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >function loadCamera(){
	//Captura elemento de vídeo
	var video = document.querySelector("#webCamera");
		//As opções abaixo são necessárias para o funcionamento correto no iOS
		video.setAttribute('autoplay', '');
	    video.setAttribute('muted', '');
	    video.setAttribute('playsinline', '');
	    //--
	
	//Verifica se o navegador pode capturar mídia
	if (navigator.mediaDevices.getUserMedia) {
		navigator.mediaDevices.getUserMedia({audio: false, video: {facingMode: 'user'}})
		.then( function(stream) {
			//Definir o elemento vídeo a carregar o capturado pela webcam
			video.srcObject = stream;
		})
		.catch(function(error) {
			alert("Oooopps... Falhou :'(");
		});
	}
}</textarea></pre>
</div>



<p>Você deve ter notado que a função acima tem um comentário com alguns parâmetros adicionais. Esses parâmetros são necessários para o funcionamento no iOS.</p>



<p>Já a função <em>takeSnapShot</em> irá justamente tirar o instantâneo. Essa função irá criar um elemento <em>canvas</em> e desenhar em seu conteúdo uma imagem matricial, baseada no vídeo (um ctrl+c / ctrl+v automático, digamos assim). A partir daí podemos obter o <em>base64</em> desse canvas e utilizá-lo para enviar posteriormente.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >function takeSnapShot(){
	//Captura elemento de vídeo
	var video = document.querySelector("#webCamera");
	
	//Criando um canvas que vai guardar a imagem temporariamente
	var canvas = document.createElement('canvas');
	canvas.width = video.videoWidth;
	canvas.height = video.videoHeight;
	var ctx = canvas.getContext('2d');
	
	//Desenhando e convertendo as dimensões
	ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
	
	//Criando o JPG
	var dataURI = canvas.toDataURL('image/jpeg'); //O resultado é um BASE64 de uma imagem.
	document.querySelector("#base_img").value = dataURI;
	
	sendSnapShot(dataURI); //Gerar Imagem e Salvar Caminho no Banco
}</textarea></pre>
</div>



<p>Você pode, inclusive, se quiser, já adicionar essa <em>base64</em> em no <em>src</em> de um elemento <em>img</em>.</p>



<p>Agora, precisamos enviar essa <em>base64</em> para o PHP. Usaremos o PHP para salvar a imagem em um arquivo jpg (você pode optar por png também). O PHP irá retornar, posteriormente, um <em>json</em> com o caminho completo da imagem, que iremos carregar no objeto <em>img</em> descrito no HTML supracitado. Faremos isso dinamicamente, por técnica de Ajax, sem formulário, pois o <em>submit</em> de um <em>form</em> poderá ser usado futuramente para a conclusão de um determinado cadastro:</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="javascript" name="mshighlighter" >function sendSnapShot(base64){
var request = new XMLHttpRequest();
request.open('POST', 'save_photos.php', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
<pre><code>    request.onload = function() {
        console.log(request);
        if (request.status &gt;= 200 &amp;&amp; request.status &lt; 400) {
            //Colocar o caminho da imagem no SRC
            var data = JSON.parse(request.responseText);

            //verificar se houve erro
            if(data.error){
                alert(data.error);
                return false;
            }

            //Mostrar informações
            document.querySelector("#imagemConvertida").setAttribute("src", data.img);
            document.querySelector("#caminhoImagem a").setAttribute("href", data.img);
            document.querySelector("#caminhoImagem a").innerHTML = data.img.split("/")[1];
        } else {
            alert( "Erro ao salvar. Tipo:" + request.status );
        }
    };

    request.onerror = function() {
        alert("Erro ao salvar. Back-End inacessível.");
    }

    request.send("base_img="+base64); // Enviar dados</code></pre>
<p>}</textarea></div>



<h2 class="wp-block-heading">PHP</h2>



<p>No lado do PHP, basicamente, usaremos um $_POST para capturar o dado enviado via <em>Ajax</em> pelo <em>Javascript</em>. Criaremos então o arquivo <strong><em>salvar_photos.php</em></strong>.</p>



<p>Não há muitos segredos, mas é importante se atentar a dois detalhes:</p>



<ol class="wp-block-list"><li>Os dados chegam com o + transformado em espaço, então precisamos converter novamente para + com um <em>replace</em>.</li><li>Precisamos salvar apenas os dados <em>mime</em>, sem os cabeçalhos, logo precisamos dar um explode para coletar apenas os dados. </li></ol>



<p>Fora isso, basicamente colocamos os dados em um arquivo JPG e retornamos a URL em <em>json</em> para ser lido pelo <em>Javascript</em> novamente.</p>


<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="php" name="mshighlighter" ><?php
	if(!isset($_POST['base_img'])){
		die("{\"error\": \" Flopou. Cadê o base_img?\"}");
	}

	$result = [];
	$data = str_replace(" ","+",$_POST['base_img']); //O envio do dado pelo XMLHttpRequest tende a trocar o + por espaço, por isso a necessidade de substituir. 
	$name = md5(time().uniqid()); 
	$path = "snaps/{$name}.jpg";

	//data
	$data = explode(',', $data);
	
	//Save data
	file_put_contents($path, base64_decode(trim($data[1])));
	
	//Print Data
	$result['img'] = $path;
	echo json_encode($result, JSON_PRETTY_PRINT);
?></textarea></pre>
</div>



<p>Uma vez tudo pronto, basta chamar a função <strong><em>loadCamera()</em></strong> no evento que você quer que ele seja disparado.</p>



<p>Como sempre, deixamos o código disponível para quem quiser utilizar. Desta vez, o código está no GitHub.</p>



<!-- Place this tag where you want the button to render. -->
<center style="margin-top:20px;"><a class="github-button" href="https://github.com/velhobit" data-size="large" data-show-count="true" aria-label="Follow @velhobit on GitHub">Follow @velhobit</a></center>



<p class="has-white-color has-luminous-vivid-orange-background-color has-text-color has-background"><strong>ATENÇÃO: O navegador não vai liberar o uso das ferramentas em um ambiente http. Você precisa necessariamente estar com seu site ou sistema em conexão segura (https).</strong></p>



<p>Se gostou, compartilha com seus amiguinhos interessados na área e curte a página no <strong><em><a rel="noreferrer noopener" aria-label="Facebook (abre em uma nova aba)" href="https://www.facebook.com/velhobit/" target="_blank">Facebook</a></em></strong>. O exemplo acima está levemente modificado para que funcione melhor aqui no site. Entre também no grupo de Design e Desenvolvimento. O link está abaixo do post.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Como redirecionar seu site / página por localização</title>
		<link>https://velhobit.com.br/programacao/como-redirecionar-seu-site-pagina-por-localizacao.html</link>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Sat, 25 Aug 2018 22:57:28 +0000</pubDate>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[geolocalização]]></category>
		<category><![CDATA[idioma]]></category>
		<category><![CDATA[localização]]></category>
		<category><![CDATA[muitos idiomas]]></category>
		<category><![CDATA[multidioma]]></category>
		<category><![CDATA[redirecionamento]]></category>
		<category><![CDATA[redirecionar]]></category>
		<category><![CDATA[site multidioma]]></category>
		<guid isPermaLink="false">https://velhobit.com.br/?p=1464</guid>

					<description><![CDATA[Uma forma simples e rápida de fazer o redirecionamento via Javascript ou PHP / cURL do seu site a partir da localização. Perfeito para sites multi-idiomas.]]></description>
										<content:encoded><![CDATA[<p>As vezes você precisa trabalhar com sites ou projetos multi-idiomas. Alguns desses projetos carregam dinamicamente a tradução ou possui páginas específicas em outro idioma. Redirecionar automaticamente para o conteúdo específico da região é um comportamento fundamental para uma boa experiência do usuário.</p>
<h2>Detecção por Geolocalização</h2>
<p>A forma mais simples e rápida de fazer isso, é através de uma API open-source online chamada <del>Nekudo (<a href="https://geoip.nekudo.com/">https://geoip.nekudo.com/</a>)</del>. O Nekudo não está mais disponível e virou IPI. Você precisa fazer um cadastro gratuito em https://ipapi.com/product e pegar sua chave e cadastrar o IP. Na dúvida de saber qual o IP do seu server, abra o seu prompt de comando (windows) ou terminal (Unix/Mac/Linux) e digite ping seusite.com.br.</p>
<p>A forma ideal de fazer isso é a partir da sugestão, ao invés do redirecionamento direto, como é feito no site da Apple e Adobe. Isso porque o usuário pode estar em viagem ou simplesmente preferir usar o conteúdo em outro idioma.</p>
<p>Vamos para a prática.</p>
<h2>Javascript</h2>
<p>Para facilitar, vamos usar um jQuery básico, que está presente em quase todos os sites e sistemas. Basta um &#8220;ajaxizinho&#8221; apenas para chamarmos a API do Geoplugin.</p>
<p>A URL <strong>https://api.ipapi.com/, seguido da chave e IP </strong>já devolve os dados em formato JSON. Como ele vai pegar o IP atual do usuário, não é necessário passar o IP:</p>
<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="js" name="mshighlighter" >
var ip = "check";
var access_key = "minhachavedeacesso";
jQuery.ajax({
url:'https://api.ipapi.com/' + ip + '?access_key=' + access_key
dataType: "json",
success: function(data){
console.log(data);
}
});</textarea></pre>
</div>
<p>O retorno então será:</p>
<div class="my-syntax-highlighter">
<pre id="result_code"></pre>
</div>
<p>Agora basta tratarmos o código para que execute uma ação e depois redirecione. Ficando assim:</p>
<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="js" name="mshighlighter" >

var ip = "check";

var access_key = "minhachavedeacesso";
jQuery.ajax({
url: 'https://api.ipapi.com/' + ip + '?access_key=' + access_key,
dataType: "json",
success: function(data){
if(data.country.code != "BR"){
var redirecionar = confirm("Hi, visitor! We checked you are in " + data.country.name + ". Would you like to visit english version?");
}
if(redirecionar){
window.location = "https://meusite.com/en/";//outra url
}
}
});</textarea></pre>
</div>
<p>Nesse ponto, apenas verificamos se não está no Brasil e ele vai redirecionar a página em questão.</p>
<p>Todavia, ele não vai guardar essa preferência. Logo, toda vez que a pessoa entrar no site, ela vai ter que responder a pergunta novamente. Mas para evitar que isso ocorra, podemos usar o localStorage. Garantindo assim que seja memorizada a opção e evitando que a API seja requerida desnecessariamente. O código final ficaria assim:</p>
<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="js" name="mshighlighter" >

var ip = "check";

var access_key = "minhachavedeacesso";

//Verifica primeiro se já tem o country code salvo
if(localStorage.sel_country_code == undefined){
jQuery.ajax({
url: 'https://api.ipapi.com/' + ip + '?access_key=' + access_key
dataType: "json",
success: function(data){
if(data.country.code != "BR"){
var redirecionar = confirm("Hi, visitor! We checked you are in " + data.country.name + ". Would you like to visit english version?");
}
if(redirecionar){
//Gravar o country_code
localStorage.sel_country_code = data.country.code
window.location = "https://meusite.com/en/";//outra url
}
}
});
}else{
//Caso já esteja definido
window.location = "https://meusite.com/en/";//outra url
//Obs. Use o valor armazenado em localStorage.sel_country_code, caso você tenha mais de um outro idioma
}</textarea></pre>
</div>
<p><center><br />
<button id="botaoTestes">Clique aqui para testar.</button></center></p>
<h2>Como saber se está funcionando?</h2>
<p>Para testar, basta você usar um serviço de VPN. Você pode fazer isso através de algum site, programa ou simplesmente rodando pelo Opera, que já possui uma VPN própria e é ótimo mantê-lo instalado para testes. Recomendamos que você use o Opera, pois, além de ser um bom navegador, ele é mais seguro para evitar usar sites duvidosos ou serviços de terceiros. O Opera Developer é uma boa opção e possui VPN integrado. <em><strong>Clique na imagem para ser direcionado a página de download oficial</strong></em>.</p>
<p><a href="https://www.opera.com/pt-br/computer/beta" target="_blank" rel="noopener"><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-1477" src="https://velhobit.com.br/wp-content/uploads/2018/08/opera-developer.jpg" alt="Baixar Opera Developer" width="925" height="436" srcset="https://velhobit.com.br/wp-content/uploads/2018/08/opera-developer.jpg 925w, https://velhobit.com.br/wp-content/uploads/2018/08/opera-developer-400x189.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/08/opera-developer-768x362.jpg 768w, https://velhobit.com.br/wp-content/uploads/2018/08/opera-developer-600x283.jpg 600w" sizes="auto, (max-width: 925px) 100vw, 925px" /></a></p>
<p>Após instalar o Ópera, para habilitar o VPN, basta ir nas <strong>configurações</strong>, a partir do símbolo do <span style="color: #ff0000;"><em><strong>O</strong></em></span>, no canto superior esquerdo.</p>
<p><img decoding="async" class="aligncenter" style="max-width: 350px;" src="https://velhobit.com.br/wp-content/uploads/2018/08/opera-opcoes.jpg" /></p>
<p>Indo na guia Avançados &gt; Recursos, ele vai retornar a primeira opção como VPN. Simplesmente a habilite.</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-1482 size-full" src="https://velhobit.com.br/wp-content/uploads/2018/08/config-vpn.jpg" alt="" width="1017" height="304" srcset="https://velhobit.com.br/wp-content/uploads/2018/08/config-vpn.jpg 1017w, https://velhobit.com.br/wp-content/uploads/2018/08/config-vpn-400x120.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/08/config-vpn-768x230.jpg 768w, https://velhobit.com.br/wp-content/uploads/2018/08/config-vpn-600x179.jpg 600w" sizes="auto, (max-width: 1017px) 100vw, 1017px" /></p>
<p>Feito isso, a opção de VPN vai ficar visível e você poderá testar o funcionamento em diversos locais.</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-1484" style="max-width: 450px;" src="https://velhobit.com.br/wp-content/uploads/2018/08/vpn.jpg" alt="" width="600" height="663" srcset="https://velhobit.com.br/wp-content/uploads/2018/08/vpn.jpg 600w, https://velhobit.com.br/wp-content/uploads/2018/08/vpn-362x400.jpg 362w, https://velhobit.com.br/wp-content/uploads/2018/08/vpn-543x600.jpg 543w" sizes="auto, (max-width: 600px) 100vw, 600px" /></p>
<h2>Ah, mas eu não quero redirecionar assim, quero que seja pelo servidor</h2>
<p>Muito bem, digamos que você queira que o redirecionamento seja feito direto pelo servidor porque você é mal que nem um pica-pau. Sem problemas.</p>
<p>Para isso, você pode usar o cURL da sua linguagem de preferência e fazer o redirecionamento através dela. Aqui vai um exemplo mais comum, em PHP:</p>
<div class="my-syntax-highlighter">
<pre><textarea id="mshighlighter" class="mshighlighter" language="php" name="mshighlighter" >
&lt;?php

// IP e chave
$ip = $_SERVER['REMOTE_ADDR'];
$access_key = 'SUA CHAVE DE ACESSO';

// Inicializar CURL:
$ch = curl_init('http://api.ipapi.com/'.$ip.'?access_key='.$access_key.'');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// Capturar dados
$json = curl_exec($ch);
curl_close($ch);

// Decode JSON:
$retorno = json_decode($json, true);

if($retorno['country_code'] != "BR"){
header("location: https://seusite.com/idioma");
die();
}
?&gt;</textarea></pre>
</div>
<p><em>Lembrando que isso precisa ser inserido antes mesmo do doctype, pois se não pode retornar o erro de Headers Already Sent.</em></p>
<h2>Concluindo</h2>
<p>É bem simples testar o IP quanto a localização. Há diversos serviços, alguns pagos e outros gratuitos, que fazem esse tipo de redirecionamento. Também há plugins e extensões que você pode instalar em seu servidor, mas certamente a demonstrada aqui vai servir para a grande maioria dos projetos.</p>
<p>Curta e compartilhe <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dicas para Otimizar o Console Javascript do Navegador</title>
		<link>https://velhobit.com.br/programacao/dicas-para-otimizar-o-console-javascript.html</link>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Fri, 16 Feb 2018 03:33:00 +0000</pubDate>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[como colocar cor no console]]></category>
		<category><![CDATA[como colocar imagem no console]]></category>
		<category><![CDATA[como usar]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[console do navegador]]></category>
		<category><![CDATA[console web]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[desenvolvimento web]]></category>
		<category><![CDATA[dicas de web]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[navegador]]></category>
		<category><![CDATA[programar para web]]></category>
		<category><![CDATA[usar o console]]></category>
		<category><![CDATA[uso do console]]></category>
		<category><![CDATA[web aplicação]]></category>
		<category><![CDATA[webapp]]></category>
		<category><![CDATA[webdesign]]></category>
		<guid isPermaLink="false">https://velhobit.com.br/?p=1148</guid>

					<description><![CDATA[O console do navegador é uma ferramenta importante para exibir a desenvolvedores um resultado simples de ser interpretado. Este post possui algumas dicas para você otimizar as funcionalidades dessa ferramenta.]]></description>
										<content:encoded><![CDATA[<p>Designers e desenvolvedores constantemente precisam <em>debugar</em> seus sistemas para encontrar erros ou relatar informações para outros desenvolvedores da equipe. Para otimizar o trabalho do profissional web, o <strong>Console</strong> do navegador de sua preferência permite adicionar diversas opções e comandos.</p>
<p>Se você digitar apenas console, no Console, você poderá ver a gama de Métodos que o Objeto tem disponível.</p>
<p>Neste tutorial, mostraremos alguns métodos e como utilizá-los de forma a permitir uma finalização que ajude o designer e desenvolvedor a obter respostas mais ideais para o problema. Você pode testar os comandos aqui mesmo, basta pressionar CTRL+SHIFT+I, ou simplesmente clicar com o botão direito e inspecionar elemento. Ao clicar na aba console, você poderá digitar os comandos e visualizar os resultados.</p>
<p>O método log é o mais básico e permite que você adicione uma</p>
<pre class="prettyprint">console.log("Oi Mundo");</pre>
<p>Porém o simples log de texto não necessariamente pode ser o ideal. Você pode, se assim precisar, adicionar alguma informação visual para que o log seja lido de forma mais intuitiva. Para isso, basta usar uma string de formato %c e instruções CSS. O exemplo abaixo, colocará o texto branco, negrito e com sombra:<!--?prettify linenums=true?--></p>
<pre class="prettyprint">console.log('%c Oi mundo', 'color:white; font-weight:bold; text-shadow: 0 0 1em black;font-size: 72px');</pre>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-1150" src="https://velhobit.com.br/wp-content/uploads/2018/02/oi-mundo.jpg" alt="" width="676" height="143" srcset="https://velhobit.com.br/wp-content/uploads/2018/02/oi-mundo.jpg 676w, https://velhobit.com.br/wp-content/uploads/2018/02/oi-mundo-400x85.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/02/oi-mundo-600x127.jpg 600w" sizes="auto, (max-width: 676px) 100vw, 676px" /></p>
<p>Com isso é possível até mesmo adicionar imagens, através do background-image:</p>
<pre class="prettyprint">console.log('%c       ', 'font-size: 100px; background: url(http://cdn.nyanit.com/nyan2.gif) no-repeat;');</pre>
<p>Passando para um ponto mais sério, você também pode visualizar no console objetos diferentes de Strings. É possível, por exemplo, visualizar um objeto JSON, o que é algo muito funcional para visualizar o resultado de métodos AJAX.</p>
<pre class="prettyprint">console.log({teste: 'texto de teste', valor: 22})</pre>
<p>No caso de você colocar um JSON ou um array, você poderá estender e visualizar os detalhes desse objeto.</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-1154" src="https://velhobit.com.br/wp-content/uploads/2018/02/consolelogo.jpg" alt="" width="671" height="482" srcset="https://velhobit.com.br/wp-content/uploads/2018/02/consolelogo.jpg 671w, https://velhobit.com.br/wp-content/uploads/2018/02/consolelogo-400x287.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/02/consolelogo-600x431.jpg 600w" sizes="auto, (max-width: 671px) 100vw, 671px" /></p>
<h2>Erros e Alertas</h2>
<p>Além do log, o Console também tem objetos que servem como point-breaks para testes e validações. Os métodos error() e warn() permite que você adicione informações de forma mais relevante e alertiva. Esses dois métodos também permitem usar a  string de formato %c .</p>
<pre class="prettyprint">console.error("Problema Sério");
console.warn("Problema Leve");</pre>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-1156" src="https://velhobit.com.br/wp-content/uploads/2018/02/problemas.jpg" alt="" width="792" height="222" srcset="https://velhobit.com.br/wp-content/uploads/2018/02/problemas.jpg 792w, https://velhobit.com.br/wp-content/uploads/2018/02/problemas-400x112.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/02/problemas-768x215.jpg 768w, https://velhobit.com.br/wp-content/uploads/2018/02/problemas-600x168.jpg 600w" sizes="auto, (max-width: 792px) 100vw, 792px" /></p>
<p>Você deve notar que, ao lado da linha onde é demonstrada o alerta/erro, há uma palavra <em><strong>anonymous</strong></em>, entre parênteses. Essa informação define qual o método relacionado com a origem do erro. Por exemplo, se o erro ou alerta ocorrer dentro de um método, será mostrado o método onde ocorreu o erro.</p>
<pre class="prettyprint">var teste = function(){console.error("Oi")};
teste();</pre>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-1159" src="https://velhobit.com.br/wp-content/uploads/2018/02/teste-info.jpg" alt="" width="810" height="198" srcset="https://velhobit.com.br/wp-content/uploads/2018/02/teste-info.jpg 810w, https://velhobit.com.br/wp-content/uploads/2018/02/teste-info-400x98.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/02/teste-info-768x188.jpg 768w, https://velhobit.com.br/wp-content/uploads/2018/02/teste-info-600x147.jpg 600w" sizes="auto, (max-width: 810px) 100vw, 810px" /></p>
<p>Essa informação é extremamente útil para auxiliar o desenvolvedor a saber qual a origem do problema.</p>
<h2>Identação</h2>
<p>Outra opção muito útil para definir detalhes no log é a identação. Na verdade, é uma organização em grupo e subgrupos das informações. Dessa forma, o desenvolvedor pode apresentar dados mais organizados para o testador.</p>
<pre class="prettyprint">console.group("Frases");
console.group("Saudações");
console.log("Oi!");
console.log("Olá!");
console.groupEnd();
console.group("Despedidas");
console.log("Tchau!");
console.log("Até mais.");
console.groupEnd();</pre>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-1161" src="https://velhobit.com.br/wp-content/uploads/2018/02/grupo-console.jpg" alt="" width="811" height="304" srcset="https://velhobit.com.br/wp-content/uploads/2018/02/grupo-console.jpg 811w, https://velhobit.com.br/wp-content/uploads/2018/02/grupo-console-400x150.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/02/grupo-console-768x288.jpg 768w, https://velhobit.com.br/wp-content/uploads/2018/02/grupo-console-600x225.jpg 600w" sizes="auto, (max-width: 811px) 100vw, 811px" /></p>
<h2>Tabelas</h2>
<p>O método table() permite você mostrar informações de dados em uma tabela. Ele é um método muito útil para ler objetos, JSON e vetores. De forma automática, esse método irá reconhecer os dados e organizá-los nessa tabela. Se por acaso você passar um array, as chaves mostradas serão apenas os índices numéricos.</p>
<pre class="prettyprint">console.table({'Dia': '10:00', 'Noite': '22:00'});</pre>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-1163" src="https://velhobit.com.br/wp-content/uploads/2018/02/tabela-log.jpg" alt="" width="806" height="234" srcset="https://velhobit.com.br/wp-content/uploads/2018/02/tabela-log.jpg 806w, https://velhobit.com.br/wp-content/uploads/2018/02/tabela-log-400x116.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/02/tabela-log-768x223.jpg 768w, https://velhobit.com.br/wp-content/uploads/2018/02/tabela-log-600x174.jpg 600w" sizes="auto, (max-width: 806px) 100vw, 806px" /></p>
<h2>Calcular Tempo</h2>
<p>O cálculo de tempo é fundamental para medir performance.  O método time() permite usar uma etiqueta para poder iniciar e finalizar uma contagem de tempo. Para isso, basta seguir o exemplo abaixo:</p>
<pre class="prettyprint">console.time("calcularTempo");
for(var i; i &lt; 100; i++){

}
console.timeEnd("calcularTempo");</pre>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-1165" src="https://velhobit.com.br/wp-content/uploads/2018/02/calcular-tempo.jpg" alt="" width="789" height="222" srcset="https://velhobit.com.br/wp-content/uploads/2018/02/calcular-tempo.jpg 789w, https://velhobit.com.br/wp-content/uploads/2018/02/calcular-tempo-400x113.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/02/calcular-tempo-768x216.jpg 768w, https://velhobit.com.br/wp-content/uploads/2018/02/calcular-tempo-600x169.jpg 600w" sizes="auto, (max-width: 789px) 100vw, 789px" /></p>
<p>Esse tempo será calculado baseado no tempo que a máquina cliente demora para realizar determinada ação, por isso, esse valor pode variar de computador para computador.</p>
<h2>Strings de Substituição</h2>
<p>Além do %c, usado para CSS, você pode usar outras Strings com objetivos específicos.</p>
<table class="standard-table">
<tbody>
<tr>
<td class="header"><strong>String           </strong></td>
<td class="header"><strong>Descrição</strong></td>
</tr>
<tr>
<td>%o or %O</td>
<td>Exibe o objeto e permite você visualizar o objeto ao clicar nele.</td>
</tr>
<tr>
<td>%d or %i</td>
<td>Exibe um inteiro.</td>
</tr>
<tr>
<td>%s</td>
<td>Apenas uma string.</td>
</tr>
<tr>
<td>%f</td>
<td>Exibe um ponto flutuante</td>
</tr>
</tbody>
</table>
<p>Dependendo do navegador (como o Firefox), você pode ter opções adicionais de máscara quanto aos valores. Para saber os detalhes, você precisa verificar na documentação do navegador, mas são muito similares as Strings usadas no console em C e no Java.</p>
<p>Por exemplo:</p>
<pre class="prettyprint">console.log("O valor da compra de %d %s é de %f, com os dados %o", 3,'carros',38500.30,{'carro':'fusca'});</pre>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-1167" src="https://velhobit.com.br/wp-content/uploads/2018/02/exemplo-log-carro.jpg" alt="" width="780" height="220" srcset="https://velhobit.com.br/wp-content/uploads/2018/02/exemplo-log-carro.jpg 780w, https://velhobit.com.br/wp-content/uploads/2018/02/exemplo-log-carro-400x113.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/02/exemplo-log-carro-768x217.jpg 768w, https://velhobit.com.br/wp-content/uploads/2018/02/exemplo-log-carro-600x169.jpg 600w" sizes="auto, (max-width: 780px) 100vw, 780px" /></p>
<h2>Concluindo</h2>
<p>O uso apropriado do console do navegador pode ajudar os desenvolvedores a fazerem testes e obterem resultados mais fiéis destes. Além disso, pode exibir mensagens importantes para alertar um usuário leigo a não mexer nessas opções (como faz o Facebook). De qualquer forma, o conhecimento das opções do console são fundamentais para qualquer profissional web que trabalha com front-end.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>BitMail &#8211; Projeto de Envio de Mailmarketing em Lote</title>
		<link>https://velhobit.com.br/editorial/bitmail-projeto-de-envio-de-mailmarketing-em-lote.html</link>
					<comments>https://velhobit.com.br/editorial/bitmail-projeto-de-envio-de-mailmarketing-em-lote.html#comments</comments>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Tue, 02 Jan 2018 23:58:50 +0000</pubDate>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Editorial]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Projetos]]></category>
		<category><![CDATA[aplicativo]]></category>
		<category><![CDATA[bulk]]></category>
		<category><![CDATA[codigo aberto]]></category>
		<category><![CDATA[e-mail]]></category>
		<category><![CDATA[envio]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[mailmarketing]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[projeto]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[windows]]></category>
		<guid isPermaLink="false">https://velhobit.com.br/?p=973</guid>

					<description><![CDATA[BitMail é um aplicativo desktop para envio de e-mails em lotes, criado com a tecnologia Electron / NodeJS. Este projeto é de código aberto e ainda está em beta e diversas funcionalidades não funcionam direito e apresentam falhas com o uso em alguns servidores de e-mail.]]></description>
										<content:encoded><![CDATA[<p style="text-align: center;"><!-- Place this tag where you want the button to render. --><br />
<a class="github-button" href="https://github.com/velhobit/BitMail--NodeJS---Electron-/archive/master.zip" data-icon="octicon-cloud-download" data-size="large" aria-label="Download velhobit/BitMail--NodeJS---Electron- on GitHub">Download</a></p>
<p>BitMail é um aplicativo desktop para envio de e-mails em lotes, criado com a tecnologia Electron / NodeJS. Este projeto é de código aberto e ainda está em beta e diversas funcionalidades não funcionam direito e apresentam falhas com o uso em alguns servidores de e-mail.</p>
<p style="text-align: center;"><!-- Place this tag where you want the button to render. --><br />
<a class="github-button" href="https://github.com/velhobit/BitMail--NodeJS---Electron-" data-size="large" data-show-count="true" aria-label="Star velhobit/BitMail--NodeJS---Electron- on GitHub">Star</a></p>
<h2>Sobre o Projeto</h2>
<p>Há duas semanas comecei a estudar NodeJS (em Dez de 2017) e, por consequência de interesse de criação de aplicativos para desktop, estudar um pouco de Electron. Apesar de já ter experiência com Javascript, estava interessado em entender a manipulação de arquivos locais.</p>
<p>Como quando estudo algo prefiro criar um projeto minimamente útil, resolvi criar uma variação de <a href="https://velhobit.com.br/projetos/portillo-mail.html">um projeto que criei anos atrás para um cliente e que também é de código aberto, o PortilloMail (eu sei, não é um nome muito criativo), criado em PHP e compatível com a maioria dos servidores compartilhados</a>.</p>
<p>Como ainda estou novo em NodeJS, ainda preciso resolver alguns problemas, que vou citar abaixo, mas o aplicativo já é utilizável em diversas circunstâncias.</p>
<ul>
<li><a href="https://velhobit.com.br/bitmail-como-preparar-os-arquivos-csv">COMO PREPARAR O ARQUIVO CSV?</a></li>
<li><a href="https://velhobit.com.br/bitmail-como-criar-meu-proprio-template">COMO CRIAR MEU PRÓPRIO TEMPLATE?</a></li>
<li><a href="https://velhobit.com.br/bitmail-faq-perguntas-frequentes">FAQ (PERGUNTAS FREQUENTES)</a></li>
</ul>
<h2>Como Enviar E-mails?</h2>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-974" src="https://velhobit.com.br/wp-content/uploads/2018/01/tela-inicial-bulk-bit-mail.jpg" alt="" width="916" height="543" srcset="https://velhobit.com.br/wp-content/uploads/2018/01/tela-inicial-bulk-bit-mail.jpg 916w, https://velhobit.com.br/wp-content/uploads/2018/01/tela-inicial-bulk-bit-mail-400x237.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/01/tela-inicial-bulk-bit-mail-768x455.jpg 768w, https://velhobit.com.br/wp-content/uploads/2018/01/tela-inicial-bulk-bit-mail-600x356.jpg 600w" sizes="auto, (max-width: 916px) 100vw, 916px" /></p>
<p>O BitMail foi feito para ser extremamente simples. Sua tela inicial possui todas as informações básicas necessárias para enviar um e-mail.</p>
<p>A primeira coluna (da esquerda para a direita) refere-se ao remetente da mensagem. Basta colocar o nome de quem está enviando, a senha e o host.</p>
<p>Por enquanto, estamos listando apenas o host Gmail e Outlook, porém, você pode optar por personalizar para configurar o SMTP da sua própria hospedagem. <strong>Com o tempo iremos atualizar com outros padrões de hospedagens mais famosas</strong>.</p>
<p>A coluna do meio é referente a mensagem. Nela você coloca as informações básicas como Assunto e Mensagem (pode usar emojis) e deverá selecionar um arquivo CSV previamente configurado, que consta os e-mails e senhas dos destinatários.</p>
<p>A última coluna é a coluna de envio. Nela você deverá digitar um e-mail para teste. <strong>Apenas após você confirmar o teste, o botão ENVIAR vai ficar funcional.</strong></p>
<p>A barra inferior é a barra de templates. O aplicativo permite que você crie arquivos HTML e os use como templates. Como a ideia é servir de mailmarketing, você mesmo pode criar o seu template. <strong>Leia aqui sobre como incluir seu próprio template</strong>. Se o quadrado preto estiver selecionado, isso quer dizer que você não irá utilizar nenhum template e irá enviar a mensagem do jeito que estiver dentro da caixa mensagem (inclusive com tags HTML).</p>
<p>Para poder garantir que seu e-mail não fique preso em uma caixa de SPAM ou que você seja interrompido pelo limite da sua hospedagem ou servidor de e-mails, o aplicativo é limitado a 200 e-mails por hora. Você pode editar isso, tal como preencher as configurações da sua hospedagem, no PAINEL AVANÇADO.</p>
<p><img loading="lazy" decoding="async" class="aligncenter size-full wp-image-975" src="https://velhobit.com.br/wp-content/uploads/2018/01/emails-avancado.jpg" alt="" width="916" height="543" srcset="https://velhobit.com.br/wp-content/uploads/2018/01/emails-avancado.jpg 916w, https://velhobit.com.br/wp-content/uploads/2018/01/emails-avancado-400x237.jpg 400w, https://velhobit.com.br/wp-content/uploads/2018/01/emails-avancado-768x455.jpg 768w, https://velhobit.com.br/wp-content/uploads/2018/01/emails-avancado-600x356.jpg 600w" sizes="auto, (max-width: 916px) 100vw, 916px" /></p>
<p>Antes de usar, é extremamente aconselhável que você leia o FAQ e saiba como preparar o arquivo CSV.</p>
<p>Se você tiver interesse em como criar o seu próprio template, você também pode ler sobre isso aqui.</p>
<h2>Requerimentos</h2>
<p>Após a instalação do NodeJS, você vai precisar de uma série de bibliotecas para poder fazer compilar.</p>
<p>Você pode baixar o NodeJS para Windows diretamente pelo site oficial ou pode usar o seguinte comando para distribuições baseadas em Debian (instalando também seu gerenciador de pacotes):</p>
<pre class="prettyprint">sudo apt-get update
sudo apt-get install nodejs
sudo apt-get install npm</pre>
<p>Após a instalação do NodeJS, acesse o console e instale o Electron:</p>
<pre class="prettyprint">npm install electron --save-dev --save-exact</pre>
<p>Para o envio dos e-mails, o pacote nodemailer se faz necessário. Para instala-lo, acesse o console e use:</p>
<pre class="prettyprint">npm install nodemailer</pre>
<p>Por fim, para diminuir o código de leitura de arquivo, pois precisava que ele fosse síncrono e mais simples, resolvi usar o n-readlines. Provavelmente, em atualizações futuras não irei usar, mas por enquanto:</p>
<pre class="prettyprint">npm install n-readlines</pre>
<p>Para poder compilar, acesse o console e na pasta onde você salvou o projeto, execute:</p>
<pre class="prettyprint">npx electron .</pre>
<p>Pronto. Você agora já pode utilizar.</p>
<p><strong>Obs. A única biblioteca front-end utilizada, para facilitar o desenvolvimento, foi o jQuery. Além do jQuery e das bibliotecas node utilizadas, o resto foi programado por mim. Então peguem leve nas críticas.</strong></p>
<p style="text-align: center;"><!-- Place this tag where you want the button to render. --><br />
<a class="github-button" href="https://github.com/velhobit" data-size="large" data-show-count="true" aria-label="Follow @velhobit on GitHub">Follow @velhobit</a></p>
<p><!-- INICIO FORMULARIO BOTAO PAGSEGURO --></p>
<form action="https://pagseguro.uol.com.br/checkout/v2/donation.html" method="post"><!-- NÃO EDITE OS COMANDOS DAS LINHAS ABAIXO --> <input name="currency" type="hidden" value="BRL"> <input name="receiverEmail" type="hidden" value="portillo.designer@gmail.com"> <input style="padding: 1em 2em; display: block; margin: 0 auto; background-color: #33c375; text-decoration: none; text-align: center; color: white; border-radius: 10px; border: none; font-size: 1em; text-transform: uppercase;" alt="Pague com PagSeguro - é rápido, grátis e seguro!" name="submit" type="submit" value="Doar Pelo PagSeguro"></form>
]]></content:encoded>
					
					<wfw:commentRss>https://velhobit.com.br/editorial/bitmail-projeto-de-envio-de-mailmarketing-em-lote.html/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>IBM Watson &#8211; Como Criar um Chatbot (com PHP e jQuery)</title>
		<link>https://velhobit.com.br/programacao/ibm-watson-como-criar-um-chatbot-com-php-e-jquery.html</link>
					<comments>https://velhobit.com.br/programacao/ibm-watson-como-criar-um-chatbot-com-php-e-jquery.html#comments</comments>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Wed, 09 Aug 2017 05:59:09 +0000</pubDate>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[bluemix]]></category>
		<category><![CDATA[chat]]></category>
		<category><![CDATA[chatbot]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[experiência do usuário]]></category>
		<category><![CDATA[front-end]]></category>
		<category><![CDATA[ibm]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[user experience]]></category>
		<category><![CDATA[UX]]></category>
		<category><![CDATA[watson]]></category>
		<guid isPermaLink="false">https://bitcolor.com.br/?p=721</guid>

					<description><![CDATA[Este tutorial mostra a base para compreensão do uso da API de conversação do IBM Watson para criação de chatbot. Desde o começo até um exemplo prático.]]></description>
										<content:encoded><![CDATA[<p>Inteligência artificial é um tema que está em discussão constante no novo milênio. O uso de chatbots tem sido cada vez mais utilizado em diversos ambientes, seja para atendimento, monitoramento, suporte ou outras aplicações diversas. <a href="https://velhobit.com.br/design/o-que-e-design.html" target="_blank" rel="noopener">Designers de Interação</a> e <a href="https://velhobit.com.br/programacao/quanto-custa-ser-programador.html" target="_blank" rel="noopener">Programadores </a>tem usado cada vez mais essas tecnologias para poder criar uma experiência melhor e mais dinâmica para o usuário.</p>
<p>Dentro da área da computação cognitiva, uma das empresas que está em muita evidência no mercado é a IBM, com sua tecnologia Watson.</p>
<p>A tecnologia Watson é uma amálgama de serviços de inteligência artificial que permite ao desenvolvedor criar plataformas de comunicação automatas com seus usuários. Para isso, a IBM disponibiliza diversas APIs de comunicação com determinados serviços. Para nosso exemplo de chatbot usaremos o serviço de Conversação do Watson.</p>
<p>Criar um chatbot com o Watson é bem mais simples do que parece. Porém, devemos deixar claro que <strong>a proposta deste tutorial é ser básico, ser um ambiente de entrada, simplificado porém funcional para o desenvolvedor ou designer interessado nesse tipo de tecnologia</strong>.</p>
<p><strong>Atenção, você precisa de um servidor que possa ser autenticado na internet. Ou seja, não adianta testar de Xampp ou Wampp, você precisa testar ao menos de uma hospedagem compartilhada.</strong></p>
<h2>Preparando o Ambiente</h2>
<p>Primeiramente você vai precisar de uma conta na Bluemix. A Bluemix é uma plataforma em nuvem de projetos da Big Blue (apelido dado a IBM pelo mercado). Para isso, basta entrar no <a href="https://www.ibm.com/br-pt/marketplace/cloud-platform" target="_blank" rel="noopener">site da empresa e clicar em Teste Gratuito 30 Dias.</a></p>
<p><a href="https://www.ibm.com/br-pt/marketplace/cloud-platform" target="_blank" rel="noopener"><img loading="lazy" decoding="async" class="alignnone size-full wp-image-722" src="https://velhobit.com.br/wp-content/uploads/2017/08/bluemix.jpg" alt="" width="1396" height="669" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/bluemix.jpg 1396w, https://velhobit.com.br/wp-content/uploads/2017/08/bluemix-400x192.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/bluemix-768x368.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/bluemix-1024x491.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/08/bluemix-600x288.jpg 600w" sizes="auto, (max-width: 1396px) 100vw, 1396px" /></a></p>
<p>Depois disso, siga as instruções para você preencher os seus dados básicos.</p>
<p>Após o preenchimento de seus dados, será pedido para você criar uma organização. Por algum motivo, você não verá a opção de América do Sul referente ao local, todavia você pode continuar selecionando SUL DOS EUA que não vai impedir o funcionamento do chatbot. Simplesmente siga as demais opções até chegar ao final.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-723" src="https://velhobit.com.br/wp-content/uploads/2017/08/organização-bluemix.jpg" alt="" width="646" height="600" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/organização-bluemix.jpg 646w, https://velhobit.com.br/wp-content/uploads/2017/08/organização-bluemix-400x372.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/organização-bluemix-600x557.jpg 600w" sizes="auto, (max-width: 646px) 100vw, 646px" /></p>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-724 size-full" src="https://velhobit.com.br/wp-content/uploads/2017/08/ready-bluemix.jpg" alt="Cadastro no Bluemix" width="651" height="571" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/ready-bluemix.jpg 651w, https://velhobit.com.br/wp-content/uploads/2017/08/ready-bluemix-400x351.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/ready-bluemix-600x526.jpg 600w" sizes="auto, (max-width: 651px) 100vw, 651px" /></p>
<p>Assim que você finalizar, é possível ver uma área para criar Apps. Por hora você pode ignorar completamente isso. À primeira vista, o Bluemix parece ser um pouco difícil de navegar e encontrar algo por conta da diversidade de opções e APIs disponíveis.</p>
<p>No canto superior esquerdo você vai ver um menu hambúrguer. Clique nesse menu e selecione a opção <strong>Serviços</strong>. Lá, você vai ver a opção <strong>Watson</strong>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-726" src="https://velhobit.com.br/wp-content/uploads/2017/08/watson-servicos.jpg" alt="" width="526" height="613" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/watson-servicos.jpg 526w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-servicos-343x400.jpg 343w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-servicos-515x600.jpg 515w" sizes="auto, (max-width: 526px) 100vw, 526px" /></p>
<p>Como nosso tutorial é sobre chatbot, devemos criar um serviço do tipo <strong>Conversação</strong>. Clique no botão <strong>Criar serviço Watson</strong> e, na página que se abrirá, selecione a opção <strong>Conversation</strong>. A configuração do serviço é bem similar ao cadastro do próprio Bluemix.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-728" src="https://velhobit.com.br/wp-content/uploads/2017/08/criar-serviço-watson.jpg" alt="" width="1259" height="646" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/criar-serviço-watson.jpg 1259w, https://velhobit.com.br/wp-content/uploads/2017/08/criar-serviço-watson-400x205.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/criar-serviço-watson-768x394.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/criar-serviço-watson-1024x525.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/08/criar-serviço-watson-600x308.jpg 600w" sizes="auto, (max-width: 1259px) 100vw, 1259px" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-727" src="https://velhobit.com.br/wp-content/uploads/2017/08/opcoes-watson.jpg" alt="Criar serviço de conversação Watson" width="1226" height="730" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/opcoes-watson.jpg 1226w, https://velhobit.com.br/wp-content/uploads/2017/08/opcoes-watson-400x238.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/opcoes-watson-768x457.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/opcoes-watson-1024x610.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/08/opcoes-watson-600x357.jpg 600w" sizes="auto, (max-width: 1226px) 100vw, 1226px" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-729" src="https://velhobit.com.br/wp-content/uploads/2017/08/configure-bluemix-watson.jpg" alt="Configuração Bluemix" width="883" height="418" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/configure-bluemix-watson.jpg 883w, https://velhobit.com.br/wp-content/uploads/2017/08/configure-bluemix-watson-400x189.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/configure-bluemix-watson-768x364.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/configure-bluemix-watson-600x284.jpg 600w" sizes="auto, (max-width: 883px) 100vw, 883px" /></p>
<p>Esse serviço possui versões Lite (que é gratuita), Padrão e Premium (que precisa de consulta). Na versão Lite, que estamos usando para este tutorial, você possui até 10 mil requisições por mês e não poderá salvar os logs dos chats. Porém a versão padrão não é cara, cada requisição é uma fração inferior a metade de um centavo, o que é um valor aceitável para um sistema corporativo.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-730" src="https://velhobit.com.br/wp-content/uploads/2017/08/preço-watson.jpg" alt="Preço Conversação Watson" width="818" height="565" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/preço-watson.jpg 818w, https://velhobit.com.br/wp-content/uploads/2017/08/preço-watson-400x276.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/preço-watson-768x530.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/preço-watson-600x414.jpg 600w" sizes="auto, (max-width: 818px) 100vw, 818px" /></p>
<p>Agora é necessário &#8220;ensinar&#8221; ao Watson o que você quer que ele responda. Apesar dele já possuir uma inteligência base interna, que reconhece erros e contextos, você precisa treina-lo para que ele dê as respostas corretas para determinadas perguntas.</p>
<p>Para iniciar, você precisa criar um novo <em><strong>Workspace</strong> </em>(por enquanto, pode ignorar o espaço de trabalho de exemplo).</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-731" src="https://velhobit.com.br/wp-content/uploads/2017/08/conversation-watson.jpg" alt="" width="1150" height="465" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/conversation-watson.jpg 1150w, https://velhobit.com.br/wp-content/uploads/2017/08/conversation-watson-400x162.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/conversation-watson-768x311.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/conversation-watson-1024x414.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/08/conversation-watson-600x243.jpg 600w" sizes="auto, (max-width: 1150px) 100vw, 1150px" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-733" src="https://velhobit.com.br/wp-content/uploads/2017/08/watson-workspace.jpg" alt="" width="870" height="399" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/watson-workspace.jpg 870w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-workspace-400x183.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-workspace-768x352.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-workspace-600x275.jpg 600w" sizes="auto, (max-width: 870px) 100vw, 870px" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-734" src="https://velhobit.com.br/wp-content/uploads/2017/08/workspace-watson.jpg" alt="Criar espaço de trabalho" width="1008" height="515" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/workspace-watson.jpg 1008w, https://velhobit.com.br/wp-content/uploads/2017/08/workspace-watson-400x204.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/workspace-watson-768x392.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/workspace-watson-600x307.jpg 600w" sizes="auto, (max-width: 1008px) 100vw, 1008px" /></p>
<p><strong>Atenção ao idioma do espaço de trabalho que você está criando.</strong></p>
<h3>Treinando o Watson</h3>
<p>Uma vez criado o espaço de trabalho (<em>Workspace</em>), iniciaremos o processo de treinamento do Watson. Para isso, você deve primeiro criar um <em><strong>intent</strong></em>. Um <em>intent</em> é uma intenção de comunicação, ou seja, é um conjunto de interações padronizadas que o usuário poderá fazer com o chatbot.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-735" src="https://velhobit.com.br/wp-content/uploads/2017/08/intents.jpg" alt="" width="1573" height="572" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/intents.jpg 1573w, https://velhobit.com.br/wp-content/uploads/2017/08/intents-400x145.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/intents-768x279.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/intents-1024x372.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/08/intents-600x218.jpg 600w" sizes="auto, (max-width: 1573px) 100vw, 1573px" /></p>
<p>Cada intenção que for criada precisa ter pelo menos <strong>5</strong> exemplos de interações para poder funcionar. A partir daí o Watson também irá entender perguntas similares. Não é necessário se preocupar com muitas variações. A tecnologia é inteligente o suficiente para trabalhar com diferenças básicas, erros de digitação e compreender contextos. Em nosso exemplo, vamos criar uma intenção com o nome de <strong>#Saudações</strong> e preencher com algumas interações básicas de saudações.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-736" src="https://velhobit.com.br/wp-content/uploads/2017/08/watson-criar-perguntas.jpg" alt="" width="1008" height="710" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/watson-criar-perguntas.jpg 1008w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-criar-perguntas-400x282.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-criar-perguntas-768x541.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-criar-perguntas-600x423.jpg 600w" sizes="auto, (max-width: 1008px) 100vw, 1008px" /></p>
<p>Uma vez criada as intenções desejadas (em nosso exemplo criamos apenas uma), você deverá criar as possíveis respostas para essas intenções e suas variações. Para isso, você deve ir na área de <strong>Dialog</strong>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-737" src="https://velhobit.com.br/wp-content/uploads/2017/08/dialog-watson.jpg" alt="" width="995" height="495" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/dialog-watson.jpg 995w, https://velhobit.com.br/wp-content/uploads/2017/08/dialog-watson-400x199.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/dialog-watson-768x382.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/dialog-watson-600x298.jpg 600w" sizes="auto, (max-width: 995px) 100vw, 995px" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-738" src="https://velhobit.com.br/wp-content/uploads/2017/08/watson-nodes.jpg" alt="" width="552" height="419" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/watson-nodes.jpg 552w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-nodes-400x304.jpg 400w" sizes="auto, (max-width: 552px) 100vw, 552px" /></p>
<p>Um diálogo (Dialog), como o nome já diz, consiste em um conjunto de interações e condições dessas interações, com uma resposta, que pode ou não resultar em um feedback para encerrar um processo de comunicação.</p>
<p>No Watson, o diálogo é organizado em um sistema de árvores, que possui uma lógica de nós e subnós. Para nosso exemplo, vamos criar um novo nó para responder a intenção de saudação que criamos anteriormente. Clique em <strong>Add node</strong>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-739" src="https://velhobit.com.br/wp-content/uploads/2017/08/watson-resposta.jpg" alt="" width="798" height="623" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/watson-resposta.jpg 798w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-resposta-400x312.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-resposta-768x600.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-resposta-600x468.jpg 600w" sizes="auto, (max-width: 798px) 100vw, 798px" /></p>
<p>Após dar um nome ao nó, você deve colocar o que o bot irá reconhecer. A intenção é representada pelo símbolo de hash (#). Então, basicamente diz:<em> Se o bot reconhecer a intenção <strong>#Saudação</strong>, então responda com</em>:</p>
<p>Você pode colocar quantas respostas você quiser. Quanto mais respostas você colocar, maior a quantidade de diálogo possível, deixando o ambiente de comunicação mais natural e otimizando o aprendizado.</p>
<p>Como opções adicionais você pode colocar as respostas em forma sequencial ou aleatória. Ainda é possível criar condições específicas de contextos ou aguardar por respostas específicas à retóricas do chatbot.</p>
<p>Com tudo isso preenchido, você já pode testar o chatbot. O próprio ambiente do bluemix possui uma área para testes. Clique no ícone com o balãozinho no canto superior direito e experimente o diálogo que você acabou de criar.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-740" src="https://velhobit.com.br/wp-content/uploads/2017/08/watson-test.jpg" alt="" width="899" height="702" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/watson-test.jpg 899w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-test-400x312.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-test-768x600.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/watson-test-600x469.jpg 600w" sizes="auto, (max-width: 899px) 100vw, 899px" /></p>
<h2>Implementando o Back-end</h2>
<p>A API do Bluemix funciona através de comunicação cURL Essa comunicação é feita a partir de envios de informações via método POST e mediante autorização de acesso. Por isso, vamos precisar de algumas informações básicas do serviço de comunicação que criamos.</p>
<p>Caso você queira ver outros exemplos que usam cURL, acesse nosso tutorial sobre <a href="https://velhobit.com.br/programacao/carregando-dinamicamente-dados-empresa-cnpj-php-jquery.html" target="_blank" rel="noopener">preenchimento automático de formulário com o CNPJ</a> ou o tutorial sobre <a href="https://velhobit.com.br/programacao/carregando-cep-cidades-dinamicamente.html" target="_blank" rel="noopener">preenchimento automático de endereço a partir do CEP</a>.</p>
<p>Então, antes de criamos o código, você vai precisar das seguintes informações:</p>
<ul>
<li>Workspace ID</li>
<li>Username</li>
<li>Password</li>
</ul>
<p>O Workspace ID pode ser adquirido lá naquela tela de criação/seleção de ambientes de trabalho (Workspaces). Basta clicar no botão de menu, no canto superior direito do cartão referente ao workspace que criamos, em seguida clicando em <strong>View Details</strong>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-742" src="https://velhobit.com.br/wp-content/uploads/2017/08/workspaces-1.jpg" alt="Pegar Código do Workspace no Watson" width="1234" height="619" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/workspaces-1.jpg 1234w, https://velhobit.com.br/wp-content/uploads/2017/08/workspaces-1-400x201.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/workspaces-1-768x385.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/workspaces-1-1024x514.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/08/workspaces-1-600x301.jpg 600w" sizes="auto, (max-width: 1234px) 100vw, 1234px" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-743" src="https://velhobit.com.br/wp-content/uploads/2017/08/workspace-view-details.jpg" alt="" width="437" height="419" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/workspace-view-details.jpg 437w, https://velhobit.com.br/wp-content/uploads/2017/08/workspace-view-details-400x384.jpg 400w" sizes="auto, (max-width: 437px) 100vw, 437px" /></p>
<p>Para conseguir o login e senha do serviço de conversação, volte a tela onde você cria os serviços e vá na opção <strong>Credenciais de Serviço</strong>. Nessa área você pode visualizar ou criar novas credenciais, conseguindo assim o <em>username</em> e <em>password</em> que vamos precisar mais adiante.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-744" src="https://velhobit.com.br/wp-content/uploads/2017/08/credenciais-serviço.jpg" alt="" width="812" height="420" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/credenciais-serviço.jpg 812w, https://velhobit.com.br/wp-content/uploads/2017/08/credenciais-serviço-400x207.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/credenciais-serviço-768x397.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/credenciais-serviço-600x310.jpg 600w" sizes="auto, (max-width: 812px) 100vw, 812px" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-746" src="https://velhobit.com.br/wp-content/uploads/2017/08/credenciais-pagina.jpg" alt="" width="1074" height="774" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/credenciais-pagina.jpg 1074w, https://velhobit.com.br/wp-content/uploads/2017/08/credenciais-pagina-400x288.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/08/credenciais-pagina-768x553.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/08/credenciais-pagina-1024x738.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/08/credenciais-pagina-600x432.jpg 600w" sizes="auto, (max-width: 1074px) 100vw, 1074px" /></p>
<p><span style="color: #ff0000;"><strong>ATENÇÃO<br />
A IBM mudou a forma de autenticação. Agora, ao invés de você ter acesso ao username e password, as novas conexões usarão a autenticação AIM e não mais a autenticação por username  password. Mais detalhes, veja a documentação: <a style="color: #ff0000;" href="https://console.bluemix.net/apidocs/assistant">https://console.bluemix.net/apidocs/assistant</a>.</strong></span></p>
<p>Agora vamos ao código.</p>
<p>A API REST do Watson, como dito acima, funciona a partir de comunicação cURL e vai retornar um json completo com todas as informações para a comunicação. Para criarmos uma conversa simples, precisamos definir o código. Fique atento ao que precisa ser preenchido.</p>
<h3>Exemplo usando PHP</h3>
<p><strong>conversa.php</strong></p>
<p>Como o retorno é json, precisamos definir a página como text/plain, para evitar qualquer renderização incorreta.</p>
<pre class="prettyprint">header("Content-Type: text/plain");</pre>
<p>Iremos definir então as informações que pegamos acima através das configurações do serviço de conversação. Lembre-se de substituir o código abaixo por seus dados.</p>
<pre class="prettyprint">$workspace = "d5b7e381-xxxx-xxxx-xxxx-xxxxxxxxxxxx";

$apikey = "xxxxxxxxxxxxxxxxx";

/*Antiga autenticação
$username = "cd27b34f-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
$password = "Klxxxxxxxx";
*/</pre>
<p>Precisamos agora capturar o texto que será enviado para o servidor do Watson. Para testes usaremos o $_REQUEST, do PHP. Por segurança, quando for trabalhar em modo de produção, troque para $_POST.</p>
<pre class="prettyprint">$texto = $_REQUEST["texto"];</pre>
<p>Agora é necessário definir um identificador. Para manter o contexto de conversa, e o Watson saber que está conversando ainda com a mesma pessoa, é necessário passar um identificador. Esse identificador deverá ser único por conversa. Caso você esteja implementando em um sistema de gestão, por exemplo, você pode usar o nome de usuário, id, e-mail, ou algum outro tipo de identificação única.</p>
<p>No nosso teste criaremos uma hash única md5 e a armazenaremos em uma sessão. Dessa forma, garantimos a criação temporária de um identificador único funcional. Nosso bloco então ficará:</p>
<pre class="prettyprint">if (session_status() == PHP_SESSION_NONE) {
    session_start();
}
if(isset($_SESSION["identificador"])){
	$identificador = $_SESSION["identificador"];
}else{
	$identificador = md5(uniqid(rand(), true));
	$_SESSION["identificador"] = $identificador;
}</pre>
<p>A URL da API REST deverá ser concatenada com o Workspace e o método que você está chamando. Dentro do gateway de conversação há vários métodos, desde status a tratamento de workspaces e diálogos. Através da documentação, você poderá explorar todos os métodos acessíveis para o Watson:<a href="https://www.ibm.com/watson/developercloud/conversation/api/v1/" target="_blank" rel="noopener"> https://www.ibm.com/watson/developercloud/conversation/api/v1/</a>.</p>
<p>Em nosso exemplo básico, entretanto, iremos utilizar apenas o método <em><strong>message</strong></em>. É importante lembrar que é necessário adicionar a data da versão da API como parâmetro para que possa funcionar.</p>
<pre class="prettyprint">$url = "https://gateway.watsonplatform.net/conversation/api/v1/workspaces/" . $workspace;
$urlMessage = $url . "/message?version=2017-05-26";</pre>
<p>Para enviar os dados para o Watson, precisamos criar uma pequena string json. Como em nosso exemplo só precisamos enviar o texto e o identificador, podemos simplesmente concatenar o texto, deixando-o pronto para envio.</p>
<pre class="prettyprint">$dados  = "{";
$dados .= "\"input\": ";
$dados .= "{\"text\": \"" . $texto . "\"},";
$dados .= "\"context\": {\"conversation_id\": \"" . $identificador . "\",";
$dados .= "\"system\": {\"dialog_stack\":[{\"dialog_node\":\"root\"}], \"dialog_turn_counter\": 1, \"dialog_request_counter\": 1}}";
$dados .= "}";</pre>
<p>Como estamos tratando de json, devemos especificar o cabeçalho do tipo de dados que estamos enviando.</p>
<pre class="prettyprint">$headers = array('Content-Type:application/json');</pre>
<p>Agora começa a comunicação. Para acessar a API, algumas exigências são feitas. É necessário ser enviado em método POST um json e ser uma comunicação segura, com identificação de usuário e senha. O bloco referente a comunicação ficará então:</p>
<pre class="prettyprint">$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $urlMessage);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $dados);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_USERPWD, "$username:$password"); Autenticação antiga
curl_setopt($ch, CURLOPT_USERPWD, "apikey:$apikey")
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$retorno = curl_exec($ch);
curl_close($ch);</pre>
<p>Por fim, para facilitar a leitura, vamos imprimir o json na tela com uma organização mais legível para um ser-humano.</p>
<pre class="prettyprint">$retorno = json_decode($retorno);
echo json_encode($retorno, JSON_PRETTY_PRINT);</pre>
<p>Com isso já poderemos ter uma resposta json, que, ao passar o texto, retornará algo similar como na imagem abaixo:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-749" src="https://velhobit.com.br/wp-content/uploads/2017/08/exemplo-json.jpg" alt="" width="599" height="875" srcset="https://velhobit.com.br/wp-content/uploads/2017/08/exemplo-json.jpg 599w, https://velhobit.com.br/wp-content/uploads/2017/08/exemplo-json-274x400.jpg 274w, https://velhobit.com.br/wp-content/uploads/2017/08/exemplo-json-411x600.jpg 411w" sizes="auto, (max-width: 599px) 100vw, 599px" /></p>
<p><strong>O código back-end completo fica (com comentários para ajudar a compreensão):</strong></p>
<pre class="prettyprint">&lt;?php
//Garantir que seja lido sem problemas
header("Content-Type: text/plain");

//Worskspace
$workspace = "d5b7e381-XXXX-XXXX-XXXX-XXXXXXXXXXXX";

/**
Antiga Autenticação
//Dados de Login
$username = "cd27b34f-XXXX-XXXX-XXXX-XXXXXXXXXXXX";
$password = "Kl8XXXXXXXXX";
**/
$apikey = "xxxxxxxxxxxxxxxxx";
//Capturar Texto
//Use $_POST em produção, por segurança
$texto = $_REQUEST["texto"];

//Verifica se existe identificador
//Caso não haja, crie um
if (session_status() == PHP_SESSION_NONE) {
    session_start();
}
if(isset($_SESSION["identificador"])){
	$identificador = $_SESSION["identificador"];
}else{
	//Você pode usar qualquer identificador
	//Você pode usar ID do usuário ou similar
	$identificador = md5(uniqid(rand(), true));
	$_SESSION["identificador"] = $identificador;
}

//URL da API
//(deve ser passado o método e a versão da API em GET)
$url = "https://gateway.watsonplatform.net/conversation/api/v1/workspaces/" . $workspace;
$urlMessage = $url . "/message?version=2017-05-26";

//Dados
$dados  = "{";
$dados .= "\"input\": ";
$dados .= "{\"text\": \"" . $texto . "\"},";
$dados .= "\"context\": {\"conversation_id\": \"" . $identificador . "\",";
$dados .= "\"system\": {\"dialog_stack\":[{\"dialog_node\":\"root\"}], \"dialog_turn_counter\": 1, \"dialog_request_counter\": 1}}";
$dados .= "}";

//Cabeçalho que leva tipo de Dados
$headers = array('Content-Type:application/json');

//Iniciando Comunicação cURL
$ch = curl_init();
//Selecionando URL
curl_setopt($ch, CURLOPT_URL, $urlMessage);
//O cabeçalho é importante para definir tipo de arquivo enviado
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
//Habilitar método POST
curl_setopt($ch, CURLOPT_POST, 1);
//Enviar os dados
curl_setopt($ch, CURLOPT_POSTFIELDS, $dados);
//Capturar Retorno
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//Autenticação
//curl_setopt($ch, CURLOPT_USERPWD, "$username:$password"); Autenticação antiga
curl_setopt($ch, CURLOPT_USERPWD, "apikey:$apikey")
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
//Executar
$retorno = curl_exec($ch);
//Fechar Conexão
curl_close($ch);

//Imprimir com leitura fácil para humanos
$retorno = json_decode($retorno);
echo json_encode($retorno, JSON_PRETTY_PRINT);

?&gt;</pre>
<h2>Código do Front-End</h2>
<p>Agora precisamos fazer a interação do usuário com o chatbot. Para isso, precisamos criar uma área do chat e o formulário que enviará os dados.</p>
<pre class="prettyprint">&lt;div id="watson" class="watson"&gt;
	&lt;div class="mensagens"&gt;
		&lt;div class="area" id="chat"&gt;
		&lt;/div&gt;
	&lt;/div&gt;
	&lt;form id="mensagem" class="mensagem"&gt;
		&lt;input type="text" id="texto" name="texto" placeholder="Digite sua mensagem"/&gt;
		&lt;button type="submit"&gt;Enviar&lt;/button&gt;
	&lt;/form&gt;
&lt;/div&gt;</pre>
<p>Com a área de chat criada, está na hora de adicionarmos os scripts necessários para fazer a comunicação com o back-end. Para facilitar, usaremos o método ajax do jQuery. Atenção aos comentários no código abaixo, pois eles explicam para quê serve cada linha.</p>
<pre class="prettyprint">&lt;!--Importar jQuery. Retire caso sua página já faça a importação. --&gt;
&lt;script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript"&gt;
//Submeter Formulário
$("#mensagem").submit(function(){
	//Caso o usuário envie uma mensagem vazia
	if($("#mensagem #texto").val() === ""){
		//Adiciona na área de Chat a mensagem enviada pelo usuário
		$("#chat").append("&lt;div class=\"texto usuario\"&gt;...&lt;/div&gt;");
		
		//Faz um scroll para a mensagem mais recente, caso necessário
		$(".mensagens").animate({scrollTop: $("#chat").height()});
		setTimeout(function(){
			//Adiciona uma resposta padrão afirmando que o usuário deixou o campo vazio
			$("#chat").append("&lt;div class=\"texto chatbot\"&gt;Você precisa digitar alguma coisa para prosseguir.&lt;/div&gt;");
			//Faz um scroll para a mensagem mais recente, caso necessário
			$(".mensagens").animate({scrollTop: $("#chat").height()});
		},1000);
		return false;
	}
	
	//Inicia método AJAX
	$.ajax({
		//Substitua o caminho da URL pelo que você salvou o arquivo de backend
		url: "/pasta/conversa.php?texto=" + $("#mensagem #texto").val(),
		dataType: 'json', // Determina o tipo de retorno
		beforeSend: function(){
			//Adiciona a mensagem de usuário à lista de mensagens.
			$("#chat").append("&lt;div class=\"texto usuario\"&gt;" + $("#mensagem #texto").val() + "&lt;/div&gt;");	
		},
		success: function(resposta){
			//Limpa o que o usuário digitou e foca no input para próxima interação.
			$("#mensagem #texto").val("");
			$("#mensagem #texto").focus();
			
			//Caso haja um erro, o Watson retornará a mensagem de erro ao usuário
			//Basta ler o objeto error para o usuário.
			if(resposta.error){
				$("#chat").append("&lt;div class=\"texto chatbot\"&gt;" + resposta.error + "&lt;/div&gt;");
				return false;
			}
			
			//Colocar a resposta do Watson para o usuário ler
			//A mensagem de texto pode ser lida a partir da lógica
			//do json de exemplo da imagem no post
			var mensagemChatbot  = "&lt;div class=\"texto chatbot\"&gt;";
			mensagemChatbot		+= resposta.output.text[0];
			mensagemChatbot		+= "&lt;/div&gt;";
			setTimeout(function(){
				$("#chat").append(mensagemChatbot);
				$(".mensagens").animate({scrollTop: $("#chat").height()});
			},1000);
		}
	});

	return false;
});
&lt;/script&gt;</pre>
<p>Observe que no código acima existe um método setTimeOut que ocorre sempre antes de adicionar a resposta do Watson. Isso é feito por uma decisão de experiência do usuário.</p>
<p>Uma resposta muito rápida pode causar uma confusão de interpretação e estranhamento.</p>
<p>Quando você está conversando com alguém, a tendência é, ao enviar uma mensagem, esperar que a pessoa ao menos pense na resposta e digite antes de responder. Um pequeno atraso de um segundo na resposta é um tempo mínimo esperado para dar uma maior naturalidade a conversa e ainda permitir que o usuário se prepare para receber uma mensagem. Essa é uma decisão puramente de UX. Caso queira, você pode retirar o setTimeout e irá funcionar normalmente, mas ao testar você poderá sentir que esse tempo de resposta faz falta.</p>
<p>Para finalizar, vamos colocar um estilo CSS para ficar mais agradável ao usuário.</p>
<pre class="prettyprint">&lt;style&gt;
	.watson{
		border: 1px solid #B0BEC5;
		border-radius: 3px;
		height: 50em;
		max-height: 500px;
		padding: 1em;
		
		max-width: 500px;
		margin: 0 auto;
		
		display: flex;
		flex-direction: column;
		justify-content: space-between;
	}
	
	.watson .mensagens{
		box-sizing: border-box;
		overflow: hidden;
		overflow-y: auto;
		height: 100%;
	}
	
	.watson .mensagens .area{
		display: flex;
		justify-content: flex-end;
		flex-direction: column;
		min-height: 100%;
	}
	
	.watson .mensagens .texto{
		border-radius: 2px;
		box-sizing: border-box;
		padding: .65em;
		margin-top: .5em;
		
		animation: popupmensagem linear .2s;
		animation-iteration-count: 1;
		-webkit-animation: popupmensagem linear .2s;
		-webkit-animation-iteration-count: 1;
		-moz-animation: popupmensagem linear .2s;
		-moz-animation-iteration-count: 1;
		-o-animation: popupmensagem linear .2s;
		-o-animation-iteration-count: 1;
		-ms-animation: popupmensagem linear .2s;
		-ms-animation-iteration-count: 1;
	}
	
	.watson .mensagens .texto:first-child{
		margin-top: 0;
	}
	
	.watson .mensagens .texto.usuario{
		background-color: #ECEFF1;
		color: #1A237E;
		margin-right: 30%;
		
		transform-origin: 0% 100%;
		-webkit-transform-origin: 0% 100%;
		-moz-transform-origin: 0% 100%;
		-o-transform-origin: 0% 100%;
		-ms-transform-origin: 0% 100%;
	}
	
	.watson .mensagens .texto.chatbot{
		background-color: #FF5722;
		color: white;
		font-weight: bold;
		margin-left: 30%;
		
		transform-origin: 100% 100%;
		-webkit-transform-origin: 100% 100%;
		-moz-transform-origin: 100% 100%;
		-o-transform-origin: 100% 100%;
		-ms-transform-origin: 100% 100%;
	}
	
	.watson form.mensagem{
		padding: 0;
		margin-top: 1em;
	}
	
	.watson form.mensagem input{
		border: 2px solid #476A7B;
		border-radius: 3px;
		padding: .5em .8em;
		font-size: 16px;
		display: block;
		box-sizing: border-box;
		width: 100%;
	}
	
	.watson form.mensagem input:focus{
		border: 2px solid #1A237E;
		outline: none;
	}
	
	.watson form.mensagem button{
		background-color: #3F51B5;
		border: none;
		border-radius: 3px;
		display: block;
		padding: .5em 1em;
		width: 100%;
		font-size: 16px;
		color: white;
		margin-top: .5em;
	}
	
	
	/**Animação de Mensagem**/
	
	@keyframes popupmensagem{
	  0% {
		transform:  scaleX(0.30) scaleY(0.30) ;
	  }
	  100% {
		transform:  scaleX(1.00) scaleY(1.00) ;
	  }
	}

	@-moz-keyframes popupmensagem{
	  0% {
		-moz-transform:  scaleX(0.30) scaleY(0.30) ;
	  }
	  100% {
		-moz-transform:  scaleX(1.00) scaleY(1.00) ;
	  }
	}

	@-webkit-keyframes popupmensagem {
	  0% {
		-webkit-transform:  scaleX(0.30) scaleY(0.30) ;
	  }
	  100% {
		-webkit-transform:  scaleX(1.00) scaleY(1.00) ;
	  }
	}

	@-o-keyframes popupmensagem {
	  0% {
		-o-transform:  scaleX(0.30) scaleY(0.30) ;
	  }
	  100% {
		-o-transform:  scaleX(1.00) scaleY(1.00) ;
	  }
	}

	@-ms-keyframes popupmensagem {
	  0% {
		-ms-transform:  scaleX(0.30) scaleY(0.30) ;
	  }
	  100% {
		-ms-transform:  scaleX(1.00) scaleY(1.00) ;
	  }
	}
&lt;/style&gt;
</pre>
<p>E agora? Funciona mesmo?</p>
<p>Veja o exemplo abaixo, utilizamos exatamente o mesmo código. Lembre-se que há apenas poucas interações e respostas criadas para este tutorial, então não espere ter uma conversa muito avançada com este chatbot.</p>
<p><strong>Obs. Está sendo utilizada no exemplo uma conta Lite, então é possível que quando você testar já tenha acabado o limite mensal.</strong></p>
<div id="watson" class="watson">
<div class="mensagens">
<div id="chat" class="area"></div>
</div>
<form id="mensagem" class="mensagem"><input id="texto" name="texto" type="text" placeholder="Digite sua mensagem" /><button type="submit">Enviar</button></form>
</div>
<p>Caso você deseje um pouco mais de segurança, recomendamos que você utilize um arquivo .htdocs na pasta em que está o conversa.php, com o conteúdo abaixo. Evitando, assim, acesso externo.</p>
<pre class="prettyprint">#Evitar Acesso Externo
Order Deny,Allow
Deny from all
Allow from 127.           # localhost</pre>
<h3>Faça o Download do Código no Github, se preferir:</h3>
<p><center><br />
<!-- Place this tag where you want the button to render. --><br />
<a class="github-button" href="https://github.com/velhobit/Watson-Example-PHP-Chatbot/archive/master.zip" data-icon="octicon-cloud-download" data-size="large" aria-label="Download velhobit/Watson-Example-PHP-Chatbot on GitHub">Download</a></center>Implementar um chatbot do IBM Watson é mais simples do que você pensava, não é? Mas lembre-se que esse é só um tutorial básico para demonstrar como usar a API REST. Você pode, verificar todos os métodos e parâmetros que podem ser utilizados diretamente pela <a href="https://www.ibm.com/watson/developercloud/conversation/api/v1/" target="_blank" rel="noopener">documentação</a>.</p>
<p>Caso tenha apreciado este conteúdo, dê uma passada lá na <a href="https://www.facebook.com/velhobit/" target="_blank" rel="noopener">página da VelhoBit no Facebook</a> e deixe seu like. Compartilhe este post com colegas e interessados na área de tecnologia e não deixe de conferir o restante dos artigos no blog.</p>
<p>Até o próximo tutorial.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://velhobit.com.br/programacao/ibm-watson-como-criar-um-chatbot-com-php-e-jquery.html/feed</wfw:commentRss>
			<slash:comments>12</slash:comments>
		
		
			</item>
		<item>
		<title>Como Preencher Dados da Empresa pelo CNPJ Dinamicamente (com PHP ou Java)</title>
		<link>https://velhobit.com.br/programacao/carregando-dinamicamente-dados-empresa-cnpj-php-jquery.html</link>
					<comments>https://velhobit.com.br/programacao/carregando-dinamicamente-dados-empresa-cnpj-php-jquery.html#comments</comments>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Thu, 03 Aug 2017 10:04:30 +0000</pubDate>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[cnpj]]></category>
		<category><![CDATA[consulta]]></category>
		<category><![CDATA[dinamico]]></category>
		<category><![CDATA[fazenda]]></category>
		<category><![CDATA[formulario]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[preenchimento]]></category>
		<guid isPermaLink="false">https://bitcolor.com.br/?p=689</guid>

					<description><![CDATA[Este tutorial mostra agilizar cadastros carregando dinamicamente os dados de uma empresa pelo CNPJ, a partir da API Receita WS. Com HTML, jQuery e PHP.]]></description>
										<content:encoded><![CDATA[<p>Dentro do design de interação, a automação de dados é importante para agilizar cadastros, além de garantir uma maior segurança dessas informações. Preencher dinamicamente o máximo de campos possível é sempre uma opção interessante para otimizar processos e manter um ambiente ágil.</p>
<p>Uma das formas mais utilizadas é o preenchimento automático de endereço a partir do <a href="https://velhobit.com.br/programacao/carregando-cep-cidades-dinamicamente.html">CEP (clique aqui, caso queira saber como fazer)</a>. Porém, uma outra alternativa muito interessante, e sempre procurada, é o preenchimento dinâmico dos dados de uma empresa a partir do CNPJ.</p>
<p>Para isso, há uma API pública bem interessante de uma organização chamada&nbsp;<a href="https://www.receitaws.com.br/">ReceitaWS</a>, que é uma empresa destinada a fornecer dados de pessoas jurídicas a partir da Receita Federal. Sua API pública é bem funcional e garante uma quantidade enorme de CNPJs atualizados. O ReceitaWS também possui uma API comercial para quem precisa de dados mais refinados e precisos.</p>
<p><strong>Obs. Só deixando claro que isto NÃO é um anúncio.</strong></p>
<h2>Conectando com o ReceitaWS</h2>
<p>A API do ReceitaWS aconselha o acesso via cURL. Falando de forma simples, é como se o servidor fizesse o acesso a um site como se fosse um navegador. Por questões de segurança e para impedir o acúmulo de processos, muitas APIs bloqueiam o acesso direto. Por isso a comunicação não pode ser feita apenas com a URL.</p>
<p>Apesar de ser possível fazer acesso cURL em praticamente qualquer linguagem, vamos usar PHP (atualização: ou Java) no nosso exemplo, por você poder usar em praticamente qualquer hospedagem.</p>
<p>Esse acesso deverá ser feito para a URL:&nbsp;https://www.receitaws.com.br/v1/cnpj/[cnpj], onde [cnpj] corresponde ao número do CNPJ que você irá consultar.</p>
<p>Para iniciar, devemos criar um arquivo onde vai ser carregado os dados e impresso o retorno.</p>
<p><strong>cnpj.php</strong></p>
<p>É extremamente importante que o nosso arquivo possua um cabeçalho que imprima como text/plain. Isso porque teremos uma resposta em jSon e passar este cabeçalho irá garantir a leitura correta dos dados.</p>
<pre class="prettyprint">header("Content-Type: text/plain");</pre>
<p>Em seguida, devemos capturar o CNPJ enviado pela requisição e guardar em uma variável.</p>
<pre class="prettyprint">$cnpj = $_REQUEST["cnpj"];</pre>
<p>Agora começa a parte interessante. Iremos usar o método cURL do PHP para poder acessar a URL e passar o CNPJ. Leias os comentários para entender seu funcionamento.</p>
<pre class="prettyprint">$ch = curl_init(); //Inicializa
curl_setopt($ch, CURLOPT_URL, "https://www.receitaws.com.br/v1/cnpj/".$cnpj); //Acessa a URL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //Permite a captura do Retorno
$retorno = curl_exec($ch); //Executa o cURL e guarda o Retorno em uma variável
curl_close($ch); //Encerra a conexão
</pre>
<p>Por fim, devemos terminar com a impressão do retorno.<br />
Para o retorno poder ser lido de forma simples, mesmo que por um humano, iremos usar o JSON_PRETTY_PRINT. Para isso, temos que converter a String de retorno usando o método Json Decode, em seguida imprimindo o resultado com o JSON_PRETTY_PRINT.</p>
<pre class="prettyprint">$retorno = json_decode($retorno); //Ajuda a ser lido mais rapidamente
echo json_encode($retorno, JSON_PRETTY_PRINT);
</pre>
<p>O código completo ficará:</p>
<pre class="prettyprint">&lt;?php
//Garantir que seja lido sem problemas
header("Content-Type: text/plain");

//Capturar CNPJ
$cnpj = $_REQUEST["cnpj"];

//Criando Comunicação cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://www.receitaws.com.br/v1/cnpj/".$cnpj);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //Descomente esta linha apenas se você não usar HTTPS, ou se estiver testando localmente
$retorno = curl_exec($ch);
curl_close($ch);

$retorno = json_decode($retorno); //Ajuda a ser lido mais rapidamente
echo json_encode($retorno, JSON_PRETTY_PRINT);

?&gt;</pre>
<p>Se quiser testar, basta acessar o seu arquivo php pelo navegador, por exemplo:<br />
seusite.com/pasta/cnpj.php?cnpj=XXXXXXXXXXXXX</p>
<p><strong>Atualização (Java):</strong></p>
<p>Você também pode fazer com Java. O exemplo abaixo é uma forma bem simples de fazer.</p>
<pre class="prettyprint">&lt;%@ page contentType="text/plain; charset=utf-8" language="java" errorPage="" %&gt;
&lt;%@page import="java.io.*"%&gt;
&lt;%@page import="java.net.URL"%&gt;
&lt;%
URL url = new URL("https://www.receitaws.com.br/v1/cnpj/"+request.getParameter("cnpj"));
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"))) {
 for (String line; (line = reader.readLine()) != null;) {
 out.println(line);
 }
}
%&gt;</pre>
<h2>Evitando acessos externos</h2>
<p>Por segurança, precisamos evitar que outros sites acessem o nosso json. Isso para evitar que o servidor caia devido a diversas requisições de fontes desconhecidas. A forma mais simples de fazer isso, e compatível com praticamente qualquer hospedagem / servidor, é através do arquivo .htaccess.</p>
<p>Na mesma pasta onde foi criado o arquiv <strong>cnpj.php</strong> deve ser criado um arquivo chamado:</p>
<p><strong> .htaccess</strong></p>
<p>Nesse arquivo deve conter as seguintes informações:</p>
<pre class="prettyprint">#Evitar Acesso Externo
Order Deny,Allow
Deny from all
Allow from 127. #localhost</pre>
<p>Basicamente, o que está sendo dito é que nenhum servidor pode acessar o conteúdo desta pasta, exceto o localhost (127.0.0.1). Caso você queira adicionar mais algum IP autorizado, basta adicionar o IP ou domínio do endereço que deseja.</p>
<p><strong>ATENÇÃO: Caso você seja usuário Cloudflare, adicone os seguintes IPs em sua lista de permissões do .htaccess:</strong></p>
<pre class="prettyprint">Allow from 199.27.128.0/21
Allow from 173.245.48.0/20
Allow from 103.21.244.0/22
Allow from 103.22.200.0/22
Allow from 103.31.4.0/22
Allow from 141.101.64.0/18
Allow from 108.162.192.0/18
Allow from 190.93.240.0/20
Allow from 188.114.96.0/20
Allow from 197.234.240.0/22
Allow from 198.41.128.0/17
Allow from 162.158.0.0/15
Allow from 104.16.0.0/12
Allow from 172.64.0.0/13</pre>
<p><strong>Atualização (Java):</strong></p>
<p>Caso você use o Java, a forma de configurar as permissões de acesso irá variar de acordo com o servidor que você utilizar.</p>
<p>Caso você utilize o Tomcat, você deve utilizar o CORS para fazer esse controle de permissão.</p>
<p>Para isso, edite o arquivo <strong>web.xml</strong>, e procure pelo filtro do CORS. O bloco deverá ficar algo semelhante ao código abaixo, segundo a mesma lógica do exemplo acima, do PHP:</p>
<pre class="prettyprint">&lt;filter&gt;
    &lt;filter-name&gt;CORS&lt;/filter-name&gt;
    &lt;filter-class&gt;com.thetransactioncompany.cors.CORSFilter&lt;/filter-class&gt;
    &lt;init-param&gt;
     &lt;param-name&gt;cors.allowOrigin&lt;/param-name&gt;
        &lt;param-value&gt;127.0.0.1&lt;/param-value&gt;
    &lt;/init-param&gt;
    &lt;init-param&gt;
     &lt;param-name&gt;cors.supportedMethods&lt;/param-name&gt;
        &lt;param-value&gt;GET, POST, HEAD, PUT, DELETE&lt;/param-value&gt;
    &lt;/init-param&gt;
    &lt;init-param&gt;
       &lt;param-name&gt;cors.supportedHeaders&lt;/param-name&gt;
       &lt;param-value&gt;Accept, Origin, X-Requested-With, Content-Type, Last-Modified&lt;/param-value&gt;
    &lt;/init-param&gt;
    &lt;init-param&gt;
        &lt;param-name&gt;cors.exposedHeaders&lt;/param-name&gt;
        &lt;param-value&gt;Set-Cookie&lt;/param-value&gt;
    &lt;/init-param&gt;
    &lt;init-param&gt;
        &lt;param-name&gt;cors.supportsCredentials&lt;/param-name&gt;
        &lt;param-value&gt;true&lt;/param-value&gt;
    &lt;/init-param&gt;
&lt;/filter&gt;</pre>
<p><strong>OBS. O uso do CORS pode dar problemas com clientes que façam acesso por cliente sem DNS, ou seja, com acesso que não é feito por conexão http ou https, como por exemplo,<br />
o Cordova/Phonegap. Nesse caso, aconselha-se simplesmente não usar o CORS, ou editar a bibliotca.</strong></p>
<h2>Enviando o CNPJ e Imprimindo os Dados da Empresa</h2>
<p>Já para imprimir os dados e ler o json de retorno, precisamos usar um formulário HTML e um pouco de Javascript. Para poder facilitar a compreensão, usaremos o bom e velho <a href="https://velhobit.com.br/programacao/implementando-a-integracao-entre-php-jquery-json.html">jQuery, já explicado em conteúdos anteriores</a>.</p>
<p>A primeira coisa é criar o formulário que devemos usar.</p>
<p><strong>form.html</strong></p>
<pre class="prettyprint">&lt;!--Importando Script Jquery--&gt;
&lt;script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"&gt;&lt;/script&gt;

&lt;!--Formulário--&gt;
&lt;form id="post"&gt;
  &lt;label for="cnpj"&gt;CNPJ&lt;/label&gt;
  &lt;input id="cnpj" required type="text"&gt;
  &lt;br/&gt;
  &lt;label for="nome"&gt;Razão Social&lt;/label&gt;
  &lt;input id="nome" type="text"&gt;
  &lt;br/&gt;
  &lt;label for="fantasia"&gt;Nome Fantasia&lt;/label&gt;
  &lt;input id="fantasia" type="text"&gt;
  &lt;br/&gt;
  &lt;label for="atividade"&gt;Atividade Principal&lt;/label&gt;
  &lt;input id="atividade" type="text"&gt;
  &lt;br/&gt;
  &lt;label for="telefone"&gt;Telefone&lt;/label&gt;
  &lt;input id="telefone" required type="text"&gt;
  &lt;br/&gt;
  &lt;label for="email"&gt;E-mail&lt;/label&gt;
  &lt;input id="email" type="text"&gt;
  &lt;br/&gt;
  &lt;label for="cep"&gt;CEP&lt;/label&gt;
  &lt;input id="cep" type="text"&gt;
  &lt;br/&gt;
  &lt;label for="logradouro"&gt;Logradouro&lt;/label&gt;
  &lt;input id="logradouro" type="text"&gt;
  &lt;br/&gt;
  &lt;label for="numero"&gt;Número&lt;/label&gt;
  &lt;input id="numero" type="text"&gt;
  &lt;br/&gt;
  &lt;label for="complemento"&gt;Complemento&lt;/label&gt;
  &lt;input id="complemento" type="text"&gt;
  &lt;br/&gt;
  &lt;label for="bairro"&gt;Bairro&lt;/label&gt;
  &lt;input id="bairro" type="text"&gt;
  &lt;br/&gt;
  &lt;label for="uf"&gt;Estado&lt;/label&gt;
  &lt;select id="uf"&gt;
    &lt;option value="AC"&gt;Acre&lt;/option&gt;
    &lt;option value="AL"&gt;Alagoas&lt;/option&gt;
    &lt;option value="AP"&gt;Amapá&lt;/option&gt;
    &lt;option value="AM"&gt;Amazonas&lt;/option&gt;
    &lt;option value="BA"&gt;Bahia&lt;/option&gt;
    &lt;option value="CE"&gt;Ceará&lt;/option&gt;
    &lt;option value="DF"&gt;Distrito Federal&lt;/option&gt;
    &lt;option value="ES"&gt;Espírito Santo&lt;/option&gt;
    &lt;option value="GO"&gt;Goiás&lt;/option&gt;
    &lt;option value="MA"&gt;Maranhão&lt;/option&gt;
    &lt;option value="MT"&gt;Mato Grosso&lt;/option&gt;
    &lt;option value="MS"&gt;Mato Grosso do Sul&lt;/option&gt;
    &lt;option value="MG"&gt;Minas Gerais&lt;/option&gt;
    &lt;option value="PA"&gt;Pará&lt;/option&gt;
    &lt;option value="PB"&gt;Paraíba&lt;/option&gt;
    &lt;option value="PR"&gt;Paraná&lt;/option&gt;
    &lt;option value="PE"&gt;Pernambuco&lt;/option&gt;
    &lt;option value="PI"&gt;Piauí&lt;/option&gt;
    &lt;option value="RJ"&gt;Rio de Janeiro&lt;/option&gt;
    &lt;option value="RN"&gt;Rio Grande do Norte&lt;/option&gt;
    &lt;option value="RS"&gt;Rio Grande do Sul&lt;/option&gt;
    &lt;option value="RO"&gt;Rondônia&lt;/option&gt;
    &lt;option value="RR"&gt;Roraima&lt;/option&gt;
    &lt;option value="SC"&gt;Santa Catarina&lt;/option&gt;
    &lt;option value="SP"&gt;São Paulo&lt;/option&gt;
    &lt;option value="SE"&gt;Sergipe&lt;/option&gt;
    &lt;option value="TO"&gt;Tocantins&lt;/option&gt;
  &lt;/select&gt;
&lt;/form&gt;
</pre>
<p>Como iremos aplicar a consulta após o usuário deixar o campo CNPJ, deveremos adicionar a chamada no focusout do CNPJ, ficando</p>
<pre class="prettyprint">&lt;script type="text/javascript"&gt;
	$("#cnpj").focusout(function(){
	//Aqui vai o código		
	});
&lt;/script&gt;</pre>
<p>Agora é bem simples. Basta usarmos o método Ajax, que já utilizamos em <a href="https://velhobit.com.br/programacao/implementando-a-integracao-entre-php-jquery-json.html">tutoriais anteriores para fazermos conexões</a>. O código abaixo possui diversos comentários para facilitar o entendimento de cada bloco.</p>
<pre class="prettyprint">&lt;script type="text/javascript"&gt;
	$("#cnpj").focusout(function(){
		//Início do Comando AJAX
		$.ajax({
			//O campo URL diz o caminho de onde virá os dados
			//É importante concatenar o valor digitado no CNPJ
			url: '/pasta/cnpj.php?cnpj='+$("#cnpj").val(),
//Atualização: caso use java, use cnpj.jsp, usando o outro exemplo.
			//Aqui você deve preencher o tipo de dados que será lido,
			//no caso, estamos lendo JSON.
			dataType: 'json',
			//SUCESS é referente a função que será executada caso
			//ele consiga ler a fonte de dados com sucesso.
			//O parâmetro dentro da função se refere ao nome da variável
			//que você vai dar para ler esse objeto.
			success: function(resposta){
				//Confere se houve erro e o imprime
				if(resposta.status == "ERROR"){
					alert(resposta.message + "\nPor favor, digite os dados manualmente.");
					$("#post #nome").focus().select();
					return false;
				}
				//Agora basta definir os valores que você deseja preencher
				//automaticamente nos campos acima.
				$("#post #nome").val(resposta.nome);
				$("#post #fantasia").val(resposta.fantasia);
				$("#post #atividade").val(resposta.atividade_principal[0].text + " (" + resposta.atividade_principal[0].code + ")");
				$("#post #telefone").val(resposta.telefone);
				$("#post #email").val(resposta.email);
				$("#post #logradouro").val(resposta.logradouro);
				$("#post #complemento").val(resposta.complemento);
				$("#post #bairro").val(resposta.bairro);
				$("#post #cidade").val(resposta.municipio);
				$("#post #uf").val(resposta.uf);
				$("#post #cep").val(resposta.cep);
				$("#post #numero").val(resposta.numero);
			}
		});
	});
&lt;/script&gt;</pre>
<p>Que tal agora testarmos o funcionamento?</p>
<p>Digite um CNPJ (apenas números) no campo CNPJ abaixo e depois saia dele (focusout), clicando em outro campo ou pressionando a tecla TAB de seu teclado.</p>
<form id="post" class="list-b"><label for="cnpj">CNPJ</label><br />
<input id="cnpj" required="" type="text"><label for="nome">Razão Social</label><br />
<input id="nome" type="text"><label for="fantasia">Nome Fantasia</label><br />
<input id="fantasia" type="text"><label for="atividade">Atividade Principal</label><br />
<input id="atividade" type="text"><label for="telefone">Telefone</label><br />
<input id="telefone" required="" type="text"><label for="email">E-mail</label><br />
<input id="email" type="text"><label for="cep">CEP</label><br />
<input id="cep" type="text"><label for="logradouro">Logradouro</label><br />
<input id="logradouro" type="text"><label for="numero">Número</label><br />
<input id="numero" type="text"><label for="complemento">Complemento</label><br />
<input id="complemento" type="text"><label for="bairro">Bairro</label><input id="bairro" type="text"><br />
<label for="cidade">Cidade</label><input id="cidade" type="text"><br />
<label for="uf">Estado</label><br />
<select id="uf"><option value="AC">Acre</option><option value="AL">Alagoas</option><option value="AP">Amapá</option><option value="AM">Amazonas</option><option value="BA">Bahia</option><option value="CE">Ceará</option><option value="DF">Distrito Federal</option><option value="ES">Espírito Santo</option><option value="GO">Goiás</option><option value="MA">Maranhão</option><option value="MT">Mato Grosso</option><option value="MS">Mato Grosso do Sul</option><option value="MG">Minas Gerais</option><option value="PA">Pará</option><option value="PB">Paraíba</option><option value="PR">Paraná</option><option value="PE">Pernambuco</option><option value="PI">Piauí</option><option value="RJ">Rio de Janeiro</option><option value="RN">Rio Grande do Norte</option><option value="RS">Rio Grande do Sul</option><option value="RO">Rondônia</option><option value="RR">Roraima</option><option value="SC">Santa Catarina</option><option value="SP">São Paulo</option><option value="SE">Sergipe</option><option value="TO">Tocantins</option></select></form>
<h4>&nbsp;</h4>
<p>&nbsp;</p>
<p><center>Baixe o exemplo no GitHub:<!-- Place this tag where you want the button to render. --><br />
<a class="github-button" href="https://github.com/velhobit/exemploCNPJ/archive/master.zip" data-icon="octicon-cloud-download" data-size="large" aria-label="Download velhobit/exemploCNPJ on GitHub">Download</a></center>É mais fácil do que parece, não é? Aproveite para compartilhar isso com seus amigos que estão estudando ou que essa informação possa ser útil <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f44d.png" alt="👍" class="wp-smiley" style="height: 1em; max-height: 1em;" />. Aproveite e deixe um like na <a href="https://www.facebook.com/velhobit/">nova página da Velhobit, no Facebook</a>.</p>
<p>&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://velhobit.com.br/programacao/carregando-dinamicamente-dados-empresa-cnpj-php-jquery.html/feed</wfw:commentRss>
			<slash:comments>17</slash:comments>
		
		
			</item>
		<item>
		<title>Como preencher o Endereço Automaticamente a Partir do CEP?</title>
		<link>https://velhobit.com.br/programacao/carregando-cep-cidades-dinamicamente.html</link>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Wed, 05 Jul 2017 22:49:36 +0000</pubDate>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[busca cep]]></category>
		<category><![CDATA[buscar]]></category>
		<category><![CDATA[cep]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">https://bitcolor.com.br/?p=613</guid>

					<description><![CDATA[Uma ótima forma de otimizar a experiência do usuário e trazer maior integridade nos dados, é carregar os dados de endereço dinamicamente a partir do CEP.]]></description>
										<content:encoded><![CDATA[<p>Para melhorar a experiência do usuário, <a href="https://velhobit.com.br/servicos/design-ux-experiencia-usuario-front-end.html">profissionais front-end</a> costumam buscar formas de automatizar certos preenchimentos de cadastros. Além disso, essas formas de carregamento trazem mais integridade para os dados, diminuindo ou evitando a digitação errada de campos que podem vir a ser usados em busca. Sem dúvida, um dos carregamentos dinâmicos mais usados em cadastros é a busca automática por CEP.</p>
<p>Para este exemplo/tutorial, iremos usar <a href="https://velhobit.com.br/programacao/implementando-a-integracao-entre-php-jquery-json.html">jQuery e HTML</a>.</p>
<h2>Carregando o Endereço Dinamicamente pelo CEP</h2>
<p>Talvez o mais famoso repositório público para preenchimento de CEP (sem a necessidade de uma integração com os Correios), deve ser o <a href="https://viacep.com.br" target="_blank" rel="noopener">ViaCEP</a>.</p>
<p>A API do ViaCEP possui uma integração com json, que é o que usaremos aqui.</p>
<p>O ViaCEP nos retorno os seguintes dados, com as respectivas chaves:</p>
<ul>
<li><strong>&#8220;cep&#8221;,</strong></li>
<li><strong>&#8220;logradouro&#8221;,</strong></li>
<li><strong>&#8220;complemento&#8221;,</strong></li>
<li><strong>&#8220;bairro&#8221;,</strong></li>
<li><strong>&#8220;localidade&#8221;,</strong></li>
<li><strong>&#8220;uf&#8221;,</strong></li>
<li><strong>&#8220;unidade&#8221;,</strong></li>
<li><strong>&#8220;ibge&#8221;,</strong></li>
<li><strong>&#8220;gia&#8221;</strong></li>
</ul>
<p>Para exemplificarmos, vamos usar um formulário HTML simples: (Usaremos a base de estados capturado a partir do <a href="https://gist.github.com/cassiocardoso/8966749" target="_blank" rel="noopener">GitHub de Cassio Cardoso</a>)</p>
<pre class="prettyprint">&lt;!--Importando Script Jquery--&gt;
&lt;script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"&gt;&lt;/script&gt;

&lt;!--Formulário--&gt;
&lt;form&gt;
&lt;label for="cep"&gt;CEP&lt;/label&gt;
		&lt;input id="cep" type="text" required/&gt;
&lt;label for="logradouro"&gt;Logradouro&lt;/label&gt;
		&lt;input id="logradouro" type="text" required/&gt;
&lt;label for="numero"&gt;Número&lt;/label&gt;
		&lt;input id="numero" type="text" /&gt;
&lt;label for="complemento"&gt;Complemento&lt;/label&gt;
		&lt;input id="complemento" type="text"/&gt;
&lt;label for="bairro"&gt;Bairro&lt;/label&gt;
		&lt;input id="bairro" type="text" required/&gt;
&lt;label for="uf"&gt;Estado&lt;/label&gt;
		&lt;select id="uf"&gt;
			&lt;option value="AC"&gt;Acre&lt;/option&gt;
			&lt;option value="AL"&gt;Alagoas&lt;/option&gt;
			&lt;option value="AP"&gt;Amapá&lt;/option&gt;
			&lt;option value="AM"&gt;Amazonas&lt;/option&gt;
			&lt;option value="BA"&gt;Bahia&lt;/option&gt;
			&lt;option value="CE"&gt;Ceará&lt;/option&gt;
			&lt;option value="DF"&gt;Distrito Federal&lt;/option&gt;
			&lt;option value="ES"&gt;Espírito Santo&lt;/option&gt;
			&lt;option value="GO"&gt;Goiás&lt;/option&gt;
			&lt;option value="MA"&gt;Maranhão&lt;/option&gt;
			&lt;option value="MT"&gt;Mato Grosso&lt;/option&gt;
			&lt;option value="MS"&gt;Mato Grosso do Sul&lt;/option&gt;
			&lt;option value="MG"&gt;Minas Gerais&lt;/option&gt;
			&lt;option value="PA"&gt;Pará&lt;/option&gt;
			&lt;option value="PB"&gt;Paraíba&lt;/option&gt;
			&lt;option value="PR"&gt;Paraná&lt;/option&gt;
			&lt;option value="PE"&gt;Pernambuco&lt;/option&gt;
			&lt;option value="PI"&gt;Piauí&lt;/option&gt;
			&lt;option value="RJ"&gt;Rio de Janeiro&lt;/option&gt;
			&lt;option value="RN"&gt;Rio Grande do Norte&lt;/option&gt;
			&lt;option value="RS"&gt;Rio Grande do Sul&lt;/option&gt;
			&lt;option value="RO"&gt;Rondônia&lt;/option&gt;
			&lt;option value="RR"&gt;Roraima&lt;/option&gt;
			&lt;option value="SC"&gt;Santa Catarina&lt;/option&gt;
			&lt;option value="SP"&gt;São Paulo&lt;/option&gt;
			&lt;option value="SE"&gt;Sergipe&lt;/option&gt;
			&lt;option value="TO"&gt;Tocantins&lt;/option&gt;
		&lt;/select&gt;
&lt;/form&gt;</pre>
<p>Agora vamos executar uma função para que no momento após sair do campo CEP, ele faça a busca e preencha os demais campos. Como é no momento após deixar o campo, iremos vincular ao evento <strong><em>focusout</em></strong>.</p>
<pre class="prettyprint">&lt;script type="text/javascript"&gt;
	$("#cep").focusout(function(){
	//Aqui vai o código		
	});
&lt;/script&gt;</pre>
<p>Agora temos que chamar a API json dentro da nossa função. Para isso, vamos utilizar o comando $.ajax, do jQuery.</p>
<p><em><strong>Obs. Acompanhe os comentários no código para entender cada linha.</strong></em></p>
<pre class="prettyprint">&lt;script type="text/javascript"&gt;
	$("#cep").focusout(function(){
		//Início do Comando AJAX
		$.ajax({
			//O campo URL diz o caminho de onde virá os dados
			//É importante concatenar o valor digitado no CEP
			url: 'https://viacep.com.br/ws/'+$(this).val()+'/json/unicode/',
			//Aqui você deve preencher o tipo de dados que será lido,
			//no caso, estamos lendo JSON.
			dataType: 'json',
			//SUCESS é referente a função que será executada caso
			//ele consiga ler a fonte de dados com sucesso.
			//O parâmetro dentro da função se refere ao nome da variável
			//que você vai dar para ler esse objeto.
			success: function(resposta){
				//Agora basta definir os valores que você deseja preencher
				//automaticamente nos campos acima.
				$("#logradouro").val(resposta.logradouro);
				$("#complemento").val(resposta.complemento);
				$("#bairro").val(resposta.bairro);
				$("#cidade").val(resposta.localidade);
				$("#uf").val(resposta.uf);
				//Vamos incluir para que o Número seja focado automaticamente
				//melhorando a experiência do usuário
				$("#numero").focus();
			}
		});
	});
&lt;/script&gt;</pre>
<p>Simples, não é?</p>
<p>Essa mesma lógica você pode usar para poder dinamicamente diversos outros tipos de dados, inclusive alguns vindo do banco. Se quiser saber mais como usar o <a href="https://velhobit.com.br/programacao/implementando-a-integracao-entre-php-jquery-json.html">Json com PHP e jQuery, assista nosso vídeo tutorial sobre o assunto</a>.</p>
<p>Vamos testar e ver como fica:</p>
<p><!--Formulário--></p>
<form><label for="cep">CEP</label><br />
<input id="cep" required="" type="text" /><br />
<label for="logradouro">Logradouro</label><br />
<input id="logradouro" required="" type="text" /><br />
<label for="numero">Número</label><br />
<input id="numero" type="text" /><br />
<label for="complemento">Complemento</label><br />
<input id="complemento" type="text" /><br />
<label for="bairro">Bairro</label><br />
<input id="bairro" required="" type="text" /><br />
<label for="uf">Estado</label><br />
<select id="uf"><option value="AC">Acre</option><option value="AL">Alagoas</option><option value="AP">Amapá</option><option value="AM">Amazonas</option><option value="BA">Bahia</option><option value="CE">Ceará</option><option value="DF">Distrito Federal</option><option value="ES">Espírito Santo</option><option value="GO">Goiás</option><option value="MA">Maranhão</option><option value="MT">Mato Grosso</option><option value="MS">Mato Grosso do Sul</option><option value="MG">Minas Gerais</option><option value="PA">Pará</option><option value="PB">Paraíba</option><option value="PR">Paraná</option><option value="PE">Pernambuco</option><option value="PI">Piauí</option><option value="RJ">Rio de Janeiro</option><option value="RN">Rio Grande do Norte</option><option value="RS">Rio Grande do Sul</option><option value="RO">Rondônia</option><option value="RR">Roraima</option><option value="SC">Santa Catarina</option><option value="SP">São Paulo</option><option value="SE">Sergipe</option><option value="TO">Tocantins</option></select></form>
<p>Abaixo, você pode ver o código completo:</p>
<pre class="prettyprint">&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;title&gt;Teste&lt;/title&gt;
&lt;/head&gt;

&lt;body&gt;
	&lt;!--Importando Script Jquery--&gt;
	&lt;script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"&gt;&lt;/script&gt;

	&lt;!--Formulário--&gt;
	&lt;form&gt;
		&lt;label for="cep"&gt;CEP&lt;/label&gt;
		&lt;input id="cep" type="text" required/&gt;
		&lt;label for="logradouro"&gt;Logradouro&lt;/label&gt;
		&lt;input id="logradouro" type="text" required/&gt;
		&lt;label for="numero"&gt;Número&lt;/label&gt;
		&lt;input id="numero" type="text" /&gt;
		&lt;label for="complemento"&gt;Complemento&lt;/label&gt;
		&lt;input id="complemento" type="text"/&gt;
		&lt;label for="bairro"&gt;Bairro&lt;/label&gt;
		&lt;input id="bairro" type="text" required/&gt;
		&lt;label for="uf"&gt;Estado&lt;/label&gt;
		&lt;select id="uf"&gt;
			&lt;option value="AC"&gt;Acre&lt;/option&gt;
			&lt;option value="AL"&gt;Alagoas&lt;/option&gt;
			&lt;option value="AP"&gt;Amapá&lt;/option&gt;
			&lt;option value="AM"&gt;Amazonas&lt;/option&gt;
			&lt;option value="BA"&gt;Bahia&lt;/option&gt;
			&lt;option value="CE"&gt;Ceará&lt;/option&gt;
			&lt;option value="DF"&gt;Distrito Federal&lt;/option&gt;
			&lt;option value="ES"&gt;Espírito Santo&lt;/option&gt;
			&lt;option value="GO"&gt;Goiás&lt;/option&gt;
			&lt;option value="MA"&gt;Maranhão&lt;/option&gt;
			&lt;option value="MT"&gt;Mato Grosso&lt;/option&gt;
			&lt;option value="MS"&gt;Mato Grosso do Sul&lt;/option&gt;
			&lt;option value="MG"&gt;Minas Gerais&lt;/option&gt;
			&lt;option value="PA"&gt;Pará&lt;/option&gt;
			&lt;option value="PB"&gt;Paraíba&lt;/option&gt;
			&lt;option value="PR"&gt;Paraná&lt;/option&gt;
			&lt;option value="PE"&gt;Pernambuco&lt;/option&gt;
			&lt;option value="PI"&gt;Piauí&lt;/option&gt;
			&lt;option value="RJ"&gt;Rio de Janeiro&lt;/option&gt;
			&lt;option value="RN"&gt;Rio Grande do Norte&lt;/option&gt;
			&lt;option value="RS"&gt;Rio Grande do Sul&lt;/option&gt;
			&lt;option value="RO"&gt;Rondônia&lt;/option&gt;
			&lt;option value="RR"&gt;Roraima&lt;/option&gt;
			&lt;option value="SC"&gt;Santa Catarina&lt;/option&gt;
			&lt;option value="SP"&gt;São Paulo&lt;/option&gt;
			&lt;option value="SE"&gt;Sergipe&lt;/option&gt;
			&lt;option value="TO"&gt;Tocantins&lt;/option&gt;
		&lt;/select&gt;
	&lt;/form&gt;
	
	&lt;script type="text/javascript"&gt;
		$("#cep").focusout(function(){
			//Início do Comando AJAX
			$.ajax({
				//O campo URL diz o caminho de onde virá os dados
				//É importante concatenar o valor digitado no CEP
				url: 'https://viacep.com.br/ws/'+$(this).val()+'/json/unicode/',
				//Aqui você deve preencher o tipo de dados que será lido,
				//no caso, estamos lendo JSON.
				dataType: 'json',
				//SUCESS é referente a função que será executada caso
				//ele consiga ler a fonte de dados com sucesso.
				//O parâmetro dentro da função se refere ao nome da variável
				//que você vai dar para ler esse objeto.
				success: function(resposta){
					//Agora basta definir os valores que você deseja preencher
					//automaticamente nos campos acima.
					$("#logradouro").val(resposta.logradouro);
					$("#complemento").val(resposta.complemento);
					$("#bairro").val(resposta.bairro);
					$("#cidade").val(resposta.localidade);
					$("#uf").val(resposta.uf);
					//Vamos incluir para que o Número seja focado automaticamente
					//melhorando a experiência do usuário
					$("#numero").focus();
				}
			});
		});
	&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Rodando sua Primeira Aplicação C no Windows ou Linux</title>
		<link>https://velhobit.com.br/programacao/rodando-sua-primeira-aplicacao-c-no-windows-ou-linux.html</link>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Mon, 20 Mar 2017 15:41:24 +0000</pubDate>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[compilação]]></category>
		<category><![CDATA[compilador]]></category>
		<category><![CDATA[editor de texto]]></category>
		<category><![CDATA[executavel]]></category>
		<category><![CDATA[g]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[linha de comando]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[programação]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[windows]]></category>
		<guid isPermaLink="false">https://bitcolor.com.br/?p=246</guid>

					<description><![CDATA[Esta postagem é um complemento da linguagem C e programação. Através do ensinamento de como compilar o seu próprio código por linha de comando.]]></description>
										<content:encoded><![CDATA[<p>Sem dúvida uma das melhores linguagens para se começar a programar é C. Uma linguagem baixo nível, que dá para entender bem todos os conceitos de programação, tipos, etc. Uma linguagem procedural e que é utilizada até hoje em diversos softwares modernos, como o Photoshop, o OpenGL, o AutoCAD, dentre outros</p>
<p>Esta postagem é um complemento ao entendimento bem básico de C e programação.</p>
<p>C é uma linguagem de programação que precisa ser compilada, isto é, ela precisa ser transformada em um conjunto de códigos que a máquina interpretará para, então, criar um executável. Para fazer isso, a linguagem precisa de um compilador, que é um software que faz esse processado.</p>
<p style="color: #078c7a;"><em>Obs. C é considerada uma linguagem auto-hospedada, pois com ela é possível criar o próprio compilador. Essa característica também é conhecida como linguagem completa.</em></p>
<p>Primeiramente, você vai precisar do seu código. Porém, antes de começar, precisamos passar por um pequeno glossário para que não haja confusões acerca de termos:</p>
<ul>
<li><strong>I/O</strong> &#8211; Denomina-se I/O sistemas que fazem uso intensivo de entrada e saída de dados. I = input, O = output. Dentro da área de computação, a terminação I/O também é usada muito para expressar tecnologias novas de implementação.</li>
<li><strong>Editor de Texto</strong> &#8211; Na área de desenvolvimento é chamado de editor de texto qualquer programa onde você possa programar um código. Geralmente, editores de texto possuem <em>auto-complete</em>, que são dicas que ajudam a programar. Como exemplos temos o Notepad++, o Brackets, o Atom, etc.</li>
<li><strong>IDE</strong> &#8211; Ambiente de Desenvolvimento Integrado. Trata-se de uma ferramenta para desenvolvimento mais ampla do que um editor de texto. Além de inserir um contexto de projeto e não só de arquivos de texto editáveis, a IDE cuida da comunicação interna entre os elementos do código. Ou seja, é um ambiente completo para o desenvolvimento. Como exemplos temos o Eclipse, o JetBrains, o Visual Studio, o Coda, etc.</li>
<li><strong>Compilador</strong> &#8211; O compilador é um programa que transforma o seu código em algo que possa ser interpretado pela máquina. Os microcontroladores compreendem apenas bytecodes, ou outras linguagens de baixo nível indicadas em seus firmwares, de modo que se faz necessário converter o seu código para algo que a máquina entenda.</li>
<li><strong>Variável</strong> &#8211; Trata-se de um lugar que você reserva em sua memória para poder armazenar um dado, como um número, um caractere, etc.</li>
<li><strong>Função</strong> &#8211; É simplesmente um trecho de código com o propósito de executar um procedimento e, geralmente, retornar uma informação.</li>
</ul>
<p>Outros termos poderemos ver em artigos futuros.</p>
<p>Para quem ainda está começando com programação, vamos deixar aqui abaixo um código, onde cada ponto de explicação está incluído como comentário.</p>
<pre class="prettyprint">#include &lt;stdio.h&gt;
// ^ Isto é uma diretiva. Ela serve para poder importar uma biblioteca externa
// (no caso, uma nativa do C conhecida como Standard I/O).
// As importações de bibliotecas devem ser a primeira coisa a ser declarada.
// O # simboliza que isso acontecerá antes de qualquer coisa ser executada pelo programa.

// Isto é um comentário. Você pode colocar duas barras
// no meio de um código e o compilador irá pular essa linha ou trecho
/* Você também pode usar /*, caso você queira
fazer um comentário com mais de uma linha.
Todavia, você precisa fechar com */

/**
 * Toda a aplicação em C deve ter uma função main() (principal).
 * Você deve ter reparado que este comentário está com uma cor diferente.
 * Convencionou-se que os comentários, antes de funções, devem ser feitos
 * com /** (Isso se chama Comentário de Cabeçalho). Isso indica a IDE que este
 * comentário descreve para quê serve
 * esta função. Isso acaba sendo incorporado a documentação do projeto
 * ou a dica de código mostrado por uma IDE. Você ainda pode usar
 * alguns parâmetros para indicar.
 * Colocar comentários, como este, não é obrigatório, mas faz parte de boas práticas,
 * pois você precisa lembrar o que esta função faz (e certamente, no futuro, você esquecerá),
 * ou indicar a um colega, como usar a função.
 * Por exemplo, esta função (também chamada de método), retorna um inteiro.
 * Logo, eu posso digitar:
 * RETURN :
 *            Type:   int   Resulta zero
 * Isso indicará a IDE e a documentação que a função retornará um inteiro.
 * Essa indicação de comentário de cabeçalho pode variar entre IDEs e linguagens.
 * */
int main() //A primeira palavra indica o que a função retorna, ou seja, a função,
// deve retornar um inteiro. Em seguida, coloca-se o nome da função, seguido de ().
{//Inicia a função (também conhecido como begin)

    int aInt = calcular(88,32); // uma variável do tipo inteiro
                                //(o nome aInt fui eu quem dei), que vai ser preenchido com o
                                //retorno da função calcular (veja abaixo)
    
    char str[15]; //uma variável do tipo caractere que eu chamei de str.
                  //O [15] significa que ela poderá ter até 15 caracteres.
                  //Vocês ainda vão entender o conceito de vetores.
    
    sprintf (str, "%d", aInt); //sprintf é uma função nativa do C que serve
                               //para transformar inteiros em caracteres,
                               //pois só posso imprimir caracteres no console (ou no dispositivo de saída).
    
    str[15] = strcat(str,"\n");//strcat é uma função nativa do C que serve para concatenar.
                               //Ou seja, juntar uma String (conjunto de caracteres) com outra.
                               //A String (que significa amarra em tradução livre, ou seja, uma amarra de caracteres)
                               //"\n" é um modo de dizer ao compilador que ele deve colocar uma quebra de linha
                               // Usar \n é algo padronizado como quebra de linha em qualquer tipo de texto plano.
                               // Lembrando que quebra de linha seria o equivalente a dar um CTRL+ENTER, em um texto comum.
    printf(str); //printf é uma função nativa do C que serve para mostrar (imprimir)
                 //algo no dispositivo de saída, no caso, no console abaixo.

    return 0; //O retorno da função.
              //Como a função diz que retorna um inteiro (lá no começo da função),
              //ela DEVE retornar um inteiro.
              //Caso você não retorne o inteiro, ela NÃO irá compilar, pois você prometeu que ela retornaria isso.
}//Finaliza a função (também conhecido como end)

/**
 * Você vai notar que esta função que eu criei, tem uma peculiaridade.
 * Repare que dentro dos parênteses há duas variáveis inteiras.
 * Essas variáveis se chamam parâmetros. Elas servem para que a função possa ser reaproveitada
 * a partir de outros termos que serão chamados acima.
 * Repare, em main(), que eu chamo calcular(88,32), mas você pode mudar para qualquer outro número inteiro.
 * O que o método (ou função), fará é calcular os dois valores que você colocar nos parâmetros.
 * No caso de C, se você não colocar os dois valores, ao chamar a função, o compilador falhará.
 * 
 * * INPUTS :
 *       PARAMETERS:
 *           int     valor                Primeiro somando
 *           int     valor2               Segundo somando
 */
int calcular(int valor, int valor2)
{
    int total = valor + valor2; //uma variável inteiro, chamada total, que retorna a soma dos parâmetros valor e valor 2;
    return total; //O retorno do método será um inteiro (como foi descrito no começo do mesmo).
    //Em main(), você pode ver que o retorno deste método retorna uma variável. 
}</pre>
<p>Você pode simplesmente copiar e colar o código acima em um editor de texto qualquer (como os citados acima). Você pode usar até mesmo o bloco de notas do Windows, ou o Gedit, no Linux. Em, seguida, salve o arquivo com o nome que você quiser, porém, com a extensão .c, por exemplo: <strong><em>meucodigo.c</em></strong>.</p>
<h2>Compilando C, no Windows</h2>
<p>Para poder compilar em C, no Windows, usaremos uma ferramenta de código aberto chamada <a href="http://www.mingw.org/">MinGW</a> (caso deseje testar, pode usar a <a href="https://sourceforge.net/projects/mingw-w64/">versão 64 bits do MinGW</a>, porém a versão 32 é compatível com ambos os sistemas). Ao instalar você pode escolher algumas especificações e se quer ou não que ela opere em modo visual (em janela), além da integração com o Explorer.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-248" src="https://velhobit.com.br/wp-content/uploads/2017/03/ming_compilador_windows.jpg" alt="" width="601" height="464" srcset="https://velhobit.com.br/wp-content/uploads/2017/03/ming_compilador_windows.jpg 601w, https://velhobit.com.br/wp-content/uploads/2017/03/ming_compilador_windows-400x309.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/03/ming_compilador_windows-600x463.jpg 600w" sizes="auto, (max-width: 601px) 100vw, 601px" /></p>
<p>Uma vez instalado o MinGW, você precisará selecionar o mingw32-base e mingw32-gcc-g++, pois ele é o compilador C / C++ para podermos trabalhar. Depois disso, basta ir no menu Installation e clicar em Apply Changes e, em seguida, no botão Apply. Ele irá instalar todos os arquivos do compilador que serão necessários para nosso teste.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-249" src="https://velhobit.com.br/wp-content/uploads/2017/03/ming_gcc.jpg" alt="" width="1017" height="301" srcset="https://velhobit.com.br/wp-content/uploads/2017/03/ming_gcc.jpg 1017w, https://velhobit.com.br/wp-content/uploads/2017/03/ming_gcc-400x118.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/03/ming_gcc-768x227.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/03/ming_gcc-600x178.jpg 600w" sizes="auto, (max-width: 1017px) 100vw, 1017px" /></p>
<p>Após concluída a instalação, já podemos usar o compilador.</p>
<p>Para poder compilar o seu arquivo, simplesmente abra o prompt de comando (cmd.exe), do Windows e vá na pasta do MinGW, localizada geralmente em C:\ (ou onde você preferiu instalar). Na dúvida basta digitar o código abaixo:</p>
<pre class="prettyprint">cd C:\MinGW\bin</pre>
<p>Em seguida, vamos chamar o compilador e o arquivo que queremos que ele compile. Para isso, basta digitar o nome do compilador, o arquivo a ser compilado, o parâmetro do comando, e o nome final do programa.</p>
<p>No caso, teremos:</p>
<p>gcc meucodigo.c -o meuprograma.exe</p>
<p>Onde gcc é o processo (o compilador), meucodigo.c é o código fonte, o parâmetro -o significa que eu estou indicando qual é a saída e o meuprograma.exe indica o nome final do programa compilado.</p>
<p>No meu caso, como criei meu código fonte e o salvei dentro de Documentos, eu coloquei:</p>
<pre class="prettyprint">gcc C:\Users\rodri\Documents\meucodigo.c -o C:\Users\rodri\Documents\meuprograma.exe</pre>
<p>Como é um pouco chato lembrar e até digitar todo o caminho, uma dica é arrastar o arquivo para dentro do prompt de comando, isso fará com que ele cole o caminho do arquivo.</p>
<p><video style="width: 100%; height: auto;" autoplay="autoplay" loop="loop" width="300" height="150"><source src="https://velhobit.com.br/wp-content/uploads/2017/03/gcc.mp4" type="video/mp4" /></video></p>
<p>Devido a quantidade enorme de comentários e observações no código, é bem provável que ele retorne alguns Warnings (alertas), ao compilar, mas não dará erro. Você poderá testar o resultado do seu programa simplesmente digitando o nome do executável no prompt de comando.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-252" src="https://velhobit.com.br/wp-content/uploads/2017/03/programa-executado.jpg" alt="" width="605" height="127" srcset="https://velhobit.com.br/wp-content/uploads/2017/03/programa-executado.jpg 605w, https://velhobit.com.br/wp-content/uploads/2017/03/programa-executado-400x84.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/03/programa-executado-600x126.jpg 600w" sizes="auto, (max-width: 605px) 100vw, 605px" /></p>
<h2>Compilando C, no Linux</h2>
<p>Para compilar C, no Linux, é ainda mais simples do que no Windows. Dependendo da distribuição do Linux que você utilizar é possível até que já haja um compilador instalado. Vamos utilizar, no exemplo, a compilação de C em uma distribuição Debian, como o Ubuntu ou CentOS, por se tratar de distribuições muito usadas.</p>
<p>Abra o terminal do Linux e digite:</p>
<pre class="prettyprint">sudo apt-get update</pre>
<p>Para quem é novo no Linux, o <strong><em>sudo</em> </strong>é um comando que afirma que você vai executar como super usuário, ou seja, com acesso completo ao sistema operacional, e, por isso, ele deverá te pedir a senha. Já o <strong><em>apt-get update</em> </strong>serve para atualizar o repositório (fonte de sistemas), de sua distribuição Linux.</p>
<p>Em seguida, basta digitar o comando:</p>
<pre class="prettyprint">sudo apt-get install build-essential</pre>
<p>Esse comando serve para pedir para que seja instalado os elementos principais para compilação de diversas linguagens usadas pelo Linux, inclusive C, assim como todas os seus pacotes de dependências (bibliotecas necessárias para o funcionamento).</p>
<p>Agora vá até a pasta onde você salvou o arquivo do código, no meu caso está em <em>/mnt/c/Users/rodri/Documents/</em>.</p>
<p>Para compilar basta colocarmos:</p>
<pre class="prettyprint">gcc meucodigo.c -o meuprograma.out</pre>
<p>Onde gcc é o processo (o compilador), meucodigo.c é o código fonte, o parâmetro -o significa que eu estou indicando qual é a saída e o meuprograma.exe indica o nome final do programa compilado.</p>
<p>Já para executarmos o programa, dentro do terminal, digitaremos:</p>
<pre class="prettyprint">./meuprograma.out</pre>
<p>&#8230; e voilà<br />
<img loading="lazy" decoding="async" class="alignnone size-full wp-image-254" src="https://velhobit.com.br/wp-content/uploads/2017/03/compilado-c-linux.jpg" alt="" width="566" height="97" srcset="https://velhobit.com.br/wp-content/uploads/2017/03/compilado-c-linux.jpg 566w, https://velhobit.com.br/wp-content/uploads/2017/03/compilado-c-linux-400x69.jpg 400w" sizes="auto, (max-width: 566px) 100vw, 566px" /></p>
<h2>Concluindo</h2>
<p>C é uma linguagem muito boa para quem está começando a programar ou está ainda entrando no mundo da tecnologia. Compilar por linha de comando te ajuda a ter uma base ainda melhor para compreender como funciona a compilação de uma linguagem e te dá mais liberdade para usar qualquer compilador, IDE ou editor de texto que você prefira e se adapte.</p>
<p>Para dar o exemplo no Ubuntu foi usado o Bash do Ubuntu disponível para Windows 10, todavia vai funcionar sem problemas em qualquer distribuição Linux, baseada em Debian, seja em máquina virtual ou em instalação normal. Se você quer saber como instalar o<a href="https://velhobit.com.br/tutoriais/como-rodar-bash-ubuntu-windows-10.html"> Bash do Ubuntu no Windows 10, acesse nosso artigo a respeito</a>.</p>
]]></content:encoded>
					
		
		<enclosure url="https://velhobit.com.br/wp-content/uploads/2017/03/gcc.mp4" length="0" type="video/mp4" />

			</item>
		<item>
		<title>Quanto Custa Ser Programador?</title>
		<link>https://velhobit.com.br/programacao/quanto-custa-ser-programador.html</link>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Thu, 19 Jan 2017 21:31:00 +0000</pubDate>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[conhecimentos]]></category>
		<category><![CDATA[cursos]]></category>
		<category><![CDATA[custo]]></category>
		<category><![CDATA[estudos]]></category>
		<category><![CDATA[preço]]></category>
		<category><![CDATA[profissão]]></category>
		<category><![CDATA[programador]]></category>
		<category><![CDATA[salário]]></category>
		<guid isPermaLink="false">https://bitcolor.com.br/?p=39</guid>

					<description><![CDATA[Programador de verdade está sempre trabalhando, sempre estudando, sempre se esforçando. E isso tem seu custo. Ser programador também é uma profissão cara.]]></description>
										<content:encoded><![CDATA[<p><em><strong>Obs. Este artigo foi originalmente escrito no começo de 2014. Foi atualizado recentemente para a realidade de 2017.</strong></em></p>
<p>Programador é o profissional responsável por resolver, replicar ou adequar soluções de software a fim de que um computador ou equipamento eletrônico com micro-controladores, execute uma tarefa.</p>
<p>O principal custo do programador é, sem dúvida, em educação. Porém, ainda sim, é bem variável, pois baseia-se nas tecnologias que este deseja se especializar.</p>
<p>O lado positivo é que muitas ferramentas para programadores são gratuitas, como o Brackets, Notepad++, assim como muitas linguagens, como o PHP, Java, C e outras.</p>
<h2>Educação</h2>
<p>Desenvolvedores precisam investir muito, muito mesmo, em livros e livros de tecnologia não são nada baratos. Dificilmente é possível encontrar um livro intermediário por menos de <del>200 reais</del> 250 reais.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-41" src="https://velhobit.com.br/wp-content/uploads/2017/01/livros-programacao.jpg" alt="Livros de Programação em Livraria" width="900" height="506" srcset="https://velhobit.com.br/wp-content/uploads/2017/01/livros-programacao.jpg 900w, https://velhobit.com.br/wp-content/uploads/2017/01/livros-programacao-400x225.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/01/livros-programacao-768x432.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/01/livros-programacao-600x337.jpg 600w" sizes="auto, (max-width: 900px) 100vw, 900px" /></p>
<p>Faculdades são um problema à parte. Apesar de várias faculdades de tecnologia aparecerem no país, a maioria focada em desenvolvimento não estão preparadas para preparar um aluno ao mercado de trabalho. Na própria faculdade, muitas vezes, possuem definições distorcidas de lógica e metodologias que não se adequam àqueles que já possuem intimidade com o computador, além de simplesmente ignorar assuntos como história e sociedade. Isso obriga a, mesmo os formados, procurarem especializações mais específicas para suas áreas, o que não é um negócio muito barato. Como é muito comum professores darem preferência a uma linguagem específica ao invés da lógica como um todo, muitos alunos, para conhecerem outras tecnologias, alternativas e métodos, precisam investir em cursos de especialização.</p>
<p>Boas faculdades particulares de tecnologia tem seu custo médio variável entre <del>300 a 1500 reais</del> 750 a 2000 reais por mês. Sendo que cursos de especialização ou específicos, tem seu custo em média de 900 a 3 mil reais por curso, podendo ter alguns mais baratos se vinculados a cursos de extensão de faculdades (principalmente as públicas). Algumas palestras e workshops, com pessoas importantes na área, podem também chegar ao valor equivalente a um curso.</p>
<h2>Certificação</h2>
<p>A certificação é uma prova, muitas vezes mais importante do que um diploma, de que o desenvolvedor tem domínio em uma determinada área ou ferramenta. Geralmente atrelado a uma tecnologia/linguagem específica, a certificação é bem aceita no mercado de trabalho e envolve testes realmente difíceis para passar. As certificações podem variar de <del>800 a 30 mil reais</del> 1500 a 40 mil reais, dependendo da área escolhida e se esta virá ou não acompanhada de um curso. Geralmente, quando se falha na prova, é necessário pagar novamente para uma segunda tentativa.</p>
<h2>Máquina</h2>
<p>A potência da máquina do programador varia da linguagem em que ele desenvolve e o objetivo de sua aplicação. Se ele optar por se especializar em PHP ou ASP, certamente ele não precisará de um computador que seja tão rápido. Entretanto, se ele trabalhar com Java, por exemplo, ele precisará ter um computador com pelo menos <del>4GB</del> 8GB de RAM (pois é&#8230; Java tá pesado). Já aqueles que trabalham com desenvolvimento de jogos ou de aplicativos pesados que exijam opções gráficas, simulação ou alta precisão, precisarão de um computador realmente caro, na faixa dos <del>8 a 15 mil reais</del> 10 a 21 mil, que possui uma configuração mais robusta. Se ele trabalhar com servidores, além de ter que ter mais de um, ele gastará uma quantia considerável para estudos e testes destes.</p>
<h2>Comunicação</h2>
<p>Grande parte de soluções e pesquisas podem ser encontradas na internet. O que exige que o programador tenha uma conexão realmente rápida. Hoje em dia, um profissional de TI precisa de uma conexão de pelo menos 20Mbps, o que gera um custo bem maior em comparação a quem tem uma internet comum em casa, e isso pode variar de região do país. Os que trabalham com gerenciamento de servidores a distância gastam muito mais, pois precisam de uma conexão ainda mais rápida para configurar e operar os mesmos sem perda de tempo ou informação. Ligações constantes para dar assistência a programadores e operadores também é comum, o que faz ter um alto custo com telefonia celular e fixa.</p>
<p>É difícil prever os custos exatos para comunicação. Os preços mudam muito de uma região do país para outras. Até mesmo de bairro para bairro o preço e velocidade máxima de conexão é absurdamente diferente.</p>
<h2>Eventos</h2>
<p>Como todo o profissional, o programador precisa estar atualizado com as últimas novidades de sua área. Precisa participar de eventos e promover encontros com outros desenvolvedores para criar melhores ações e estratégias para resolver seus problemas.</p>
<p>Porém eventos custam dinheiro principalmente para quem não mora no eixo sul do país, onde estão concentrados a maioria dos encontros. O problema é que, muitas vezes, não são as empresas que enviam os funcionários. Os programadores precisam pedir licença e custear do próprio bolso.</p>
<p>Na melhor das hipóteses, o custo para uma viagem não é menor que 2 mil reais (caso você seja alguém bem econômico e não se importe em dormir em albergues ou <em>Airbnb</em>), se for para uma cidade próxima. Caso seja internacional, prepare-se para um custo na faixa dos 12 mil reais.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-42" src="https://velhobit.com.br/wp-content/uploads/2017/01/jornada-adobe-2013.jpg" alt="Imagem de datashow falando sobre programação, da Adobe" width="1586" height="839" srcset="https://velhobit.com.br/wp-content/uploads/2017/01/jornada-adobe-2013.jpg 1586w, https://velhobit.com.br/wp-content/uploads/2017/01/jornada-adobe-2013-400x212.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/01/jornada-adobe-2013-768x406.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/01/jornada-adobe-2013-1024x542.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/01/jornada-adobe-2013-600x317.jpg 600w" sizes="auto, (max-width: 1586px) 100vw, 1586px" /></p>
<h2>E quanto ganha um programador?</h2>
<p>Isso varia muito, de acordo com a região do país e de empresa para empresa. A média é que um desenvolvedor ganhe entre 3 mil e 30 mil reais, dependendo de sua função, para mais. Estudantes e programadores Jr, ganham em média de 1500 a 2500 reais <em>(isso não mudou muito de 2013 pra cá)</em>.</p>
<p>O problema é que as empresas não estão dispostas a pagar corretamente por seus programadores ou ainda dão condições de trabalho que não correspondem com a área, como computadores ruins ou obrigatoriedade de uniformes e falta de flexibilidade no horário.</p>
<p>Por outro lado, alguns profissionais trabalham como autônomos dando consultorias para empresas. Entretanto, esses profissionais precisam ter uma certa “fama” em seu seguimento. Alguns cobram até 60 mil reais por consultoria de 15 dias. Mas isso não quer dizer que são bons. Muitos programadores famosos são péssimos profissionais, mas vivem de sua fama, cobrando valores absurdos e apresentando soluções não eficientes (ou nenhuma) e mal se entrosam no projeto. Porém essa é uma questão mais ética.</p>
<h2>Concluindo</h2>
<p>O Programador, ao contrário do que possa parecer, não é um profissional de glória. Diferente do que fez parecer, a partir dos anos 90, raramente pessoas de talento e estudo conseguem receber um valor justo por seu trabalho. Geralmente, os “mestres de cerimônia”, que só tem fama e fazem parecer trabalhar, acabam sendo mais valorizados por causa de seu carisma.</p>
<p>Programador de verdade está sempre trabalhando, sempre estudando, sempre se esforçando. Sempre interessado em evoluir e melhorar os seus projetos. Para um programador legítimo, um projeto quase nunca está perfeito. Mas é sempre incrivelmente gratificante depois de passar horas tentando fazer algo complicado, finalmente conseguir. É uma sensação extasiante e inexplicável.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Qual o Melhor Computador para Design e Desenvolvimento?</title>
		<link>https://velhobit.com.br/programacao/qual-o-melhor-computador-para-design-e-desenvolvimento.html</link>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Thu, 19 Jan 2017 21:27:53 +0000</pubDate>
				<category><![CDATA[Desenvolvimento]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[computador]]></category>
		<category><![CDATA[cpu]]></category>
		<category><![CDATA[escolhas]]></category>
		<category><![CDATA[gpu]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[investimento]]></category>
		<category><![CDATA[laptop]]></category>
		<category><![CDATA[processadores]]></category>
		<category><![CDATA[trabalho]]></category>
		<guid isPermaLink="false">https://bitcolor.com.br/?p=33</guid>

					<description><![CDATA[Profissionais que usam o computador como sua principal ferramenta precisam conhecer como sua máquina funciona para tomar as melhores decisões em seu trabalho.]]></description>
										<content:encoded><![CDATA[<p>Assim como um pintor conhece sua tela e pincéis e um pedreiro conhece sua espátula e ferramentas, todo o profissional de TI precisa conhecer seu computador, e isso inclui o designer. Todo profissional precisa conhecer sua ferramenta.</p>
<p>Por muitas vezes, perguntei a alguns amigos designers qual era a configuração da máquina em que eles trabalhavam. Alguns me respondiam “Windows 7”, outros me respondiam, “ah é um Mac”. Mas, na realidade, o que eu queria saber era quanto de RAM, quanto de HD, qual o processador, placa de vídeo e, para minha surpresa, sempre me deparava com um “o quê?”, “como é?”, “sou designer. Não tem nada a ver eu saber disso”. Isso é decepcionante.</p>
<p>As vezes é necessário criar grandes formatos ou editar vídeos, talvez um pouco de 3D, então precisa de um computador que possa dar suporte as suas necessidades. Mas como saber se o que precisa é de mais RAM ou mais processamento? Ou se na verdade você simplesmente já tinha tudo certo, mas nem sabia que existiam Sistemas Operacionais 64 bits? Aliás, nem sequer sabia o que era 64 bits?</p>
<p>Existem muitos designers que enchem um site de estruturas complexas e somente camadas de PNG, ou gigantescas manobras de canvas, para poder montar algo vistoso. O designer necessita se preocupar com a tecnologia que o seu usuário usa e qual a configuração média do dispositivo, de acordo com a proposta do aplicativo, site ou artefato. Essa é outra razão para compreender como funciona computadores e dispositivos móveis.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-35" src="https://velhobit.com.br/wp-content/uploads/2017/01/laptop-branco-ligado-monitor-design.jpg" alt="laptop-branco-ligado-monitor-design" width="1080" height="638" srcset="https://velhobit.com.br/wp-content/uploads/2017/01/laptop-branco-ligado-monitor-design.jpg 1080w, https://velhobit.com.br/wp-content/uploads/2017/01/laptop-branco-ligado-monitor-design-400x236.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/01/laptop-branco-ligado-monitor-design-768x454.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/01/laptop-branco-ligado-monitor-design-1024x605.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/01/laptop-branco-ligado-monitor-design-600x354.jpg 600w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /></p>
<h2>Devo comprar um laptop ou um desktop</h2>
<p>Laptops são computadores portáteis, conhecidos no Brasil como notebooks. Já os Desktops são computadores de mesa. A vantagem do primeiro é a mobilidade, porém, essa mobilidade tem um custo mais elevado, que pode ser refletido tanto em preço, quanto em performance. Independente do que você precisar comprar, fique atento as questões abaixo para que você possa escolher melhor a sua máquina. Para tanto, vamos listar por componentes mais comuns.</p>
<h2>Processadores</h2>
<p>O processador, ou a CPU (Unidade Central de Processamento), é o elemento que mais gera dúvidas a respeito de performance. Para quem trabalha com vídeos ou edição de som, o processador é fundamental para garantir uma renderização mais rápida. Já para quem trabalha com imagens estáticas, como o Photoshop ou Illustrator, ele vai acelerar o tempo de adição de efeitos e filtros. Para quem trabalha com web e desenvolvimento, a performance do processador é mais importante para virtualização, seja para dispositivos móveis ou máquinas virtuais.</p>
<p>Basicamente, há duas empresas quando o assunto é processadores: Intel e AMD. Com isso, vale a atenção a algumas características que podem enganar o consumidor mais desatento: As marcas i3, i5 e i7 são nomenclaturas puramente comerciais. A grande maioria dos laptops i7, por exemplo, são da linha U, que correspondem a um menor custo de energia, porém com uma performance inferior. A linha i7 XXX U, da Intel, por exemplo, apresenta menor clock e menor quantidade de núcleos, sendo comparado a um i3 para Desktops ou a um i5 da linha HQ, para laptops. Por isso, antes de se pensar em nomes comerciais, é necessário ficar atento a algumas características, como:</p>
<p><strong>Clock →</strong> Digamos que seja a velocidade do processador. Ele é determinado a partir de métrica de frequência. Um processador mínimo, para quem trabalha com programas gráficos, é de 2,6GHz. Esse clock deve ser mais poderoso, caso o objetivo seja trabalhar com renderização de vídeo e 3D, onde é aconselhado pelo menos 3,2GHz. A tendência é que quantos mais GHz, mais rápido será a renderização.</p>
<p><strong>Núcleos (Core) →</strong> Esse é um assunto polêmico. A necessidade de uma quantidade maior ou menor de núcleos depende da disponibilidade do aplicativo de usar ou não esses núcleos. Uma quantidade maior de núcleos significa que o processamento será dividido e executado simultaneamente entre eles, aumentando, por consequência, a performance. Os núcleos podem ser físicos ou lógicos (geralmente representado como Número de Threads). A diferença é que o núcleo físico realmente o número de núcleos no processador, enquanto o virtual emula núcleos dentro da CPU, com o objetivo de dividir as tarefas. Os núcleos físicos possuem performance superior, porém, mesmo processadores com 4 ou mais núcleos, tendem a possuir núcleos virtuais para somatizar a performance. Muitos núcleos são recomendados para quem trabalha com bastante 3D ou precise trabalhar com máquinas virtuais. Vale lembrar que a quantidade de vários núcleos significa que o computador irá dividir mais processos simultaneamente, ficando assim mais rápido, caso o programa usado dê esse suporte. A grande maioria dos programas profissionais modernos (programas da Adobe, AutoDesk, alguns compiladores, etc.) usam bem as várias threads do processador.</p>
<p><strong>Cache →</strong> A memória cache representa o tamanho da informação que o processador poderá processar por vez. Quanto mais memória cache, mais tarefas o processador poderá executar em um curto espaço de tempo e, por consequência, maior performance. Muitos consideram a memória cache mais importante do que o Clock. É importante salientar que a quantidade de memória varia de núcleo para núcleo. Desse modo, segue a mesma lógica do clock, quanto mais você tiver, melhor vai ser sua performance para renderização. No entanto, atenção, a Intel mostra o cache POR NÚCLEO, enquanto a AMD tem o costume de mostrar a SOMA do cache. Então fique atento e observe sempre, nas configurações, o cache por núcleo. A partir de 4MB de cache L3 é interessante para quem trabalha com impressos, web e aplicativos. Para quem trabalha intensamente com vídeo e 3D, 8MB, ou mais, de cache L3 é mais recomendado.</p>
<p>O site <a title="Acesse o site CPU BOSS" href="http://cpuboss.com/" target="_blank" rel="noopener">CPU BOSS</a> vai ajudar você a ter uma ideia de comparação na hora de escolher um processador.</p>
<h2>Memória RAM</h2>
<p>Até o começo dos anos 2000, muita memória RAM era sinônimo de altíssima performance. Isso porque a memória RAM, ou Memória de Acesso Aleatório, é responsável por guardar as informações que estão sendo executadas naquele momento. Em resumo, quanto mais memória RAM, mais programas abertos e mais pesados podem ficar abertos simultaneamente. O fato é que, hoje, os aplicativos são mais otimizados para consumir menos memória. Porém, para quem trabalha com projetos muito pesados, como revistas, livros e grandes formatos, uma quantidade razoável de memória RAM é muito importante. Já para quem trabalha com web, nem tanto. Já para virtualização, memória RAM é muito importante para dividir entre as máquinas virtuais. 8GB é o mínimo para quem trabalha com revistas e livros. Já para quem trabalha com web, 6GB é suficiente. Virtualização e vídeo, a partir de 16GB.</p>
<h2>Placa de Vídeo</h2>
<p>Nem todo computador tem uma placa de vídeo, mas todo ele tem um chipset ou um processador de vídeo. Hoje, existem duas opções no mercado: APU e GPU.</p>
<p>A APU é um tipo de processamento de vídeo que é compartilhado com o processador. Praticamente todos os processadores hoje possuem um processamento de vídeo incorporado. Mas esse vídeo incorporado não possui tanta performance quanto um processador de vídeo dedicado e também precisa usar parte da memória RAM.</p>
<p>Já a GPU é um processador dedicado de vídeo. As principais fabricantes são a nVIDIA e a AMD/Radeon. Por possuir um processamento próprio de vídeo e memória dedica, possui uma performance muito superior. Por isso elas são mais caras e exigem também mais energia e esquentam mais, o que pode ser algo que pese na opinião de alguém que queira comprar um computador, já que a fan (ventoinha) pode fazer muito barulho na hora que requer alto processaemnto.</p>
<p>Quem trabalha apenas com impressos, publicações e elementos institucionais, ou com desenvolvimento e web, não tem a necessidade de uma GPU. Uma APU o atenderá sem problemas. Porém para usar recursos mais avançados do Photoshop, como o 3D, uma GPU simples, dedicada, será o suficiente. Agora, se o intuito é trabalhar com 3D ou vídeo, então uma GPU mais parruda se faz necessário. Vale lembrar que é importante ver se o software que você usa, para edição de vídeo, usa mais a GPU ou a CPU para renderização. Esse último detalhe pode ser fundamental para uma escolha ideal.</p>
<p>Apesar do que pode parecer, a memória dedicada da GPU não é o ponto mais importante no que diz respeito a qualidade. Também a questão de núcleos não é tão importante assim, visto que processadores gráficos possuem uma quantidade absurda de núcleos em comparação a CPUs. A arquitetura da GPU quanto ao seu clock e a sua quantidade de memória é algo fundamental para analisar. Por exemplo, a GPU Geforce 930M (para laptops), da nVidia, é suficiente para quem quer trabalhar com impressos, web e vídeos esporádicos. Já a GTX 780, também da nVidia, apesar de mais antiga, é melhor, porém apenas para desktops. No caso da nVidia, o que difere a qualidade está mais relacionada aos seus dois últimos dígitos, sendo que o primeiro especifica o quão recente é a arquitetura. Pessoas que trabalham com 3D de forma mais assídua, e as que usam a GPU para renderizar vídeos, precisam de GPUs mais potentes. Alguns podem juntar várias GPUs em uma única, somando o processamento (mas não a memória dedicada) e deixando a renderização mais rápida.</p>
<p>Usuários do Ubuntu, cuidado ao comprar uma placa de vídeo Radeon. Muitas não receberão mais atualizações para o sistema operacional, ficando inutilizável o OpenGL nas distribuições mais recentes. Fique atento ao modelo que for adquirir.</p>
<p>Para verificar e comparar GPUs, o site <a title="Acesse o Site GPU Boss" href="http://gpuboss.com/" target="_blank" rel="noopener">GPU BOSS </a>vai te ajudar a escolher qual a melhor.</p>
<h2>Displays e Monitores</h2>
<p>Um assunto deveras delicado, mas bem simples. Designers precisam sempre de qualidade de resolução e brilho, além de fidelidade de cores. O foco é sempre na relação de taxa de atualização x polegadas x resolução x tecnologia. O ideal ainda é uma tela IPS ou OLED. A resolução FULLHD deve ser usada no máximo em um monitor de 21.5 polegadas, para não ficar incômoda a densidade de pixels. Recomenda-se uma resolução maior também para manter uma boa área de utilização em relação as ferramentas. Qualquer coisa maior que 21.5 polegadas deverá ser 2K ou 4K, para manter uma boa qualidade de imagem. Já no que diz respeito a frequência, praticamente todos os monitores hoje apresentam boa frequência, porém para quem trabalha com vídeos, pode tentar conseguir um monitor na faixa dos 100hz. Mas cuidado, fuja totalmente das telas TFTs.</p>
<h2>HDD e SSD</h2>
<p>Espaço de armazenamento nunca é demais, mas as vezes velocidade é mais necessário. Os HDs eletromecânicos (HDD) possuem a vantagem de serem mais baratos e, graças a tecnologia SMART, saber quando vão dar problemas e o usuário pode tomar uma previdência quanto a um backup. Além disso, por ser mais barato, a quantidade de espaço disponível é muito maior a um preço menor. O problema é que por serem mecânicos são mais lentos. O mais rápido que é possível encontrar no mercado é o de 7200RPM.</p>
<p>Já o SSD, é extramamente rápido, por não possuir componentes mecânicos, o tempo de abertura de um arquivo ou programa é até 90% mais rápido do que em HDD. Porém, no caso de queimarem ou ter um problema sério, eles simplesmente irão parar de funcionar. Não há uma forma prática de diagnosticar que o SSD vai dar problemas. O custo também é muito alto. SSDs podem chegar a preços até 10x mais caro que um HD de mesma quantidade de memória. Vale salientar que a velocidade do SSD varia entre marcas e modelos, mas sempre é mais rápido que os HDDs comuns.</p>
<h2>Periféricos</h2>
<p>Mouses e teclados são detalhes pouco discutidos, mas são importantes. Para começar, quem trabalha muito com programação, ou digita muito, pode preferir um teclado mecânico. Porém teclados mecânicos são bem mais caros que o convencionais e fazem mais barulho, em contra partida possuem resposta muito mais rápida e eficiênte, o pressionar é mais confiável. Já no que diz respeito a mouses e touchpads, isso é uma questão realmente de adaptação, você precisa experimentar qual é o mais ideal para a sua mão. Procure mouses com DPIs mais altos, pois possuem maior precisão. No que diz respeito as Pen Tablets (erroneamente chamado de Mesa Digitalizadora), pouquíssimas pessoas realmente precisam deles e vão utilizar. A maioria das pessoas que as tem, compram por questão de status ou de uma ideia errada da atualização. O uso das PenTablets é maior para pessoas que realmente trabalham com ilustração matricial ou que precisem retocar imagens com frequência.</p>
<p><strong>Obs. este artigo é de 2015. Então fiquem de olho nas atualizações dos hardwares.</strong></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-36" src="https://velhobit.com.br/wp-content/uploads/2017/01/laptops.jpg" alt="laptops de diversos modelos" width="1920" height="817" srcset="https://velhobit.com.br/wp-content/uploads/2017/01/laptops.jpg 1920w, https://velhobit.com.br/wp-content/uploads/2017/01/laptops-400x170.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/01/laptops-768x327.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/01/laptops-1024x436.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/01/laptops-600x255.jpg 600w" sizes="auto, (max-width: 1920px) 100vw, 1920px" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-37" src="https://velhobit.com.br/wp-content/uploads/2017/01/desktop.jpg" alt="Desktop de diversos modelos" width="1920" height="817" srcset="https://velhobit.com.br/wp-content/uploads/2017/01/desktop.jpg 1920w, https://velhobit.com.br/wp-content/uploads/2017/01/desktop-400x170.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/01/desktop-768x327.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/01/desktop-1024x436.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/01/desktop-600x255.jpg 600w" sizes="auto, (max-width: 1920px) 100vw, 1920px" /></p>
<h2>Por fim, desktop ou laptop</h2>
<p>Laptops costumam ser mais caros e ter uma performance inferior aos desktops de preços equivalentes. Além disso, você está à mercê das opções disponíveis no mercado, não vai ter a liberdade para montar uma máquina que julgar ideal. Mas os laptops possuem a vantagem da mobilidade e de ocupar um menor espaço físico, pode-se trabalhar em qualquer local e se deslocar a escritórios diferentes. Muitas pessoas preferem usar laptops com monitores separados, quando em estações de trabalho. Quando comprar um laptop deve-se ficar muito atento ao processador e a GPU, que, na maioria das vezes, possuem baixa qualidade para poder baratear os custos e melhorar a performance da bateria. Se comprar um laptop, opte primeiro por adquirir nas lojas oficiais, físicas ou online, salvo promoções pontuais, na loja da marca costuma ser mais barato e ter melhores condições.</p>
<p>Desktops possuem a vantagem de serem flexíveis, mais baratos e ter melhor performance. Porém exige muito espaço físico e você não há boa mobilidade. Consomem mais energia e é necessário um pouco mais de experiência para montar um equipamento que realmente agrade. Na grande maioria das vezes, ainda é possível fazer atualizações, aumentando o tempo de vida útil do computador, adicionando com o tempo uma placa de vídeo melhor ou mais RAM, trocar o processador ou adicionar periféricos. Tudo de acordo com as necessidades que forem surgindo. O ideal é comprar as peças e montar, pois a maioria das empresas que entregam o PC pronto tendem a escolher componentes de mais baixa qualidade para diminuir os custos.</p>
<p><em><strong>Atenção: No momento em que receber o computador, seja ele um laptop, desktop ou até mesmo montado por você, faça todos os testes possíveis. Processamento, GPU, APU, etc. Use ferramentas de Benchmark de terceiros para isso. Não utilize as ferramentas da própria empresa da marca do computador que você comprou. Muitas vezes, elas não fazem os testes necessários para averiguar realmente todos os elementos do hardware.</strong></em></p>
<p>Conhecer a sua própria máquina é mais que um luxo, é uma obrigação. Entender qual a nova tecnologia que entrará no mercado, e se adaptar a elas, é importante para se manter em um mercado cheio de concorrência, algumas até desleiais. Não estou falando de entender o que é um transistor, ou de fazer um curso de montagem e manutenção em algum “cursinho” por aí, mas sim, de entender o porquê de você comprar um processador de 4 núcleos, entender a diferença de uma GTX 930 para uma GTX 970, saber porque está comprando 16GB de RAM e não somente 8GB. Só assim você terá como tirar o maior proveito possível de seu computador e não fazê-lo tornar somente um elefante branco.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Entendendo a Sefaz &#8211; NFe, CTe, NFSe e Outros</title>
		<link>https://velhobit.com.br/programacao/entendendo-a-sefaz-nfe-cte-nfse-e-outros.html</link>
					<comments>https://velhobit.com.br/programacao/entendendo-a-sefaz-nfe-cte-nfse-e-outros.html#comments</comments>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Thu, 19 Jan 2017 21:22:43 +0000</pubDate>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[chave]]></category>
		<category><![CDATA[conhecimento eletrônico]]></category>
		<category><![CDATA[cte]]></category>
		<category><![CDATA[fiscal]]></category>
		<category><![CDATA[informações]]></category>
		<category><![CDATA[mdfe]]></category>
		<category><![CDATA[nfce]]></category>
		<category><![CDATA[nfe]]></category>
		<category><![CDATA[nota]]></category>
		<category><![CDATA[nota fiscal]]></category>
		<category><![CDATA[sefaz]]></category>
		<category><![CDATA[webservice]]></category>
		<category><![CDATA[wsdl]]></category>
		<category><![CDATA[xml]]></category>
		<guid isPermaLink="false">https://bitcolor.com.br/?p=27</guid>

					<description><![CDATA[A integração com os webservices da Sefaz é um pouco complicada. Este compilado resume os conceitos básicos para o desenvolvimento de sua aplicação]]></description>
										<content:encoded><![CDATA[<p>Eu entendo que o título deste artigo vai parecer muito arrogante, pois é impossível entender a Sefaz, mas assim o título fica menor e é melhor para o <a href="https://velhobit.com.br/tecnologia-e-negocios/apelacao-do-seo/">SEO</a>. O que vamos explorar aqui não é exatamente código, mas revisar conceitos e problemas mais comuns que <a href="https://velhobit.com.br/desenvolvimento/quanto-custa-ser-desenvolvedor/">programadores</a> têm ao implementar um módulo fiscal em seu sistema. Este artigo é destinado para quem vai começar a implementação e facilitar o entendimento de para aqueles que simplesmente vão fazer manutenções em sistemas já existentes.</p>
<p>Comecei a trabalhar com essa parte fiscal há mais ou menos 1,5 ano. Para quem já trabalhou com NFe, CTe e, mais recentemente, NFSe, deve saber que a Sefaz parece que faz de tudo para você cometer erros. O suporte é quase nulo e eles poderiam realmente fazer uma forma de facilitar a comunicação e dar melhores retornos. Mas a verdade é que parece que o governo usa multa como fonte de renda, então para quê facilitar que o empresário pague ao próprio governo, né?</p>
<p>Supostamente, a NFe / CTe foi criada para reduzir o esforço e facilitar a emissão de documentos fiscais. Não há duvidas de que o controle do governo para o pagamento desses impostos aumentou e a dificuldade para sonegar impostos é maior. Entretanto, a dificuldade para emissão da nota também aumentou. Atualmente as empresas são obrigadas a emitir NF e do antigo CTRC (na maioria dos estados) de forma eletrônica. Futuramente a Nota Fiscal de Serviço também será eletrônica.</p>
<p><strong>Obs. NFe = Nota Fiscal Eletrônica, NFSe = Nota Fiscal de Serviço Eletrônica, CTe = Conhecimento de Transporte Eletrônico. O leiaute 3.0 da NFe, referente ao Cupom Fiscal Eletrônico ainda não está em fases de testes e não explorarei neste artigo por não possuir ainda conhecimento necessário para descrever, no entanto, o 3.0 deverá seguir a mesma lógica.</strong></p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-28" src="https://velhobit.com.br/wp-content/uploads/2017/01/usando-computador-fiscal.png" alt="Contador usando computador e falando ao telefone, com camisa azul." width="700" height="395" srcset="https://velhobit.com.br/wp-content/uploads/2017/01/usando-computador-fiscal.png 700w, https://velhobit.com.br/wp-content/uploads/2017/01/usando-computador-fiscal-400x226.png 400w, https://velhobit.com.br/wp-content/uploads/2017/01/usando-computador-fiscal-600x339.png 600w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<h2>Os Manuais da Sefaz</h2>
<p>Muitos podem dizer que todas as respostas estão nos manuais e basta lê-los (hahahaha!). Mas muitos programadores só precisam dar suporte a um sistema já implementado ou simplesmente não entendeu determinados processos descritos nos manuais.</p>
<p>Primeiramente, devo lembrar que todos os manuais estão disponíveis através dos respectivos sites das fazendas:</p>
<ul>
<li><a href="http://www.nfe.fazenda.gov.br/portal/listaConteudo.aspx?tipoConteudo=33ol5hhSYZk=">Documentos NFe</a></li>
<li><a href="http://www.cte.fazenda.gov.br/listaConteudo.aspx?tipoConteudo=YIi+H8VETH0=">Documentos CTe</a></li>
</ul>
<p>Já para as notas fiscais de serviço (NFSe) há um problema a parte. Apesar de existir um padrão para NFSe, cabe a cada município a responsabilidade de disponibilizar os servidores e padrões para os webservices das mesmas, dificultando e MUITO a vida do programador. Consulte o site da Sefaz de seu município para obter o link com o manual.</p>
<p>Não somente os manuais são importantes como também as notas técnicas. As notas técnicas são mudanças que acontecem com certa frequência sobre os servidores da Sefaz e atualizações nas regras de validação e legislação. Infelizmente não tem como você receber atualizações em seu email. Então você deve estar sempre de olho nessas páginas e prestar atenção em fóruns relativos a Sefaz que concordem com a linguagem que você está trabalhando.</p>
<p>Sem dúvida a parte mais importante do manual e o que deve ser seguido na maioria dos erros (os erros mais comuns são os de preenchimento), são as Tabelas de Leiaute.  Ela não é complicada, mas pode causar algumas confusões em profissionais menos experientes. Abaixo, listarei a importância e descrição de cada campo da tabela leiaute:</p>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-29" src="https://velhobit.com.br/wp-content/uploads/2017/01/exemplo-tabela-leioute-nfe.jpg" alt="exemplo-tabela-leioute-nfe" width="703" height="372" srcset="https://velhobit.com.br/wp-content/uploads/2017/01/exemplo-tabela-leioute-nfe.jpg 703w, https://velhobit.com.br/wp-content/uploads/2017/01/exemplo-tabela-leioute-nfe-400x212.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/01/exemplo-tabela-leioute-nfe-600x317.jpg 600w" sizes="auto, (max-width: 703px) 100vw, 703px" /></p>
<ul>
<li># : Código de referência único para cada linha da tabela de leiaute;</li>
<li>Campo : Descreve o nome da tag XML para aquele valor;</li>
<li>Ele : Indica o tipo do campo(A &#8211; atributo, E &#8211; Elemento, CE – Elemento que deriva de uma Escolha, G – Grupo, CG &#8211; Elemento de Grupo que deriva de uma Escolha, ID – ID da XML 1.0, RC – Restrição de Chave);</li>
<li>Pai : Referência da tag pai daquela linha, baseado no código único;</li>
<li>Tipo: Descreve o tipo básico do valor que deve ser passado para aquele campo (N = Número, C = Caractere, D = Data, xml = XML).</li>
<li>Ocor. (Ocorrência) : Mostra o número mínimo e máximo de vezes que a tag deve aparecer na XML. Exemplo: 0-1 quer dizer que ela não é obrigatória, mas só pode aparecer uma vez, 1-1 quer dizer que é obrigatória e aparecer somente uma vez, 1-3 quer dizer que ela é obrigatória, mas só precisa aparecer uma vez e pode aparecer até 3 vezes. Ou seja, o primeiro número corresponde a ocorrência mínima e o segundo número a ocorrência máxima;</li>
<li>Tam. (Tamanho) : Quantidade de caracteres que deve ter a tag. Pode ser referenciado através de número mínimo e máximo, como na ocorrência (ex: 1-4, entre um e quatro caracteres) ou através de apenas um número, especificando que deve ter aquela quantidade exata de caracteres.</li>
<li>Dec. (Decimais) : Em caso de número, descreve a quantidade de casas decimais obrigatórias daquele número;</li>
<li>Descrição / Obsevações : Explica alguma regra específica que deve ser aplicada àquele valor da XML</li>
</ul>
<p><strong>Vale lembrar que nenhuma tag pode ficar vazia. Se a tag não for obrigatória, ela simplesmente não deve ser impressa na XML.</strong></p>
<p><strong>Fique muito atento que as vezes, no banco, pode aparecer caracteres especiais (como tabulação) e deixar uma tag vazia, mesmo quando você fizer um &lt; if (campo.valor == &#8220;&#8221; || campo.valor == null): break;&gt;, para impedir que a tag não seja impressa.</strong></p>
<h2>Os Webservices</h2>
<p>A Sefaz trabalha com Webservices XML. Há webservices específicos para homologação, produção e contingência (casos em que webservices principais estejam fora do ar). A maioria dos estados possuem os próprios webservices, outros usam os de outros estados.</p>
<p>Você pode verificar os links nos sites da <a href="http://www.nfe.fazenda.gov.br/portal/principal.aspx">Sefaz Nacional do NFe</a> e do <a href="http://www.cte.fazenda.gov.br/">CTe</a>. Os links para os serviços das NFEs são disponibilizados por seus municípios.</p>
<p>Quando você vai enviar uma XML de nota ou conhecimento para a Sefaz, você não envia somente a XML da nota, como também para verificar o status do serviço, consulta, cancelamento, etc. Essas XMLs possuem as informações necessárias para o servidor da Sefaz saber qual função o sistema deverá executar e os parâmetros necessários para uma resposta correta.</p>
<p>Validação da XML e Schemas</p>
<p>Schemas são arquivos XML que servem como base para validação de um outro XML. Os schemas descrevem as regras de validação baseadas, principalmente, em expressões regulares. Você deve passar pelo schema para validar a XML antes de ir enviar para a Sefaz. No entanto, quando a XML passar pelo webservice, ela passará pelo mesmo schema e dará uma resposta, porém essa resposta as vezes não vem completa e é necessário validar &#8220;no olho&#8221;.</p>
<p>Para facilitar, você pode colar a XML da sua nota pelo validador da Sefaz Virtual do Rio Grande do Sul. Irá funcionar para qualquer estado.</p>
<ul>
<li><a href="https://www.sefaz.rs.gov.br/nfe/nfe-val.aspx">Validador online NFe;</a></li>
<li><a href="https://www.sefaz.rs.gov.br/cte/cte-val.aspx">Validador online CTe;</a></li>
</ul>
<p>Obs. As vezes o validados do RS fica dando problema e não consegue validar. Basta recarregar a página que o problema tende a desaparecer.</p>
<p>Você pode baixar os schemas diretamente no site da Sefaz. Para NFSe, você vai ter que consultar, novamente, a Sefaz do município.</p>
<h2>Comunicação</h2>
<p>Por padrão, a comunicação ao Sefaz é feita através do protocolo SOAP 2. Ao montar a comunicação você deverá passar a URL do webservice, o caminho do certificado digital, a senha do certificado, a url de status e as XMLs necessárias para executar a tarefa que deseja. Erros durante a comunicação são comuns, principalmente quando há algum problema com o certificado digital ou quando o webservice da Sefaz encontra-se fora do ar.</p>
<p>Sempre verifique se o webservice o qual esteja tentando comunicação está no ar através dos sites da SEFAZ nacional no menu &#8220;Verificar Disponibilidade&#8221;.</p>
<p>Obs. Lembre-se de sempre colocar ?WSDL no final das URLs dos webservices (sim, a Sefaz usa servidores Windows).</p>
<h2>Certificado Digital</h2>
<p>O certificado digital é um documento criptografado que possui a assinatura da empresa. O certificado serve para autenticar a XML enviada como sendo realmente pertencente a empresa emissora da nota. Toda XML deve ser assinada através do certificado digital.</p>
<p>O certificado usado na Nota Fiscal Eletrônica e no Conhecimento de Transporte Eletrônico é o do tipo A1 e pode ser adquirido através de autoridades certificadoras autorizadas pela Sefaz, como por exemplo o Serasa. Os certificados são comprados pelas empresas emissoras de nota e podem ser utilizados para várias filiais da mesma empresa.</p>
<p>Vale salientar que os certificados são emitidos no padrão PKCS#12 (.pfx) e quem usa servidores Linux/Unix/Mac devem converter os certificados para PEM (.pem). Para isso há conversores online ou você pode fazer diretamente pelo Terminal através do openssl.</p>
<p>Obs. Sempre abra os arquivos PEM em um editor de texto e verifique os Bag Attributes e todas as Keys estão preenchidas, pois as vezes elas não estão com esses valores e isso causa erros sem resposta.</p>
<h2>Homologação, Produção e Contingência</h2>
<p>Após o possuir o certificado, o contador da empresa emissora do NFe/CTe deve, junto a Sefaz de seu estado, autorizar a empresa para ambiente de homologação (ou seja, ambiente de testes), a autorização sai em torno de 24 horas depois do pedido feito pelo contador. Cada filial deverá ter autorizada e homologada individualmente, porém o certificado, como dito antes, pode ser o mesmo.</p>
<p>No ambiente de homologação, o sistema deve estar configurado com os webservices de homologação do estado da empresa (<a href="http://hom.nfe.fazenda.gov.br/portal/webServices.aspx">homologação NFe</a>, <a href="http://hom.cte.fazenda.gov.br/">homologação CTe</a>). A XML deve estar preenchida com os dados de homologação. Verifique a parte de homologação no manual para entender como devem ser esses dados.</p>
<p>Após a autorização de homologação, você deve fazer a emissão e autorização de no mínimo 10 notas/conhecimentos, 5 cancelamentos e 5 inutilizações (falaremos disso abaixo). Somente após fazer isso, você pode pedir para o contador autorizar a empresa a emitir nota em ambiente de produção. Faça quantos testes forem necessários até sentir-se seguro. Erros em Notas podem causar problemas muito sérios para as empresas, principalmente quanto a sonegação de impostos.</p>
<p>Lembre-se de, quando passar a nota para o ambiente de produção, mudar os webservices para o ambiente de produção. O tempo para autorizar a empresa para o ambiente de produção é de mais 24 horas.</p>
<p>Obs. Se a empresa estiver com dívidas muito altas de impostos ou algum problema de cadastro e atualização de dados na Sefaz, você pode ter problemas durante a emissão da nota/conhecimento. Nesse caso, consulte o contador ou administrador da empresa para que ele tome as devidas providências. Como é um erro sem retorno, no caso de suspeitar desse problema, consulte o e-CAC.</p>
<p>No caso dos webservices estarem fora do ar ou a empresa não disponibilizar de internet naquele momento, é necessário emitir a Nota Fiscal em contingência. Há ao todo 3 formas de continência. Os servidores de contingência estão disponíveis no site da Sefaz Nacional. Exceto no caso do emitente estar sem internet, o próprio servidor de continência envia os dados da NFe/CTe para a Sefaz Nacional. Isso pode demorar cerca de 2 horas depois que o servidor do estado voltar ao normal.</p>
<h2>Emissão da Nota/Conhecimento Eletrônico</h2>
<p>Para poder emitir uma Nota ou Conhecimento, você precisará gerar uma chave única para esta. A chave é gerada a partir da seguinte lógica:</p>
<p>O dígito verificador é um número que é gerado por um algoritmo específico a partir do número restante. Basicamente, multiplica-se o número da base pelos decimais equivalentes de 2 a 9, soma o resultado e pega o resto da divisão do resultado pro 11, por fim, pega o 11 e subtrai o resto. Se o resultado for 10, deve-se pássaro 0. É fácil encontrar o algoritmo para a linguagem que você trabalha no Google. Abaixo o código em PHP.</p>
<pre class="prettyprint">function calculadDigitoVerificador($chave43) {

   $multiplicadores = array(2,3,4,5,6,7,8,9);

   $i = 42;

   while ($i &gt;= 0) {

       for ($m=0; $m&lt;count($multiplicadores) &amp;&amp; $i&gt;=0; $m++) {

           $soma_ponderada+= $chave43[$i] * $multiplicadores[$m];
           $i--;

       }

   }

   $resto = $soma_ponderada % 11;

   if ($resto == '0' || $resto == '1') {

       return 0;

   } else {

       return (11 - $resto);

  }

}</pre>
<p><img loading="lazy" decoding="async" class="alignnone size-full wp-image-30" src="https://velhobit.com.br/wp-content/uploads/2017/01/tabela-chave-acesso-dv.jpg" alt="tabela-chave-acesso-dv" width="1196" height="195" srcset="https://velhobit.com.br/wp-content/uploads/2017/01/tabela-chave-acesso-dv.jpg 1196w, https://velhobit.com.br/wp-content/uploads/2017/01/tabela-chave-acesso-dv-400x65.jpg 400w, https://velhobit.com.br/wp-content/uploads/2017/01/tabela-chave-acesso-dv-768x125.jpg 768w, https://velhobit.com.br/wp-content/uploads/2017/01/tabela-chave-acesso-dv-1024x167.jpg 1024w, https://velhobit.com.br/wp-content/uploads/2017/01/tabela-chave-acesso-dv-600x98.jpg 600w" sizes="auto, (max-width: 1196px) 100vw, 1196px" /></p>
<p>Com a chave de 44 caracteres pronta e a XML preenchida corretamente, você já pode emitir a Nota Fiscal / Conhecimento Transporte. Você receberá como resposta a XML validada e o retorno  da Sefaz avisando se a nota foi autorizada, denegada (quando há algum problema com o emitente)  ou rejeitada e precisa ser corrigida.</p>
<p>Lembre-se que esses documentos fiscais devem seguir uma seqüência numérica que deve ser usada dentro de cada série.</p>
<p><strong>Obs. Os CTe&#8217;s não são emitidos por agências, mas sim por filiais, por isso fique atento a sequência numérica.</strong></p>
<h2>Consulta</h2>
<p>Você pode consultar a nota / conhecimento através do site da Sefaz Nacional ou diretamente na Sefaz de seu estado. Para isso, basta você entrar com o número da chave.</p>
<p>Há um webservice específico para consulta para permitir que o seu sistema mostre para o usuário a situação daquele documento.</p>
<p>Vale lembrar que se você for consultar na Sefaz Nacional pode ser que a nota não apareça em até cerca de duas horas após a emissão. A consulta feita na Sefaz estadual tende a ser na hora.</p>
<h2>Carta de Correção</h2>
<p>A carta de correção é um documento fiscal que faz adendos a uma nota fiscal/cte emitida. Esse documento anexa informações ao documento dentro da Sefaz. Para o sistema, será emitido um novo XML de resposta contendo as informações da correção.</p>
<p>Alguns estados não permitem a emissão da correção. No caso, o usuário deverá cancelar o documento e emitir outro.</p>
<h2>Cancelamento</h2>
<p>Se uma compra for cancelada ou houver um erro que não pode ser resolvido através da carta de correção, você pode fazer o cancelamento da Nota/Conhecimento através do webservice de EVENTO, passando a função de cancelamento.</p>
<p>Geralmente, você tem até 24 horas para cancelar uma Nota Fiscal Eletrônica a partir da hora de emissão da mesma. Porém, alguns estados só permitem o cancelamento em até 3 horas. Para o CTe há uma semana de prazo de cancelamento.</p>
<p>Em caso de necessitar cancelar a nota ou cte após o prazo terminado, avise ao contador da empresa emissora. Este deverá enviar um documento a Sefaz do estado para resolver o problema e uma pequena taxa deverá ser cobrada.</p>
<h2>Inutilização</h2>
<p>Se por algum motivo você precisar pular o número de uma nota, seja por esquecimento, erro no sistema, etc., você deverá inutilizar aquele número.</p>
<p>A Nota/CTe segue um número contínuo dentro de cada série. Por isso, utilize o webservice de inutilização para pular algum número da sequência. Alguns estados não possuem servidor de inutilização (consulte o site da Sefaz Nacional), nesse caso, consulte o contador da empresa emitente e ele deverá enviar um documento para a Sefaz, em papel, para inutilizar esses números.</p>
<h2>DANFE/DACTE</h2>
<p>O Danfe / Dacte são os documentos impressos NÃO FISCAIS contendo a informação das Notas/Conhecimento. Descrevo o não fiscal porque o que tem realmente valor fiscal são as XMLs que devem ser salvas por 5 anos. No entanto o Danfe é necessário para o emissor da nfe passar os dados da nota impressos para o cliente. Já o Dacte é OBRIGATÓRIO que o motorista/piloto/ferroviário ande junto com os Danfes dos produtos que estão sendo transportados.</p>
<p>Nos manuais da Sefaz há descrições de que como deve ser o leiaute do Danfe/Dacte. Estes nada mais são do que uma apresentação impressa e legível dos dados da XML. Você pode usar o DOM Document sem problema para ler a XML e gerar o seu arquivo PDF.</p>
<h2>Bibliotecas Prontas</h2>
<p>Como as comunidades de programadores são enormes, há bibliotecas para as principais linguagens que possibilitam a rápida implementação de NFe, NFs e CTe no seu sistema. Porém mesmo com essas bibliotecas, diversas modificações são necessárias, principalmente quando sai uma nova nota técnica.</p>
<ul>
<li><a href="http://www.nfephp.org/">PHP</a>;</li>
<li><a href="https://github.com/marinho/PyNFe">Python</a>;</li>
<li><a href="http://sourceforge.net/projects/jnfe/">Java</a>;</li>
<li><a href="http://acbr.sourceforge.net/drupal/">Delphi</a>;</li>
</ul>
<p>Se você conhecer outras bibliotecas, por favor deixe nos comentários para que eu possa atualizar o post.</p>
<h2>Erros Freqüentes</h2>
<p>Abaixo uma lista com algumas soluções dos erros mais freqüentes duvidosos, ou seja, que a resposta da Sefaz não deixa clara. Se você encontrar um erro que conseguiu solucionar, por favor deixe nos comentários para que possamos atualizar o post:</p>
<ul>
<li>Validação de XML &#8211; São os erros mais comuns. Geralmente possuem uma resposta com o nome da tag e a descrição que leva a expressão regular pelo esquema. A grande maioria das vezes são causadas por caracteres especiais ou problemas de validação no sistema para o preenchimento de dados ou por tags vazias. Solução: converta todas as suas strings para UTF8 e faça um &#8220;trim&#8221; para retirar espaçamentos em branco. Uma boa dica é retirar qualquer acento, til, caracteres especiais para evitar erros. Verifique também se o valor do campo da XML condiz com o descrito na tabela de laioute;</li>
<li>Servidor da Sefaz Não Responde &#8211; Esse erro acontece normalmente quando o servidor da Sefaz está instável ou fora do ar. Verifique no Site da Sefaz Nacional a disponibilidade do servidor. Pode acontecer caso você tenha preenchido errado a URL do Webservice;</li>
<li>Emissor não autorizado para emitir em ambiente de (&#8230;) &#8211; Acontece caso a empresa não esteja autorizada no ambiente que está tentando emitir ou quando você erra a URL do webservice de seu estado.</li>
<li>Sem resposta &#8211; Os erros sem resposta costumam acontecer quando há um problema antes da comunicação. É mais comum acontecer quando há algum erro no certificado ou quando a URL do Webservice está preenchida errado. Verifique o certificado e o webservice de acordo com o descrito acima neste artigo. Instale o certificado na sua máquina e verifique pela URL do webservice se ela está acessível;</li>
<li>Erros de comunicação / Não consegue acessar &#8211; Erro comum quando a senha do certificado está errada ou há um problema no certificado, como o descrito acima neste artigo. Verifique também se a XML está com o ambiente correto. Esse erro também pode acontecer quando a empresa está com algum problema junto a Sefaz;</li>
<li>Hora de cancelamento anterior a hora de emissão &#8211; Esse erro é muito comum em servidores com os horários mal configurados. Por padrão, um servidor deve ter a sua hora configurada pelo GMT &#8211; 3 horas (ou 4 horas, dependendo da região do Brasil) mais o horário de verão (se  houver na região). Você pode até forçar isso via código, entretanto, alguns servidores mal configurados, ao invés de especificar a região (América do Sul/Brasil) podem estar com o horário do GMT errado contando já com menos 3 horas. Para resolver o problema (quando não tens acesso ao servidor), force, via código, a configurar o GMT correto e marcar como America do Sul Brasil. Em último caso, use o horário a partir da internet.</li>
</ul>
<p><strong>Vale lembrar que em breve todos os estados terão que usar também o NFCe, a Nota Fiscal de Consumidor Final Eletrônica. Essa nota substitui os cupons fiscais e apenas deverá ser impresso a descrição, o link e o QRCode para acesso do contribuinte. Os estados estão adotando o NFCe aos poucos no ano de 2016.</strong></p>
]]></content:encoded>
					
					<wfw:commentRss>https://velhobit.com.br/programacao/entendendo-a-sefaz-nfe-cte-nfse-e-outros.html/feed</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Implementando a Integração entre PHP + jQuery + jSon</title>
		<link>https://velhobit.com.br/programacao/implementando-a-integracao-entre-php-jquery-json.html</link>
					<comments>https://velhobit.com.br/programacao/implementando-a-integracao-entre-php-jquery-json.html#comments</comments>
		
		<dc:creator><![CDATA[Rodrigo Portillo]]></dc:creator>
		<pubDate>Thu, 19 Jan 2017 21:06:57 +0000</pubDate>
				<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[aplicativo]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[desenvolvimento]]></category>
		<category><![CDATA[front-end]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tutorial]]></category>
		<guid isPermaLink="false">https://bitcolor.com.br/?p=19</guid>

					<description><![CDATA[Um vídeo tutorial para quem ainda não conhece jSon, poder entender o funcionamento básico do compartilhamento de dados usando essa tecnologia.]]></description>
										<content:encoded><![CDATA[<p>Hoje estou postando um vídeo tutorial para quem ainda não conhece jSon, poder entender o funcionamento básico do compartilhamento de dados usando essa tecnologia.Como base, usaremos o PHP e o jQuery (ótima biblioteca Javascript).</p>
<p>Claro que por se tratar de um vídeo não é tão fácil ficar acompanhando o código. Por isso mesmo, estamos disponibilizando aqui o código para que você possa entender.</p>
<div class="videoWrapper"><iframe loading="lazy" src="//www.youtube.com/embed/9x47niEJk_M" width="640" height="360" frameborder="0" allowfullscreen="allowfullscreen"></iframe></div>
<p>Aproveite e deixe um comentário aqui em baixo, ou no YouTube e assine o nosso canal!</p>
<p>Script para criar a tabela no postgres:</p>
<pre class="prettyprint">CREATE TABLE jogos
(
id serial NOT NULL,
nome text,
console text,
preco numeric(10,2)
)</pre>
<p>dados.php:</p>
<pre class="prettyprint">/**
 * Tutorial jSON
 */

//Definir formato de arquivo
 header('Content-Type:' . "text/plain");

$host = "localhost"; // IP do Banco
 $user = "postgres"; // Usuário
 $pswd = "postgres"; // Senha
 $dbname = "tutoriais"; // Banco
 $con = null; // Conexão

$con = @pg_connect("host=$host user=$user password=$pswd dbname=$dbname") or die (pg_last_error($con));

//@pg_close($con); //Encerrrar Conexão

if(!$con) {
 echo '[{"erro": "Não foi possível conectar ao banco"';
 echo '}]';
 }else {
 //SQL de BUSCA LISTAGEM
 $sql = "SELECT * FROM jogos ORDER BY console";
 $result = pg_query($sql); //Executar a SQL
 $n = pg_num_rows($result); //Número de Linhas retornadas

if (!$result) {
 //Caso não haja retorno
 echo '[{"erro": "Há algum erro com a busca. Não retorna resultados"';
 echo '}]';
 }else if($n&lt;1) {
 //Caso não tenha nenhum item
 echo '[{"erro": "Não há nenhum dado cadastrado"';
 echo '}]';
 }else {
 //Mesclar resultados em um array
 for($i = 0; $i&lt;$n; $i++) { $dados[] = pg_fetch_assoc($result, $i); } echo json_encode($dados, JSON_PRETTY_PRINT); } } ?&gt;</pre>
<p><!--?php &lt;br ?--><br />
index.html:</p>
<pre class="prettyprint">&lt;!DOCTYPE HTML&gt;
&lt;html lang="pt-br"&gt;
	&lt;head&gt;
		&lt;meta charset="UTF-8"&gt;
		&lt;link rel="icon" type="favicon.png" /&gt;
		&lt;link rel="stylesheet" type="text/css" href="estilo.css"&gt;
		
		&lt;!--jQuery--&gt;
		&lt;script src="http://code.jquery.com/jquery-2.0.3.min.js" type="text/javascript"&gt;&lt;/script&gt;
		&lt;!--Script--&gt;
		&lt;script src="script.js" type="text/javascript"&gt;&lt;/script&gt;
		
		
	&lt;/head&gt;
	&lt;body onload="carregarItens()"&gt;
		&lt;section&gt;
			&lt;h1&gt;PortilloDesign Tutorial JSON + PHP&lt;/h1&gt;
			&lt;!--Área que mostrará carregando--&gt;
			&lt;h2&gt;&lt;/h2&gt;
			&lt;!--Tabela--&gt;
			&lt;table id="minhaTabela"&gt;
				&lt;caption&gt;Cadastro de Jogos&lt;/caption&gt;
				&lt;thead&gt;
					&lt;th&gt;ID&lt;/th&gt;
					&lt;th&gt;Jogo&lt;/th&gt;
					&lt;th&gt;Console&lt;/th&gt;
					&lt;th&gt;Valor&lt;/th&gt;
				&lt;/thead&gt;
				&lt;tbody&gt;
				&lt;/tbody&gt;
			&lt;/table&gt;
		&lt;/section&gt;
	&lt;/body&gt;
&lt;/html&gt;</pre>
<p>script.js:</p>
<pre class="prettyprint">/**
* Capturar itens do banco de dados
*/
function carregarItens(){
	//variáveis
	var itens = "", url = "dados/dados.php";

    //Capturar Dados Usando Método AJAX do jQuery
    $.ajax({
	    url: url,
	    cache: false,
	    dataType: "json",
	    beforeSend: function() {
		    $("h2").html("Carregando..."); //Carregando
	    },
	    error: function() {
		    $("h2").html("Há algum problema com a fonte de dados");
	    },
	    success: function(retorno) {
		    if(retorno[0].erro){
			    $("h2").html(retorno[0].erro);
		    }
		    else{
			    //Laço para criar linhas da tabela
			    for(var i = 0; i&lt;retorno.length; i++){
				    itens += "&lt;tr&gt;";
				    itens += "&lt;td&gt;" + retorno[i].id + "&lt;/td&gt;";
				    itens += "&lt;td&gt;" + retorno[i].nome + "&lt;/td&gt;";
				    itens += "&lt;td&gt;" + retorno[i].console + "&lt;/td&gt;";
				    itens += "&lt;td&gt;" + retorno[i].preco + "&lt;/td&gt;";
				    itens += "&lt;/tr&gt;";
			    }
			    //Preencher a Tabela
			    $("#minhaTabela tbody").html(itens);
			    
			    //Limpar Status de Carregando
			    $("h2").html("Carregado");
		    }
	    }
    });
}</pre>
]]></content:encoded>
					
					<wfw:commentRss>https://velhobit.com.br/programacao/implementando-a-integracao-entre-php-jquery-json.html/feed</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
