<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Elisangela Silva </title>
    <description>The latest articles on DEV Community by Elisangela Silva  (@likannp).</description>
    <link>https://dev.to/likannp</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F350738%2Fbcee204f-7575-4f5a-b9d4-7cfadb864f3e.jpeg</url>
      <title>DEV Community: Elisangela Silva </title>
      <link>https://dev.to/likannp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/likannp"/>
    <language>en</language>
    <item>
      <title>Desbravador, os segredos do JavaScript aguardam em sua mochila! 🎒🔮 (variáveis)</title>
      <dc:creator>Elisangela Silva </dc:creator>
      <pubDate>Fri, 21 Mar 2025 20:14:37 +0000</pubDate>
      <link>https://dev.to/likannp/desbravador-os-segredos-do-javascript-aguardam-em-sua-mochila-variaveis-2l1h</link>
      <guid>https://dev.to/likannp/desbravador-os-segredos-do-javascript-aguardam-em-sua-mochila-variaveis-2l1h</guid>
      <description>&lt;p&gt;Um dos grandes segredos para se dar bem com JavaScript (e frameworks que são baseados nele) é dominar o básico e praticar até que fique natural. Ignorar esses fundamentos ou não dar a devida importância a eles é um dos erros mais comuns que podemos cometer. Por isso, vamos começar nossa jornada de estudos com calma, explorando cada detalhe da Sintaxe Básica e, claro, botando a mão na massa com alguns exercícios.🛠️📚&lt;/p&gt;

&lt;p&gt;Um dos primeiros passos em qualquer jornada de programação, assim como em uma aventura de ✨RPG✨, é conhecer suas ferramentas básicas. No mundo de JavaScript, as variáveis são como os itens da sua mochila: &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt; e &lt;code&gt;var&lt;/code&gt;. Cada uma tem seu próprio poder e propósito, e você não pode simplesmente jogar um dado 🎲 e escolher uma aleatoriamente. Elas têm seus segredos e momentos certos para serem usadas, então é importante entender qual delas vai te ajudar a vencer cada desafio! 🧙‍♂️✨&lt;/p&gt;

&lt;h2&gt;
  
  
  var 🧙‍♀️
&lt;/h2&gt;

&lt;p&gt;Nossa primeira variável, a &lt;code&gt;var&lt;/code&gt;, é como um mago antigo: poderosa, mas cheia de truques que podem confundir até os aventureiros mais experientes. Ela tem escopo de função, o que significa que, onde quer que você a declare dentro de uma função, ela estará acessível em todo o território dessa função. Além disso, ela tem uma habilidade especial chamada Hoisting, que faz com que o JavaScript "içe" sua declaração para o topo do escopo durante a fase de compilação. Em outras palavras, mesmo que você declare a &lt;code&gt;var&lt;/code&gt; no meio do código, o JavaScript age como se ela tivesse sido declarada lá no começo. 🪄&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function exemploHoisting() {
    console.log(arma); // undefined (hoisting)
    var arma = "Espada Flamejante 🔥⚔️";
    console.log(arma); // "Espada Flamejante 🔥⚔️"
}
exemploHoisting();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ela também é bastante flexível: você pode &lt;strong&gt;reatribuir&lt;/strong&gt; e &lt;strong&gt;redeclarar&lt;/strong&gt; valores a uma &lt;code&gt;var&lt;/code&gt; quantas vezes quiser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function exemploRedeclaracao() {
    var poder = "Fogo 🔥";;
    console.log(poder); // "Fogo 🔥"

    var poder = "Gelo ❄️"; // Redeclarando a mesma variável
    console.log(poder); // "Gelo ❄️"

    poder = "Raio ⚡"; // Reatribuindo valor
    console.log(poder); // "Raio ⚡"
}

exemploRedeclaracao();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parece incrível, né? Mas, como todo grande poder, isso vem com uma grande responsabilidade... ou, no caso, alguns problemas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Por causa do hoisting, a &lt;code&gt;var&lt;/code&gt; é inicializada com &lt;code&gt;undefined&lt;/code&gt;. Isso pode levar a situações estranhas, especialmente se você tentar usar a variável antes de declarar ou atribuir um valor a ela. Imagine tentar usar uma poção antes de enchê-la! 🧪&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(x); // undefined (não dá erro, mas o valor é undefined)
var x = 10;
console.log(x); // 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, o JavaScript não reclama quando você tenta acessar &lt;code&gt;x&lt;/code&gt; antes de declarar, mas ele te entrega um &lt;code&gt;undefined&lt;/code&gt;. Isso pode causar bugs difíceis de rastrear, especialmente em projetos maiores. Por isso, hoje em dia, muitos aventureiros preferem usar &lt;code&gt;let&lt;/code&gt; e &lt;code&gt;const&lt;/code&gt;, que são mais previsíveis e seguras. Mas, mesmo assim, entender a &lt;code&gt;var&lt;/code&gt; é essencial para dominar os segredos do JavaScript! 🛡️⚔️&lt;/p&gt;

&lt;h2&gt;
  
  
  let 🛡️
&lt;/h2&gt;

