Início / Exemplos de Código

💻 Exemplos de Código

Aplicações completas e trechos de código para você estudar, copiar e adaptar. Todos integrados com o JSON Server.

Experimente: Mini Sandbox Interativo

Edite o código abaixo e clique em ▶ Executar para ver o resultado em tempo real. Este é o mesmo princípio que ferramentas como CodePen e JSFiddle usam!

<!-- Lista de cards com Tailwind -->
<div class="container">
  <h1>Lista de Tarefas</h1>

  <form id="form-tarefa">
    <input type="text" id="input-tarefa"
           placeholder="Nova tarefa..." />
    <button type="submit">Adicionar</button>
  </form>

  <ul id="lista"></ul>

  <p id="contagem">0 tarefas</p>
</div>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: sans-serif; padding: 20px; background: #f8fafc; }

.container {
  max-width: 420px;
  margin: 0 auto;
  background: white;
  border-radius: 12px;
  padding: 24px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.08);
}

h1 { font-size: 1.4rem; margin-bottom: 16px; color: #1e293b; }

form {
  display: flex;
  gap: 8px;
  margin-bottom: 16px;
}

input[type="text"] {
  flex: 1;
  padding: 8px 12px;
  border: 2px solid #e2e8f0;
  border-radius: 8px;
  font-size: 0.9rem;
  outline: none;
}
input:focus { border-color: #6366f1; }

button {
  background: #6366f1;
  color: white;
  border: none;
  padding: 8px 14px;
  border-radius: 8px;
  cursor: pointer;
  font-weight: 600;
}
button:hover { background: #4f46e5; }

#lista { list-style: none; margin-bottom: 12px; }

#lista li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 12px;
  margin-bottom: 6px;
  border-radius: 8px;
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  cursor: pointer;
  transition: all 0.2s;
}
#lista li:hover { border-color: #6366f1; }
#lista li.feito {
  text-decoration: line-through;
  color: #94a3b8;
  background: #f1f5f9;
}
.btn-del {
  background: #fee2e2;
  color: #dc2626;
  border: none;
  padding: 3px 8px;
  border-radius: 5px;
  font-size: 0.75rem;
  cursor: pointer;
}

#contagem { font-size: 0.8rem; color: #94a3b8; text-align: right; }
const form   = document.getElementById('form-tarefa');
const input  = document.getElementById('input-tarefa');
const lista  = document.getElementById('lista');
const contagem = document.getElementById('contagem');

let tarefas = [];

form.addEventListener('submit', (e) => {
  e.preventDefault();
  const texto = input.value.trim();
  if (!texto) return;

  tarefas.push({ id: Date.now(), texto, feito: false });
  input.value = '';
  renderizar();
});

function renderizar() {
  lista.innerHTML = '';

  tarefas.forEach(t => {
    const li  = document.createElement('li');
    if (t.feito) li.classList.add('feito');

    const span = document.createElement('span');
    span.textContent = t.texto;
    span.addEventListener('click', () => {
      t.feito = !t.feito;
      renderizar();
    });

    const btn = document.createElement('button');
    btn.textContent = 'Excluir';
    btn.className   = 'btn-del';
    btn.addEventListener('click', () => {
      tarefas = tarefas.filter(x => x.id !== t.id);
      renderizar();
    });

    li.appendChild(span);
    li.appendChild(btn);
    lista.appendChild(li);
  });

  const feitas = tarefas.filter(t => t.feito).length;
  contagem.textContent = `${feitas} / ${tarefas.length} concluídas`;
}
<div class="calc">
  <div id="display">0</div>
  <div class="teclado">
    <button class="btn-cinza" onclick="limpar()">C</button>
    <button class="btn-cinza" onclick="apagar()">⌫</button>
    <button class="btn-cinza" onclick="inserir('%')">%</button>
    <button class="btn-op"    onclick="inserir('/')">÷</button>
    <button onclick="inserir('7')">7</button>
    <button onclick="inserir('8')">8</button>
    <button onclick="inserir('9')">9</button>
    <button class="btn-op" onclick="inserir('*')">×</button>
    <button onclick="inserir('4')">4</button>
    <button onclick="inserir('5')">5</button>
    <button onclick="inserir('6')">6</button>
    <button class="btn-op" onclick="inserir('-')">−</button>
    <button onclick="inserir('1')">1</button>
    <button onclick="inserir('2')">2</button>
    <button onclick="inserir('3')">3</button>
    <button class="btn-op" onclick="inserir('+')">+</button>
    <button class="btn-zero" onclick="inserir('0')">0</button>
    <button onclick="inserir('.')">.</button>
    <button class="btn-igual" onclick="calcular()">=</button>
  </div>
</div>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { background: #1c1c2e; display: flex; justify-content: center; padding: 24px; font-family: sans-serif; }

.calc { width: 260px; background: #16213e; border-radius: 20px; overflow: hidden; box-shadow: 0 20px 60px rgba(0,0,0,0.5); }

#display {
  padding: 16px 20px 8px;
  text-align: right;
  font-size: 2.2rem;
  font-weight: 300;
  color: white;
  min-height: 70px;
  word-break: break-all;
}

.teclado { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2px; background: #0f3460; }

button {
  padding: 18px;
  font-size: 1rem;
  background: #16213e;
  color: white;
  border: none;
  cursor: pointer;
  transition: background 0.15s;
  font-family: inherit;
}
button:hover  { background: #0f3460; }
button:active { background: #e94560; }

.btn-cinza { background: #1a1a2e; color: #a0a0a0; }
.btn-op    { color: #e94560; font-weight: bold; }
.btn-zero  { grid-column: span 2; }
.btn-igual { background: #e94560; font-weight: bold; }
.btn-igual:hover { background: #c73652; }
let expr = '';
let novo  = true; // true = próximo dígito reinicia a expressão

function inserir(tecla) {
  if (novo) { expr = ''; novo = false; }
  expr += tecla;
  document.getElementById('display').textContent = expr;
}

function limpar() {
  expr = '';
  novo = false;
  document.getElementById('display').textContent = '0';
}

function apagar() {
  expr = expr.slice(0, -1);
  document.getElementById('display').textContent = expr || '0';
}

function calcular() {
  try {
    // Function() é mais seguro que eval() para expressões simples
    const resultado = Function('"use strict"; return (' + expr + ')')();
    document.getElementById('display').textContent =
      Number.isFinite(resultado) ? +resultado.toFixed(10) : 'Erro';
    expr = String(resultado);
    novo = true; // próximo dígito começa nova expressão
  } catch {
    document.getElementById('display').textContent = 'Erro';
    expr = '';
  }
}
<div class="crono">
  <h2>⏱ Cronômetro</h2>
  <div id="display">00:00</div>
  <div class="controles">
    <button id="btn-play"  onclick="iniciar()">▶ Iniciar</button>
    <button id="btn-pause" onclick="pausar()" disabled>⏸ Pausar</button>
    <button onclick="zerar()">↺ Zerar</button>
  </div>
  <div id="historico"></div>
</div>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: sans-serif; background: #0f172a; min-height: 100px; display: flex; align-items: center; justify-content: center; padding: 20px; }

.crono {
  text-align: center;
  background: #1e293b;
  border-radius: 20px;
  padding: 28px 40px;
  box-shadow: 0 8px 32px rgba(0,0,0,0.4);
  min-width: 260px;
}

h2 { color: #94a3b8; font-size: 0.8rem; letter-spacing: 0.1em; text-transform: uppercase; margin-bottom: 16px; }

#display {
  font-family: 'Courier New', monospace;
  font-size: 4rem;
  font-weight: bold;
  color: #38bdf8;
  margin-bottom: 24px;
  letter-spacing: 0.05em;
}

.controles { display: flex; gap: 8px; justify-content: center; margin-bottom: 16px; }

button {
  padding: 9px 18px;
  border: none;
  border-radius: 8px;
  font-size: 0.82rem;
  cursor: pointer;
  background: #334155;
  color: #e2e8f0;
  transition: background 0.2s;
}
button:hover:not(:disabled) { background: #475569; }
button:disabled { opacity: 0.35; cursor: default; }
#btn-play { background: #0ea5e9; color: white; }
#btn-play:hover:not(:disabled) { background: #0284c7; }

#historico { font-size: 0.8rem; color: #475569; }
.volta { padding: 4px 0; border-top: 1px solid #334155; display: flex; justify-content: space-between; }
let segundos  = 0;
let intervalo = null;

// setInterval executa uma função repetidamente a cada N milissegundos
function iniciar() {
  if (intervalo) return; // evita criar dois intervalos
  document.getElementById('btn-play').disabled  = true;
  document.getElementById('btn-pause').disabled = false;

  intervalo = setInterval(() => {
    segundos++;
    atualizar();
  }, 1000); // dispara a cada 1000ms = 1 segundo
}

// clearInterval cancela o intervalo criado por setInterval
function pausar() {
  clearInterval(intervalo);
  intervalo = null;
  document.getElementById('btn-play').disabled  = false;
  document.getElementById('btn-pause').disabled = true;

  // Registra volta no histórico
  const div = document.createElement('div');
  div.className = 'volta';
  const num = document.querySelectorAll('.volta').length + 1;
  div.innerHTML = `<span>Volta ${num}</span><span>${formatar(segundos)}</span>`;
  document.getElementById('historico').prepend(div);
}

function zerar() {
  clearInterval(intervalo);
  intervalo = null;
  segundos  = 0;
  atualizar();
  document.getElementById('historico').innerHTML = '';
  document.getElementById('btn-play').disabled  = false;
  document.getElementById('btn-pause').disabled = true;
}

function atualizar() {
  document.getElementById('display').textContent = formatar(segundos);
}

// padStart(2, '0') garante 2 dígitos: 5 → "05"
function formatar(s) {
  const min = String(Math.floor(s / 60)).padStart(2, '0');
  const seg = String(s % 60).padStart(2, '0');
  return `${min}:${seg}`;
}
<div class="conversor">
  <h2>🌡️ Conversor de Temperatura</h2>

  <div class="campo">
    <label>Celsius (°C)</label>
    <input type="number" id="celsius"
           oninput="converter('celsius')" placeholder="0">
  </div>
  <div class="campo">
    <label>Fahrenheit (°F)</label>
    <input type="number" id="fahrenheit"
           oninput="converter('fahrenheit')" placeholder="32">
  </div>
  <div class="campo">
    <label>Kelvin (K)</label>
    <input type="number" id="kelvin"
           oninput="converter('kelvin')" placeholder="273.15">
  </div>

  <div id="info"></div>
</div>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: sans-serif; background: linear-gradient(135deg, #1e1b4b, #312e81); min-height: 100px; display: flex; align-items: center; justify-content: center; padding: 20px; }

.conversor {
  background: white;
  border-radius: 16px;
  padding: 28px;
  width: 100%;
  max-width: 340px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.3);
}

h2 { font-size: 1rem; color: #1e1b4b; margin-bottom: 20px; text-align: center; }

.campo { margin-bottom: 14px; }

label {
  display: block;
  font-size: 0.75rem;
  color: #6b7280;
  font-weight: 700;
  margin-bottom: 4px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

input {
  width: 100%;
  padding: 10px 14px;
  border: 2px solid #e5e7eb;
  border-radius: 8px;
  font-size: 1.1rem;
  font-weight: 600;
  color: #111827;
  outline: none;
  transition: border 0.2s;
}
input:focus { border-color: #6366f1; }

#info {
  margin-top: 12px;
  font-size: 0.82rem;
  color: #6366f1;
  text-align: center;
  min-height: 20px;
  font-weight: 600;
}
// oninput dispara a cada caractere digitado — ideal para conversão em tempo real
function converter(origem) {
  const val = parseFloat(document.getElementById(origem).value);

  if (isNaN(val)) {
    // Limpa os outros campos se o input estiver vazio
    ['celsius', 'fahrenheit', 'kelvin']
      .filter(id => id !== origem)
      .forEach(id => document.getElementById(id).value = '');
    document.getElementById('info').textContent = '';
    return;
  }

  // 1. Converte tudo para Celsius primeiro (base comum)
  let celsius;
  if      (origem === 'celsius')    celsius = val;
  else if (origem === 'fahrenheit') celsius = (val - 32) * 5 / 9;
  else                              celsius = val - 273.15; // kelvin

  // 2. Calcula as outras escalas a partir de Celsius
  const fahrenheit = celsius * 9 / 5 + 32;
  const kelvin     = celsius + 273.15;

  // 3. Preenche os campos (exceto o que o usuário está digitando)
  if (origem !== 'celsius')    document.getElementById('celsius').value    = celsius.toFixed(2);
  if (origem !== 'fahrenheit') document.getElementById('fahrenheit').value = fahrenheit.toFixed(2);
  if (origem !== 'kelvin')     document.getElementById('kelvin').value     = kelvin.toFixed(2);

  // 4. Curiosidade contextual
  let info = '';
  if      (celsius <= 0)             info = '🧊 Ponto de congelamento da água';
  else if (celsius >= 100)           info = '♨️ Ponto de ebulição da água';
  else if (celsius >= 36 && celsius <= 37.5) info = '🧑 Temperatura corporal normal';
  else if (celsius >= 20 && celsius <= 26)   info = '😊 Temperatura ambiente agradável';
  document.getElementById('info').textContent = info;
}

Aplicações Completas

Estas aplicações estão disponíveis no servidor local. Certifique-se de que o JSON Server está rodando (npm start).

Cadastro de Contatos CRUD

Cadastro de Contatos – CRUD

M06/M07

CRUD completo de contatos com inserção, edição, exclusão e listagem via JSON Server. Usa Fetch API com async/await e manipulação dinâmica do DOM.

HTML CSS JavaScript Fetch API JSON Server
Filtro de Contatos

Contatos – Filtro/Pesquisa

M07

Filtragem de contatos por cidade e categoria usando os parâmetros de query do JSON Server. Demonstra busca com filtros combinados.

Filtros Query Params JSON Server
Login do Sistema

Sistema de Login

M08

Login e registro de usuários com JSON Server. Sessão mantida no sessionStorage. Permite cadastro de novos usuários e logout.

Autenticação sessionStorage JSON Server
Mapa com Mapbox

Mapas com Mapbox

M09

Exibição de locais no mapa usando a API Mapbox. Os dados dos locais vêm do JSON Server (coleção locais). Requer conta Mapbox.

Mapbox GL JS API Key GeoJSON

Crie conta gratuita com o e-mail XXXXXX@sga.pucminas.br em mapbox.com para obter a API Key.

Gráficos com Chart.js

Gráficos com Chart.js

M09

Dashboard de gráficos usando Chart.js com dados vindos do JSON Server (coleção lancamentos). Gráficos de barras e pizza.

Chart.js Canvas API JSON Server
Passagem de Parâmetros

Passagem de Parâmetros

M07

Técnica de navegar entre páginas passando dados via URL (query string). Lista de cidades carregada do JSON Server com página de detalhes.

URLSearchParams Query String Roteamento

Referência Rápida

Padrões de código que você usará com frequência na disciplina.

1 Renderizar lista de itens

javascript
function renderizarLista(itens, containerId) {
  const container = document.getElementById(containerId);
  container.innerHTML = ''; // Limpa antes de renderizar

  if (itens.length === 0) {
    container.innerHTML =
      '<p class="vazio">Nenhum item encontrado.</p>';
    return;
  }

  itens.forEach(item => {
    const el = document.createElement('div');
    el.className  = 'card';
    el.dataset.id = item.id; // Guarda o ID no elemento

    el.innerHTML = `
      <h3>${item.nome}</h3>
      <p>${item.descricao}</p>
    `;

    container.appendChild(el);
  });
}

2 Capturar e enviar formulário

javascript
document
  .getElementById('meu-form')
  .addEventListener('submit', async (e) => {
    e.preventDefault(); // Evita reload da página

    // Lê os valores dos campos
    const nome  = document.getElementById('nome').value.trim();
    const email = document.getElementById('email').value.trim();

    // Validação básica
    if (!nome || !email) {
      alert('Preencha todos os campos!');
      return;
    }

    const novoItem = { nome, email };

    try {
      const resposta = await fetch('/api/itens', {
        method:  'POST',
        headers: { 'Content-Type': 'application/json' },
        body:    JSON.stringify(novoItem)
      });

      if (resposta.ok) {
        e.target.reset();  // Limpa o formulário
        await carregarItens(); // Atualiza a lista
      }
    } catch (erro) {
      alert('Erro ao salvar: ' + erro.message);
    }
  });

3 Modal de edição (preencher e salvar)

javascript
// Guarda o ID do item sendo editado
let idEditando = null;

async function abrirEdicao(id) {
  idEditando = id;

  // Busca os dados atuais do item
  const resposta = await fetch(`/api/contatos/${id}`);
  const contato  = await resposta.json();

  // Preenche o formulário do modal
  document.getElementById('edit-nome').value  = contato.nome;
  document.getElementById('edit-email').value = contato.email;

  // Exibe o modal
  document.getElementById('modal').style.display = 'flex';
}

async function salvarEdicao() {
  const dadosAtualizados = {
    nome:  document.getElementById('edit-nome').value,
    email: document.getElementById('edit-email').value
  };

  await fetch(`/api/contatos/${idEditando}`, {
    method:  'PUT',
    headers: { 'Content-Type': 'application/json' },
    body:    JSON.stringify(dadosAtualizados)
  });

  document.getElementById('modal').style.display = 'none';
  carregarContatos(); // Atualiza a lista
}

4 Estado de carregamento (Loading)

javascript
function mostrarLoading(containerId) {
  document.getElementById(containerId).innerHTML = `
    <div class="loading">
      <div class="spinner"></div>
      <p>Carregando...</p>
    </div>
  `;
}

function mostrarErro(containerId, msg) {
  document.getElementById(containerId).innerHTML = `
    <div class="erro">
      <p>❌ ${msg}</p>
      <button onclick="carregarDados()">Tentar novamente</button>
    </div>
  `;
}

async function carregarDados() {
  mostrarLoading('container');

  try {
    const dados = await fetch('/api/itens')
      .then(r => r.json());
    renderizarLista(dados, 'container');
  } catch (e) {
    mostrarErro('container', 'Não foi possível carregar os dados.');
  }
}