Search buenodc

Nesta página
  1. Importante
  2. Contextualização
  3. Como começar
  4. Como funciona
  5. Cronograma
  6. Material de apoio
  7. Missão 1 — Renderizando as Tarefas
  8. Missão 2 — Marcando como Concluída
  9. Missão 3 — Adicionando Novas Tarefas
  10. Missão 4 — Removendo Tarefas e Contando Pendentes
  11. Entrega individual (cada integrante deve enviar seu próprio arquivo)

Atividade DOM — Painel TaskFlow

Disciplina: Programação Web 2
Assunto: DOM — Document Object Model
Professor: Me. Danilo Bueno
Grupos: duplas
Duração: 4 aulas de 50 minutos (em sala)


Importante

Antes de começar a atividade leia o material de apoio sobre DOM. É imprescindível que você leia antes de codar, pois a atividade é justamente para praticar os conceitos apresentados no material. Se tiver dúvidas, releia o material, pergunte ao professor ou aos colegas. Você também pode consultar os slides da aula.


Contextualização

A TaskFlow é uma startup de gestão de tarefas para times de tecnologia. O time de backend já entregou os dados: um array JavaScript com as tarefas do sprint atual.

O problema é que nada aparece na tela — o frontend ainda não existe. Os dados estão lá, mas sem DOM nenhuma tarefa é exibida ao usuário.

Você e sua dupla foram contratados como o time de frontend para construir a interface.


Como começar

Crie dois arquivos na mesma pasta, nomeados exatamente assim (sem nomes):

index.html — cole o conteúdo abaixo:

<!DOCTYPE html>
<html lang="pt-BR">
  <head>
    <meta charset="UTF-8" />
    <title>TaskFlow</title>
  </head>
  <body>
    <h1>TaskFlow</h1>
    <ul id="lista-tarefas"></ul>
    <script src="tarefas.js"></script>
  </body>
</html>

tarefas.js — cole o conteúdo abaixo:

// Como executar:
//   abra o index.html no navegador (duplo clique ou arraste para o Chrome)
//   pressione F12 para ver erros no Console
// ─────────────────────────────────────────────────────────────

const tarefas = [
  { id: 1, titulo: "Criar wireframe da homepage", responsavel: "Ana", concluida: false },
  { id: 2, titulo: "Implementar login com JWT", responsavel: "Carlos", concluida: true },
  { id: 3, titulo: "Revisar pull request #42", responsavel: "Ana", concluida: false },
  { id: 4, titulo: "Configurar CI/CD no GitHub Actions", responsavel: "Bruno", concluida: false },
  { id: 5, titulo: "Escrever testes unitários", responsavel: "Carlos", concluida: true },
];

Todo o JavaScript da atividade vai no tarefas.js, logo abaixo do array. Recarregue o navegador (F5) para ver cada mudança.

Se o HTML abrir mas nada acontecer, abra o DevTools (F12 → aba Console) — os erros aparecem lá com o número da linha.


Como funciona

O arquivo tarefas.js tem 4 missões. Implemente cada tarefa logo abaixo do array tarefas.

Dica: a cada tarefa concluída, recarregue o navegador e confira o resultado antes de avançar.


Cronograma

AulaFocoMissões
1ªSetup + renderizaçãoMissão 1
2ªEventos de cliqueMissão 2
3ªFormulárioMissão 3
4ªRemoção + entregaMissão 4 + envio

Material de apoio


Missão 1 — Renderizando as Tarefas

Objetivo: exibir todas as tarefas do array como itens <li> na lista do HTML.

Tarefa 1.1: selecione o elemento <ul id="lista-tarefas"> com querySelector e guarde na constante lista.


Tarefa 1.2: percorra o array tarefas com for...of. Para cada tarefa, crie um elemento <li> com createElement, defina seu textContent com o título e o responsável no formato abaixo, e adicione o <li> à lista com appendChild.

Criar wireframe da homepage — Ana
Implementar login com JWT — Carlos
Revisar pull request #42 — Ana
...

Tarefa 1.3: tarefas que já estão concluídas (concluida: true) devem aparecer visualmente diferentes. Após criar o <li>, verifique se tarefa.concluida é true e adicione a classe "concluida" com classList.add.