&lt;p&gt;Se a &lt;code&gt;var&lt;/code&gt; é como um mago antigo cheio de truques, o &lt;code&gt;let&lt;/code&gt; é como um guerreiro confiável e previsível. Ele foi introduzido no JavaScript (ES6) para resolver muitos dos problemas que a &lt;code&gt;var&lt;/code&gt; trazia, especialmente aqueles relacionados ao escopo e ao hoisting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Escopo de Bloco 🧱
&lt;/h3&gt;

&lt;p&gt;Diferente da &lt;code&gt;var&lt;/code&gt;, que tem escopo de função, o &lt;code&gt;let&lt;/code&gt; tem &lt;strong&gt;escopo de bloco&lt;/strong&gt;. Isso significa que ele só existe dentro do bloco onde foi declarado (seja um &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;, ou qualquer coisa entre chaves &lt;code&gt;{}&lt;/code&gt;). É como se ele fosse uma ferramenta que você só pode usar dentro de uma sala específica do seu castelo. 🏰&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function exemploEscopo() {
    if (true) {
        let arma = "Arco Flamejante 🏹🔥";
        console.log(arma); // "Arco Flamejante 🏹🔥" (dentro do bloco if)
    }
    console.log(arma); // Erro! "arma" não está definida fora do bloco if.
}
exemploEscopo();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, a variável arma só existe dentro do bloco &lt;code&gt;if&lt;/code&gt;. Se você tentar usá-la fora dele, o JavaScript vai te dar um erro. Isso evita confusões e bugs, já que você sabe exatamente onde a variável pode ser usada. 🎯&lt;/p&gt;

&lt;h3&gt;
  
  
  Sem Hoisting Enganoso 🚫
&lt;/h3&gt;

&lt;p&gt;O &lt;code&gt;let&lt;/code&gt; também sofre &lt;strong&gt;hoisting&lt;/strong&gt;, mas de uma forma mais segura. Ele é "içado" para o topo do bloco, mas não é &lt;strong&gt;inicializado até que a declaração seja encontrada no código&lt;/strong&gt;. Isso significa que, se você tentar acessar a variável antes de declará-la, o JavaScript vai te avisar com um erro, em vez de te dar um &lt;code&gt;undefined&lt;/code&gt; silencioso.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function exemploHoistingLet() {
    console.log(poder); // Erro! "poder" não foi definido.
    let poder = "Invisibilidade 🕶️";
    console.log(poder); // "Invisibilidade 🕶️"
}
exemploHoistingLet();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, o JavaScript não deixa você usar a variável antes de declarar, o que evita aqueles bugs chatos que a var pode causar.🐛&lt;/p&gt;

&lt;h3&gt;
  
  
  Reatribuição, mas sem Redeclaração 🔄
&lt;/h3&gt;

&lt;p&gt;Com o &lt;code&gt;let&lt;/code&gt;, você pode &lt;strong&gt;reatribuir&lt;/strong&gt; valores a uma variável, mas &lt;strong&gt;não pode redeclarar&lt;/strong&gt; a mesma variável no mesmo escopo. Isso ajuda a evitar conflitos e mantém seu código mais organizado.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function exemploReatribuicao() {
    let magia = "Bola de Fogo 🔥";
    console.log(magia); // "Bola de Fogo 🔥"

    magia = "Nevasca ❄️"; // Reatribuindo valor
    console.log(magia); // "Nevasca ❄️"

    // let magia = "Raio ⚡"; // Erro! Não pode redeclarar.
}

exemploReatribuicao();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  const 🧙‍♀️
&lt;/h2&gt;

&lt;p&gt;Se a &lt;code&gt;var&lt;/code&gt; é o mago antigo e o &lt;code&gt;let&lt;/code&gt; é o guerreiro confiável, a &lt;code&gt;const&lt;/code&gt; é como um artefato mágico: uma vez criada, ela não pode ser alterada. Ela foi introduzida no JavaScript (ES6) para lidar com valores que &lt;strong&gt;não devem mudar&lt;/strong&gt; ao longo do tempo, como constantes matemáticas, configurações ou referências a objetos imutáveis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Escopo de Bloco 🧱
&lt;/h3&gt;

&lt;p&gt;Assim como o &lt;code&gt;let&lt;/code&gt;, a &lt;code&gt;const&lt;/code&gt; tem &lt;strong&gt;escopo de bloco&lt;/strong&gt;. Isso significa que ela só existe dentro do bloco onde foi declarada. Se você tentar acessá-la fora desse bloco, o JavaScript vai te avisar com um erro.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function exemploEscopoConst() {
    if (true) {
        const tesouro = "Baú de Ouro 💰";
        console.log(tesouro); // "Baú de Ouro 💰" (dentro do bloco if)
    }
    console.log(tesouro); // Erro! "tesouro" não está definido fora do bloco if.
}
exemploEscopoConst();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui, a variável &lt;code&gt;tesouro&lt;/code&gt; só existe dentro do bloco &lt;code&gt;if&lt;/code&gt;. Fora dele, ela é inacessível, o que ajuda a manter o código organizado e seguro. 🗝️&lt;/p&gt;

&lt;h3&gt;
  
  
  Sem Hoisting Enganoso 🚫
&lt;/h3&gt;

&lt;p&gt;Assim como o &lt;code&gt;let&lt;/code&gt;, a &lt;code&gt;const&lt;/code&gt; também sofre &lt;strong&gt;hoisting&lt;/strong&gt;, mas não pode ser acessada antes da declaração. Se você tentar, o JavaScript vai te dar um erro, evitando comportamentos inesperados.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function exemploHoistingConst() {
    console.log(artefato); // Erro! "artefato" não foi definido.
    const artefato = "Amuleto da Proteção 🛡️";
    console.log(artefato); // "Amuleto da Proteção 🛡️"
}
exemploHoistingConst();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Imutabilidade (Quase) Absoluta 🔒
&lt;/h3&gt;

&lt;p&gt;Aqui está a principal característica da &lt;code&gt;const&lt;/code&gt;: &lt;strong&gt;ela não pode ser reatribuída&lt;/strong&gt;. Uma vez que você declara uma &lt;code&gt;const&lt;/code&gt; e atribui um valor a ela, esse valor não pode ser alterado. É como um selo mágico que protege seu tesouro. 🪙&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function exemploImutabilidade() {
    const PI = 3.14159;
    console.log(PI); // 3.14159

    // PI = 3.14; // Erro! Não pode reatribuir uma const.
}
exemploImutabilidade();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Mas atenção!&lt;/strong&gt; A &lt;code&gt;const&lt;/code&gt; não torna o valor em si imutável, apenas a *&lt;em&gt;referência *&lt;/em&gt;àquele valor. Se você usar &lt;code&gt;const&lt;/code&gt; com objetos ou arrays, ainda pode modificar suas propriedades ou elementos.&lt;/p&gt;

&lt;p&gt;Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function exemploObjetoConst() {
    const personagem = { nome: "Aragorn 🧝‍♂️", classe: "Guerreiro ⚔️" };
    console.log(personagem.nome); // "Aragorn 🧝‍♂️"

    personagem.nome = "Legolas 🏹"; // Isso é permitido!
    console.log(personagem.nome); // "Legolas 🏹"

    // personagem = { nome: "Gandalf 🧙‍♂️" }; // Erro! Não pode reatribuir a variável.
}
exemploObjetoConst();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  Resumindo a Jornada das Variáveis 🛡️⚔️
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;var&lt;/code&gt;: O mago antigo, poderoso, mas cheio de truques. Escopo de função e hoisting podem causar confusão. 🧙‍♂️&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;let&lt;/code&gt;: O guerreiro confiável. Escopo de bloco e sem hoisting enganoso. Ideal para variáveis que precisam ser reatribuídas. 🛡️&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;const&lt;/code&gt;: O artefato mágico. Escopo de bloco e imutabilidade (quase absoluta). Perfeita para valores fixos e referências que não devem mudar. 🧙‍♀️&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Upgrade do Rails 4.2.7 para o Rails 5.2.6</title>
      <dc:creator>Elisangela Silva </dc:creator>
      <pubDate>Wed, 24 Nov 2021 20:17:37 +0000</pubDate>
      <link>https://dev.to/likannp/upgrade-do-rails-427-para-o-rails-526-144c</link>
      <guid>https://dev.to/likannp/upgrade-do-rails-427-para-o-rails-526-144c</guid>
      <description>&lt;p&gt;Hi guys! Espero que vocês estejam bem e seguros. 😃 Bom, esses dias recebi a missão de atualizar as versões do ruby (2.3.7 para 2.6.6) e rails (7.2.7 para 5.2.6) em um dos projetos do trabalho. Tinha em mente que iria ser chatinho e cansativo, mas não imaginava que tanto, kkkkkk.&lt;/p&gt;

&lt;p&gt;Irei abordar os pontos que considero importantes e que gostaria de ter ouvido antes de iniciar esta jornada. 😃 &lt;/p&gt;

&lt;p&gt;Inicialmente testei o simples, adicionei no Gemfile as versões que desejava do ruby e rails, e em seguida executei o &lt;code&gt;bundle install&lt;/code&gt; para atualizar as novas versões no Gemfile.Lock. Obtive como resposta vários erros sobre as versões das gems, isso porque as versões que estavam no projeto não suportavam o rails 5.x ou estavam depreciadas.&lt;/p&gt;

&lt;p&gt;Iniciei as atualizações das gems pelo bundler, adicionando uma versão compatível e estável com a versão do rails 5.x. Esse é um ponto importante pois algumas versões de gems necessitam de uma versão mais atualizada do bundler. Eu por exemplo, atualizei da versão ‘1.17.3’ para '~&amp;gt; 2.1', '&amp;gt;= 2.1.4' e em seguida executei o &lt;code&gt;bundle install&lt;/code&gt;, obtive alguns erros mas esperado pois não tinha atualizado as demais gems. E assim fui atualizando as versões das gems de cima para baixo, adicionando versões compatíveis e estáveis com a versão do rails 5.x, utilizando o RubyGems e documentação das próprias como referência.&lt;/p&gt;

&lt;p&gt;Algumas gems podem estar depreciadas, por exemplo, a &lt;code&gt;gem 'quiet_assets'&lt;/code&gt;, o próprio rails agora tem uma solução. Neste caso não será necessário encontrar uma substituta, mas em outros casos pode ser necessário. Depois de atualizar algumas versões, rodei o &lt;code&gt;bundle install&lt;/code&gt; e obtive o mesmo erro do início, mesmo não sendo recomendado pela comunidade, decidi pela exclusão do Gemfile.Lock e rodar novamente o &lt;code&gt;bundle install&lt;/code&gt;, a partir daí consegui rodar e gerar um novo Gemfile.Lock atualizado 😃 . Agora vamos para as configurações.&lt;/p&gt;