No index.html, adicione o estilo abaixo dentro de um <style> na <head>:

<style>
  .concluida { text-decoration: line-through; opacity: 0.5; }
</style>

Pergunta: por que usar textContent e não innerHTML para definir o título da tarefa?


Missão 2 — Marcando como Concluída

Objetivo: ao clicar numa tarefa, alternar visualmente entre concluída e pendente.

Tarefa 2.1: ainda dentro do for...of da Missão 1, adicione um addEventListener de "click" em cada <li>. Dentro do callback, use classList.toggle("concluida") no próprio <li>.


Tarefa 2.2: abra o navegador e clique nas tarefas. O clique deve alternar o estilo riscado. Clique duas vezes seguidas na mesma tarefa — ela deve voltar ao estado original.

Pergunta: o que o toggle faz que seria trabalhoso implementar manualmente com add e remove?


Missão 3 — Adicionando Novas Tarefas

Objetivo: permitir que o usuário adicione tarefas pelo formulário.

Tarefa 3.1: no index.html, adicione um formulário abaixo do <ul>:

<form id="form-nova-tarefa">
  <input type="text" id="campo-titulo" placeholder="Título da tarefa" />
  <input type="text" id="campo-responsavel" placeholder="Responsável" />
  <button type="submit">Adicionar</button>
</form>

Tarefa 3.2: no tarefas.js, selecione o <form> com querySelector e adicione um listener do evento "submit". Dentro do callback:

  1. Chame event.preventDefault() para evitar o recarregamento da página.
  2. Leia os valores dos dois inputs com .value.trim().
  3. Se qualquer campo estiver vazio, exiba alert("Preencha todos os campos.") e retorne cedo (return).

Pergunta: o que acontece se você não chamar event.preventDefault() no submit do formulário?


Tarefa 3.3: ainda dentro do callback, crie um <li> com createElement, defina o textContent com título e responsável (mesmo formato da Missão 1) e insira na lista com appendChild.


Tarefa 3.4: após inserir a tarefa, limpe os dois campos (input.value = "") e devolva o foco ao primeiro campo (inputTitulo.focus()).


Missão 4 — Removendo Tarefas e Contando Pendentes

Objetivo: adicionar um botão “Remover” em cada tarefa e exibir o total de tarefas pendentes.

Tarefa 4.1: modifique a criação do <li> (feita nas Missões 1 e 3) para incluir um <button> com o texto "✕" dentro de cada item. Use createElement, defina textContent e insira o botão no <li> com appendChild antes de adicionar o <li> à lista.


Tarefa 4.2: adicione um listener de "click" no botão. No callback, remova o <li> pai com:

botao.parentElement.remove();

Atenção: o listener de "click" do botão e o do <li> (toggle de concluída) vão conflitar — clicar no botão também dispara o clique no <li>. Resolva isso chamando event.stopPropagation() dentro do listener do botão, antes de remover o item.


Tarefa 4.3: no index.html, adicione um parágrafo para o contador, logo acima do <ul>:

<p id="contador">Tarefas pendentes: 0</p>

Crie uma função chamada atualizarContador() que:

  1. Conta quantos <li> na lista não têm a classe "concluida" (dica: subtraia o total dos <li> pelo número de querySelectorAll(".concluida")).
  2. Atualiza o textContent do <p id="contador">.

Chame atualizarContador() após cada mudança: ao renderizar a lista inicial, ao clicar (toggle), ao adicionar nova tarefa e ao remover.


Tarefa 4.4 (desafio): o botão “Remover” acima não sincroniza com o array JavaScript. Implemente a remoção também no array: ao clicar em ”✕”, além de remover o <li>, encontre o objeto correspondente no array tarefas e remova com splice.

Para isso, no momento da criação do <li>, guarde o id da tarefa num atributo data-id:

li.dataset.id = tarefa.id;

Ao remover, use findIndex para localizar o item e splice para remover.


Entrega individual (cada integrante deve enviar seu próprio arquivo)

  1. Responder o questionário (link no Moodle)
  2. Enviar o arquivo tarefas.js com as missões completas