&lt;p&gt;Na &lt;a href="https://guiarails.com.br/upgrading_ruby_on_rails.html#:~:text=1.4%20A%20Tarefa%20de%20Atualiza%C3%A7%C3%A3o" rel="noopener noreferrer"&gt;documentação&lt;/a&gt; do Rails podemos encontrar os próximos passos. Quando rodar o &lt;code&gt;rails app:update&lt;/code&gt; será apresentado no terminal alguns ajustes que podem ser realizados nos arquivos já existentes, neste momento você deve ter cuidado principalmente nas configs e não terminar modificando as configurações personalizadas do projetos, tente mudar o mínimo possível e consulte a &lt;a href="https://guiarails.com.br/upgrading_ruby_on_rails.html" rel="noopener noreferrer"&gt;documentação&lt;/a&gt; sempre sobre alguma mudança nas configurações padrões do Rails. Também serão adicionados novos arquivos.&lt;/p&gt;

&lt;p&gt;O próximo passo foi rodar o &lt;code&gt;rails server&lt;/code&gt;, apareceram outros erros por causa de código depreciado. O primeiro foi o &lt;code&gt;alias_method_chain&lt;/code&gt; que foi &lt;a href="https://api.rubyonrails.org/v5.0.0/classes/Module.html#:~:text=alias_method_chain(target%2C%20feature)" rel="noopener noreferrer"&gt;desatualizado&lt;/a&gt;. O segundo foi com o ActiveRecord::Migration não ser suportado, sendo assim necessario atualização das migrations para ActiveRecord::Migration[5.2], nesse &lt;a href="https://stackoverflow.com/questions/48815984/rails5-directly-inheriting-from-from-activerecordmigration-is-not-supported-s" rel="noopener noreferrer"&gt;link&lt;/a&gt; tem um exemplo de como faz.&lt;/p&gt;

&lt;p&gt;Depois desses ajustes consegui iniciar o servidor, agora é testar todo projeto, não deixar escapar nenhum detalhe, todas funcionalidades devem ser testadas. Essa parte é importante para analisar se está tudo funcionando ou se será necessário ajustes, por exemplo pode ocorrer de uma funcionalidade não está funcionando no projeto porque a gem não é mais utilizada daquela forma e será necessário atualização no código para usar aquela gem.&lt;/p&gt;

&lt;p&gt;Por não conter testes no projeto, foi necessário uma bateria extensa de testes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REFERENCIA BIBLIOGRAFICA&lt;/strong&gt;&lt;br&gt;
Atualizando o Ruby on Rails - &lt;a href="https://guiarails.com.br/upgrading_ruby_on_rails.html" rel="noopener noreferrer"&gt;https://guiarails.com.br/upgrading_ruby_on_rails.html&lt;/a&gt;&lt;br&gt;
RubyGems -&lt;a href="https://rubygems.org/" rel="noopener noreferrer"&gt;https://rubygems.org/&lt;/a&gt; &lt;br&gt;
Descontinuação do alias_method_chain - &lt;a href="https://api.rubyonrails.org/v5.0.0/classes/Module.html#:%7E:text=alias_method_chain(target%2C%20feature)" rel="noopener noreferrer"&gt;https://api.rubyonrails.org/v5.0.0/classes/Module.html#:~:text=alias_method_chain(target%2C%20feature)&lt;/a&gt;&lt;br&gt;
ActiveRecord::Migration is not supported - &lt;a href="https://stackoverflow.com/questions/48815984/rails5-directly-inheriting-from-from-activerecordmigration-is-not-supported-s" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/48815984/rails5-directly-inheriting-from-from-activerecordmigration-is-not-supported-s&lt;/a&gt;&lt;br&gt;
Descontinuação do before_filter - &lt;a href="https://stackoverflow.com/questions/41572287/deprecation-warning-before-filter-is-deprecated-and-will-be-removed-in-rails-5" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/41572287/deprecation-warning-before-filter-is-deprecated-and-will-be-removed-in-rails-5&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Validação e Formatação de Formulários: Client-Side vs. Server-Side</title>
      <dc:creator>Elisangela Silva </dc:creator>
      <pubDate>Sat, 22 May 2021 11:39:46 +0000</pubDate>
      <link>https://dev.to/likannp/validacao-e-formatacao-de-campos-e-dados-com-html-e-javascript-3l9g</link>
      <guid>https://dev.to/likannp/validacao-e-formatacao-de-campos-e-dados-com-html-e-javascript-3l9g</guid>
      <description>&lt;p&gt;Artigo atualizado dia 22/03/2025&lt;/p&gt;

&lt;p&gt;Olá, pessoal! &lt;/p&gt;

&lt;p&gt;Hoje vamos explorar um pouco sobre &lt;strong&gt;validação e formatação de dados&lt;/strong&gt; no &lt;strong&gt;client-side&lt;/strong&gt; (navegador) e no &lt;strong&gt;server-side&lt;/strong&gt; (servidor). &lt;/p&gt;

&lt;p&gt;Este artigo presume que você já conhece o &lt;a href="https://developer.mozilla.org/pt-BR/docs/Learn/HTML/Introduction_to_HTML" rel="noopener noreferrer"&gt;básico de HTML&lt;/a&gt; e &lt;a href="https://developer.mozilla.org/pt-BR/docs/Learn/JavaScript" rel="noopener noreferrer"&gt;JavaScript&lt;/a&gt;. Caso não, deixei dois links para você começar sua jornada.&lt;/p&gt;

&lt;p&gt;Em alguns momentos, utilizarei &lt;strong&gt;Expressões Regulares&lt;/strong&gt; (regex). Se você não está familiarizado com o conceito, recomendo este artigo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tableless.com.br/o-basico-sobre-expressoes-regulares/" rel="noopener noreferrer"&gt;O básico sobre expressões regulares&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Sumário
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introdução&lt;/li&gt;
&lt;li&gt;Campo que permite apenas letras&lt;/li&gt;
&lt;li&gt;Campo para e-mail&lt;/li&gt;
&lt;li&gt;Campo para CPF&lt;/li&gt;
&lt;li&gt;Campo para data de nascimento&lt;/li&gt;
&lt;li&gt;Campo para celular e telefone fixo&lt;/li&gt;
&lt;li&gt;Campo para observação&lt;/li&gt;
&lt;li&gt;Conclusão&lt;/li&gt;
&lt;li&gt;Código completo no Codepen&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Introdução &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Para ilustrar os conceitos, vamos utilizar um formulário simples. Comecei criando um rascunho no &lt;a href="https://www.figma.com/" rel="noopener noreferrer"&gt;Figma&lt;/a&gt;, uma ferramenta incrível para design de interfaces. Confira o resultado:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuic0gvovh5qmp5cm69bl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuic0gvovh5qmp5cm69bl.png" alt="Rascunho do formulário no Figma" width="385" height="604"&gt;&lt;/a&gt;&lt;/p&gt;
Rascunho do formulário criado no Figma.



&lt;p&gt;Agora, vamos implementar as validações e formatações!&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Campo que permite apenas letras &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Começaremos pelo campo &lt;strong&gt;Nome&lt;/strong&gt;, que deve aceitar apenas letras. Existem duas abordagens para isso:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Opção 1: Usando o atributo &lt;code&gt;pattern&lt;/code&gt; do HTML&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O atributo &lt;code&gt;pattern&lt;/code&gt; permite validar o valor de um campo usando uma expressão regular. Ele funciona com inputs do tipo &lt;code&gt;text&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;tel&lt;/code&gt;, entre outros.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"nome"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Nome:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"nome"&lt;/span&gt; &lt;span class="na"&gt;pattern=&lt;/span&gt;&lt;span class="s"&gt;"[A-Za-zÀ-ú\s]+"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Apenas letras"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;[A-Za-zÀ-ú\s]+&lt;/code&gt;&lt;/strong&gt;: Aceita letras maiúsculas, minúsculas, acentuadas e espaços.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;required&lt;/code&gt;&lt;/strong&gt;: Garante que o campo não seja enviado vazio.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quando o usuário tenta enviar o formulário com dados inválidos, uma mensagem de erro é exibida:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5pofmzt47rh95u24j9jr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5pofmzt47rh95u24j9jr.png" alt="Mensagem de erro ao enviar dados inválidos" width="447" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Opção 2: Bloqueando números com JavaScript&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Outra abordagem é impedir que números sejam digitados no campo. Para isso, usamos o evento &lt;code&gt;keydown&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"nome"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nomeClient"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Apenas letras"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;inputNome&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.nomeClient&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;inputNome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;9&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Bloqueia a tecla pressionada&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  2. Campo para e-mail &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Para validar e-mails, podemos usar o atributo &lt;code&gt;type="email"&lt;/code&gt; do HTML. Ele verifica se o valor contém um &lt;code&gt;@&lt;/code&gt; e um domínio válido.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;E-mail:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"exemplo@dominio.com"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se o e-mail for inválido, o navegador exibe uma mensagem de erro:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fziduyjbe07w5j2dvhr0m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fziduyjbe07w5j2dvhr0m.png" alt="Mensagem de erro para e-mail inválido" width="609" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observação&lt;/strong&gt;: A validação no client-side é útil para melhorar a experiência do usuário, mas &lt;strong&gt;nunca substitui&lt;/strong&gt; a validação no server-side.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Campo para CPF &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;A validação de CPF envolve três etapas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Bloquear letras e caracteres especiais.&lt;/li&gt;
&lt;li&gt;Verificar se o CPF tem 11 dígitos.&lt;/li&gt;
&lt;li&gt;Validar o CPF usando o algoritmo da Receita Federal.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Código Completo para CPF&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"cpf"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;CPF:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cpf"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Apenas números"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"erro_cpf"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mensagem-erro"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display: none;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;CPF inválido!&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;campoCPF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#cpf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;campoCPF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;z&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Bloqueia letras&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;campoCPF&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blur&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cpf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\D&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Remove não dígitos&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;validarCPF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cpfFormatado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(\d{3})(\d{3})(\d{3})(\d{2})&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$1.$2.$3-$4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cpfFormatado&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;erro_cpf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;erro_cpf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validarCPF&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cpf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Implementação do algoritmo da Receita Federal&lt;/span&gt;
  &lt;span class="c1"&gt;// (Código omitido para brevidade)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Campo para data de nascimento &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Para o campo de data de nascimento, podemos usar o tipo &lt;code&gt;date&lt;/code&gt; do HTML, que já inclui uma validação básica.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"data_nascimento"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Data de Nascimento:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"date"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"data_nascimento"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. Campo para celular e telefone fixo &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Para telefones, usamos o atributo &lt;code&gt;maxlength&lt;/code&gt; para limitar o número de caracteres e regex para formatação.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"celular"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Celular:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"celular"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Apenas números"&lt;/span&gt; &lt;span class="na"&gt;maxlength=&lt;/span&gt;&lt;span class="s"&gt;"11"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"telefone"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Telefone Fixo:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"telefone"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Apenas números"&lt;/span&gt; &lt;span class="na"&gt;maxlength=&lt;/span&gt;&lt;span class="s"&gt;"10"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Formatação para celular&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#celular&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blur&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;numero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\D&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(\d{2})(\d{5})(\d{4})&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;($1) $2-$3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Formatação para telefone fixo&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#telefone&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blur&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;numero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\D&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;numero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(\d{2})(\d{4})(\d{4})&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;($1) $2-$3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Campo para observação &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Para campos de texto longo, usamos a tag &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"observacao"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Observação:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"observacao"&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Limite de 100 caracteres"&lt;/span&gt; &lt;span class="na"&gt;maxlength=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusão &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Neste artigo, exploramos como validar e formatar dados no client-side usando HTML e JavaScript. Lembre-se de que a validação no client-side é importante para melhorar a experiência do usuário, mas &lt;strong&gt;nunca deve substituir&lt;/strong&gt; a validação no server-side, que garante a segurança e integridade dos dados.&lt;/p&gt;

&lt;p&gt;Confira o código completo no Codepen:&lt;br&gt;&lt;br&gt;
&lt;a href="https://codepen.io/elisangelamsilva/pen/WNRVwbw" rel="noopener noreferrer"&gt;Ver código no Codepen&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se tiver dúvidas, sugestões ou críticas, deixe um comentário abaixo.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Gerando PDF com a gem wicked_pdf no Rails 6</title>
      <dc:creator>Elisangela Silva </dc:creator>
      <pubDate>Sun, 25 Apr 2021 03:30:48 +0000</pubDate>
      <link>https://dev.to/likannp/gerando-pdf-com-a-gem-wickedpdf-no-rails-6-1894</link>
      <guid>https://dev.to/likannp/gerando-pdf-com-a-gem-wickedpdf-no-rails-6-1894</guid>
      <description>&lt;p&gt;Hi guys! Espero que vocês estejam bem e seguros 😃. Sou iniciante no Rails e esses dias no trabalho surgiu uma tasks envolvendo a gem wicked_pdf, decidi estudá-la e escrever esse artigo. Espero que gostem! &lt;/p&gt;

&lt;p&gt;Dividirei o artigo em duas partes, a primeira parte abordarei as instalações e ajustes necessários,e na segunda parte desenvolverei uma aplicação simples. &lt;/p&gt;

&lt;p&gt;Iniciaremos criando a aplicação utilizando o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rails new schedule
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ela se chamará Schedule.&lt;/p&gt;

&lt;p&gt;Logo em seguida utilizando o seguinte comando para criar view e controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rails generate controller Schedule index --skip-routes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ajuste da rota:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="s2"&gt;"schedule#index"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora você pode rodar a aplicação:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rails s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1y43l613yicnwicmxkjr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1y43l613yicnwicmxkjr.png" alt="image" width="322" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Caso você não tenha ideia do que esses comandos acima fazem, sua jornada inicia por esse &lt;a href="https://guiarails.com.br/getting_started.html" rel="noopener noreferrer"&gt;link&lt;/a&gt;, este link tem um tutorial legal para iniciantes. &lt;/p&gt;

&lt;h3&gt;
  
  
  1. Instalações e Ajustes
&lt;/h3&gt;

&lt;p&gt;Tudo ok até aqui?! Caso sim, vamos prosseguir.  A &lt;a href="https://github.com/mileszs/wicked_pdf" rel="noopener noreferrer"&gt;documentação da gem&lt;/a&gt; mostra o passo a passo de como a gem deve ser instalada, ela funciona nas versões do Rails abaixo do 6, a partir dessa versão vocês terão que realizar algumas modificações que iremos tratar nesse artigo.&lt;/p&gt;

&lt;p&gt;Vamos iniciar adicionando a gem ao Gemfile e executar bundle install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt;  &lt;span class="s1"&gt;'wicked_pdf'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora crie o initializer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rails generate wicked_pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depois de adicionar a gem wicked_pdf, precisamos incluir um detalhe. O wicked_pdf usa o binário &lt;a href="https://wkhtmltopdf.org/" rel="noopener noreferrer"&gt;wkhtmltopdf&lt;/a&gt; que, por sua vez, é baseado no WebKit. Sua funcionalidade é pegar um documento HTML e passar para o wkhtmltopdf que converte em um documento PDF que pode ser baixado pelo usuário.&lt;/p&gt;

&lt;p&gt;Então vamos adicionar a gem do wkhtmltopdf ao Gemfile e execute bundle install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt;  &lt;span class="s1"&gt;'wkhtmltopdf-binary'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O problema inicia agora, quando você tenta rodar o servidor aparece no console um erro parecido com esse aqui:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: No such file or directory @ rb_sysopen - /home/user/folder/schedele/config/webpacker.yml (RuntimeError)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Desde o Rails 6, o Webpacker é o compilador JavaScript padrão. Portanto, você também terá que configurá-lo antes de iniciar seu servidor Rails. &lt;/p&gt;

&lt;p&gt;Existem algumas resoluções legais nessa &lt;a href="https://github.com/rails/webpacker/issues/940" rel="noopener noreferrer"&gt;issue&lt;/a&gt;, recomendo que você leia e até tente, vou disponibilizar abaixo o que funcionou comigo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Certifique-se que você tem o yarn instalado ou ou dê uma olhada em &lt;a href="https://yarnpkg.com/en/docs/install" rel="noopener noreferrer"&gt;https://yarnpkg.com/en/docs/install&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; Será necessário o nodejs na versão 10.17.0&lt;/li&gt;
&lt;li&gt; Configure
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rails webpacker:install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; Certifique-se que todos os pacotes estão atualizados
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn install --check-files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Agora teste iniciando seu servidor Rails
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ rails s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Desenvolvendo a aplicação
&lt;/h3&gt;

&lt;p&gt;Tudo ok até aqui? Caso sim, vamos dar continuidade na construção da aplicação.&lt;/p&gt;

&lt;p&gt;Iniciei essa segunda parte pelo controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ScheduleController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;AplicationController&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;relatorio&lt;/span&gt;
      &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;pdf: &lt;/span&gt;&lt;span class="s2"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;layout: &lt;/span&gt;&lt;span class="s2"&gt;"application.pdf.erb"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="ss"&gt;template: &lt;/span&gt;&lt;span class="s2"&gt;"schedule/relatorio.pdf.erb"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A action index será a view principal. Já a action relatorio será responsável por renderizar o pdf. &lt;/p&gt;

&lt;p&gt;Criei o arquivo "application.pdf.erb" onde será definido o layout principal do pdf.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#app/views/layouts/application.pdf.erb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Schedule&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width,initial-scale=1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;csrf_meta_tags&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;csp_meta_tag&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;yield&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#app/views/schedele/relatorio.pdf.erb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Hello Word!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adicionei a rota da nova action no arquivo routes.rb&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="s2"&gt;"schedule#index"&lt;/span&gt;
  &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s2"&gt;"relatorio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s2"&gt;"shedule#relatorio"&lt;/span&gt;
  &lt;span class="ss"&gt;resources: :schedele&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Na view index, adicionei o helper to_link com a path da action que irá renderizar o arquivo pdf.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Schedule#index&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Find me in app/views/schedule/index.html.erb&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;link_to&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;Create&lt;/span&gt; &lt;span class="na"&gt;PDF&lt;/span&gt; &lt;span class="na"&gt;document&lt;/span&gt;&lt;span class="err"&gt;',&lt;/span&gt; &lt;span class="na"&gt;relatorio_path&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="na"&gt;format:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;pdf&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;) =&lt;/span&gt;&lt;span class="s"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdxzw0havy3zmp53sw7ob.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdxzw0havy3zmp53sw7ob.png" alt="Tela com o botão para criar o PDF" width="388" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A partir daí consegui gerar o pdf: &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2w5ezxr6adjmcz1u2ext.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2w5ezxr6adjmcz1u2ext.png" alt="PDF com a mensagem " width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No repositório da &lt;a href="https://github.com/mileszs/wicked_pdf" rel="noopener noreferrer"&gt;gem&lt;/a&gt; tem dicas de como utlizar css, imagens e javascript no pdf.&lt;/p&gt;

&lt;p&gt;Qualquer duvida deixa nos comentários. Obrigada pela paciência e espero ter ajudado. Até mais!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Novo Recurso do GitHub - README no Perfil</title>
      <dc:creator>Elisangela Silva </dc:creator>
      <pubDate>Thu, 16 Jul 2020 16:51:12 +0000</pubDate>
      <link>https://dev.to/likannp/novo-recurso-do-github-readme-no-perfil-3fme</link>
      <guid>https://dev.to/likannp/novo-recurso-do-github-readme-no-perfil-3fme</guid>
      <description>&lt;p&gt;Nos últimos dias o GitHub disponibilizou um novo recurso na plataforma onde os usuários podem adicionar um readme e deixar em destaque no perfil. Vou mostrar o passo a passo de como adicionar.&lt;/p&gt;

&lt;p&gt;Primeiro você terá que criar um repositório com o mesmo nome do seu usuário. Por exemplo meu username é Elisangelamsilva ao adicionar aparecerá isso aqui:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4baem0htd3v7z4y7ia5p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4baem0htd3v7z4y7ia5p.png" alt="Alt Text" width="800" height="303"&gt;&lt;/a&gt;&lt;br&gt;
É necessário deixar público e marcar na opção de inicializar com o README.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv3okysv90ywue307ogg3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv3okysv90ywue307ogg3.png" alt="Alt Text" width="800" height="413"&gt;&lt;/a&gt;&lt;br&gt;
Visualização do perfil: &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F66rggwu66kg3yfm465vf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F66rggwu66kg3yfm465vf.png" alt="Alt Text" width="800" height="190"&gt;&lt;/a&gt;&lt;br&gt;
Agora você já pode personalizar como quiser, como exemplo adicionei apenas o ícone com link para o meu perfil no Linkedin.&lt;br&gt;
O próprio GitHub disponibiliza alguns exemplos do que pode ser adicionado, mas isso é por &lt;br&gt;
sua conta. Use com sabedoria e configure do seu jeito.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3jpmimdlryezme4u6nb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3jpmimdlryezme4u6nb9.png" alt="Alt Text" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Segue alguns links úteis para você deixar seu readme personalizado:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://gist.github.com/rxaviers/7360908?fbclid=IwAR19cyZ-fYj5isZXcoGaf_06WaHv_HaogQRAXYCiA7UZZCRZ7x5BWNJHqe0" rel="noopener noreferrer"&gt;Emoji Markup&lt;/a&gt;
2.&lt;a href="https://shields.io/?fbclid=IwAR1i_ORxVrmutODDj2HpXI3-iq4M7jyBMj7Cr0-_jWrOzg42-71OXBgvfEA" rel="noopener noreferrer"&gt;Conversão de imagens&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>github</category>
      <category>readme</category>
      <category>showdev</category>
    </item>
    <item>
      <title>PRINCIPAIS CONCEITOS DO PADRÃO MVC (MODEL-VIEW-CONTROLLER)</title>
      <dc:creator>Elisangela Silva </dc:creator>
      <pubDate>Fri, 10 Jul 2020 19:14:08 +0000</pubDate>
      <link>https://dev.to/likannp/principais-conceitos-do-padrao-mvc-model-view-controller-1o5a</link>
      <guid>https://dev.to/likannp/principais-conceitos-do-padrao-mvc-model-view-controller-1o5a</guid>
      <description>&lt;p&gt;Existem diversos padrões de arquitetura de software (design pattern) que podem ser aplicados para organizar o código de uma aplicação, e talvez o mais acessível deles seja o padrão MVC. Este padrão cria uma separação da implementação do software em camadas entre os dados da aplicação (model) e sua apresentação (view). Ações do usuário são interceptadas por um controller responsável em atualizar o modelo e refletir seu estado mais atual através de sua respectiva view.  Essa divisão em camadas torna mais fácil e define melhor as responsabilidades e proporciona uma independência. &lt;/p&gt;

&lt;p&gt;É altamente testável, pois quando se tem as camadas divididas onde cada parte está em  seu devido lugar e o desenvolvedor consegue testar cada parte de forma separada,  favorecendo o Desenvolvimento Dirigido por Testes (TDD). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7py33y398bt1zbahbp9b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7py33y398bt1zbahbp9b.png" alt="Alt Text" width="496" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O que significa cada sigla do MVC (MODEL-VIEW-CONTROLLER)&lt;/strong&gt;&lt;br&gt;
O &lt;strong&gt;model&lt;/strong&gt; seria o coração da aplicação, onde se tem a regra de negócio, entidades, aplicação do banco de dados, e tudo que pertença a aplicação em termo de regra de negócio e validação. &lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;view&lt;/strong&gt; onde temos a interface de comunicação com o usuário é responsável por renderizar a resposta da requisição seja ela em desktop ou web.  &lt;/p&gt;

&lt;p&gt;A camada &lt;strong&gt;controller&lt;/strong&gt; faz o controle do fluxo da aplicação, fazendo o intermédio de todo o fluxo a definir o que o usuário verá na tela. É a primeira camada que recebe requisição dentro do padrão MVC. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl70kh9s9ot3v12u0q2oo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fl70kh9s9ot3v12u0q2oo.png" alt="Alt Text" width="609" height="62"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Quando é necessário acessar o banco de dados para obter resposta. &lt;br&gt;
&lt;strong&gt;Fluxo com dados:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs6lry3h9nlfwjftsjz73.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs6lry3h9nlfwjftsjz73.png" alt="Alt Text" width="496" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como funciona?&lt;/strong&gt;&lt;br&gt;
O usuário em seu browser realiza uma requisição HTPP, que ao chegar ao controller que verifica e comunica ao model. O model realiza uma consulta ao banco de dados, retornando os dados requisitados para o mode, vale lembrar que essa parte do model é invisível ao usuário. O model retorna ao controller que tem o trabalho de renderizar a informação na view. A view retornará  um evento para o controller que devolverá a resposta HTPP para o browser onde o usuário poderá visualizar o que foi requerido. &lt;/p&gt;

&lt;p&gt;Caso não seja necessário acessar dados, a requisição não precisa passar pela camada model, pois a camada model que se liga ao banco de dados. &lt;br&gt;
&lt;strong&gt;Fluxo sem dados:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd26flx2yttu1idqyuf6i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd26flx2yttu1idqyuf6i.png" alt="Alt Text" width="432" height="226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementação&lt;/strong&gt; &lt;br&gt;
Isso depende da linguagem de programação que será utilizada e do contexto da aplicação. Normalmente haverá uma classe abstrata para cada um dos 3 elementos principais: Model, View e Controller. O programador desenvolve aplicações criando subclasses dessas classes abstratas onde cada aspecto do sistema vai ter seu model. Cada modelo terá 1 ou mais controladores e visões. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sugestão de leitura:&lt;/strong&gt; &lt;br&gt;
Use a Cabeça! Padrões de Projetos (livro).  &lt;/p&gt;

</description>
      <category>mvc</category>
      <category>designpattern</category>
      <category>padroes</category>
    </item>
  </channel>
</rss>
