Arrays e ciclos: a lista de clientes

Hoje o botão Guardar passa a acrescentar clientes a uma lista, e a tabela desenha-se sozinha com um ciclo.

🎯 No fim desta aula vais conseguir

🧰 Antes de começar

  1. Abre a pasta meu-crm no VS Code (Ficheiro → Abrir Pasta…).
  2. Abre o index.html com o Live Server (botão direito → Open with Live Server).
  3. Confirma que o botão Guardar da aula 6 mostra a mensagem verde.

😕 Faltaste à aula 6 ou o teu projeto não funciona? Descarrega o ponto de controlo da aula 6, descompacta-o e trabalha a partir dele.

Parte A — Treino: listas e ciclos (≈ 30 min)

1 A primeira lista

Um array é uma lista de valores guardada numa só variável. Escreve-se entre [ ], com os valores separados por vírgulas. Cada valor tem uma posição (também chamada índice), que começa no 0.

Um ciclo repete as mesmas instruções várias vezes. O for (const venda of vendasDaSemana) lê-se: «para cada venda da lista vendasDaSemana, faz…».

🤔 Prevê antes de executar: o que vai aparecer em Primeira venda? E qual será o Total da semana? Escreve a tua resposta no caderno.

Grava (Ctrl+S), abre o treino.html com o Live Server e abre a Consola (F12).

✅ Deves ver na Consola: Primeira venda: 120, Quantas vendas? 5, Total da semana: 800 € e a lista numerada 1. Caneta, 2. Caderno, 3. Agrafador.

😕 Não aparece nada / aparece um erro vermelho
  • Erro Identifier 'total…' has already been declared: tens duas variáveis com o mesmo nome. Procura a repetida e muda-lhe o nome.
  • Não aparece nada: confirmaste que gravaste o ficheiro e que abriste o treino.html (não o index.html)?
  • Erro com Unexpected token: falta uma ) ou }. Volta a copiar o bloco inteiro.

🔎 Investiga (Parte A)

  1. Acrescenta console.log(vendasDaSemana[4]);. Que valor aparece? E com vendasDaSemana[5]? Porquê?
  2. No ciclo for (let i = 0; i < produtos.length; i++), o que acontece se trocares i + 1 por i?
  3. Muda os valores do array vendasDaSemana. O total atualiza-se sozinho? Que vantagem tem isto?

Parte B — O CRM passa a ter uma lista de clientes (≈ 50 min)

2 Criar a lista de clientes

Vamos guardar todos os clientes num array chamado clientes. Por agora começa vazio: [].

💡 Usamos let (e não const) porque mais tarde vamos trocar a lista inteira por outra.

3 Desenhar a tabela a partir da lista

A função desenharTabela() percorre a lista com um ciclo e, para cada cliente, junta (+=) uma linha de tabela ao texto html. No fim, mete esse HTML dentro do <tbody id="corpo-tabela">.

A função linhaCliente() cria o HTML de uma linha. Repara nas crases ` `: dentro delas, ${cliente.nome} é substituído pelo nome verdadeiro do cliente.

4 Atualizar o ecrã e arrancar

A função atualizarEcra() vai ser chamada sempre que os dados mudam. Por agora só desenha a tabela, mas nas próximas aulas vamos acrescentar-lhe mais coisas (repara nos comentários // AULA 13, // AULA 14…).

Por fim, a linha de arranque: quando a página abre, desenha o ecrã pela primeira vez. Tem de ficar sempre na última linha do app.js.

✅ Deves ver: a tabela de clientes fica vazia (só com o cabeçalho). As duas linhas de exemplo (Ana Silva e Rui Costa) desapareceram!

🤔 Pensa: ainda não apagaste as linhas de exemplo do index.html… então porque desapareceram? (Dica: o que faz corpo.innerHTML = html quando a lista está vazia?)

5 Arrumar: apagar as linhas de exemplo

As linhas de exemplo já não servem para nada. No index.html, dentro de <tbody id="corpo-tabela">, apaga todos os blocos <tr> … </tr> (o da Ana Silva, o do Rui Costa e o terceiro, se fizeste o E2 da aula 2).

⚠️ Fizeste o E1 da aula 2 (campo Cidade)? Deixa ficar o campo Cidade no formulário, mas apaga por agora o <th>Cidade</th> do cabeçalho da tabela. A função linhaCliente ainda não tem a cidade e as colunas ficavam desalinhadas. Vais voltar a pô-lo na aula 12.

Deve ficar assim:

6 O novo botão Guardar

A versão da aula 6 só mostrava uma mensagem. A nova versão junta os dados do formulário num objeto (um conjunto de pares nome: valor entre chavetas { }), acrescenta-o à lista com clientes.push(cliente) e volta a desenhar o ecrã.

⚠️ Atenção: este bloco substitui a função antiga. Seleciona a função guardarCliente da aula 6 inteira (desde function guardarCliente até à } que a fecha), apaga-a e cola esta no mesmo sítio.

💡 Fizeste o desafio da aula 6 (validar o telefone)? Na nova função, acrescenta o telefone à chamada: validarCliente(cliente.nome, cliente.email, cliente.nif, cliente.telefone). Se não o fizeres, aparece o erro Cannot read properties of undefined ao guardar. (Nas aulas 8 e 9 esta função volta a ser substituída: repete este acrescento.)

7 Testar

  1. Grava todos os ficheiros e volta ao CRM no browser.
  2. Acrescenta 3 clientes diferentes (com estados diferentes).
  3. Tenta guardar um cliente sem nome: deve aparecer a mensagem de erro e a tabela não muda.

✅ Deves ver: cada cliente aparece numa linha nova da tabela, com a etiqueta colorida do estado, e o formulário fica limpo depois de guardar.

😕 Não funciona?
  • Abre a Consola (F12). atualizarEcra is not defined → falta o passo 4.
  • clientes is not defined → falta o passo 2, ou escreveste o nome de forma diferente (maiúsculas contam!).
  • Aparece undefined numa coluna → um nome no linhaCliente não coincide com o do objeto (ex.: cliente.Nome em vez de cliente.nome).
  • Aparece a mensagem verde mas a tabela não muda → ficaste com duas funções guardarCliente. Apaga a antiga (a que não tem clientes.push).
  • Nada acontece ao clicar → a linha atualizarEcra(); do arranque tem de estar no fim do ficheiro, e o index.html tem de ter os <script> da aula 6.

🤔 Prevê: se carregares em F5 (recarregar a página), o que acontece aos clientes que criaste? Experimenta. (Vamos resolver isto na próxima aula.)

🔎 Investiga (Parte B)

  1. Na Consola, escreve clientes e carrega Enter. O que vês? Quantos elementos tem a lista?
  2. Escreve clientes[0].nome na Consola. O que aparece?
  3. Na função linhaCliente, troca a ordem de duas colunas <td>. O que acontece à tabela? E ao cabeçalho? Volta a pôr como estava.

✍️ Exercícios (fazem parte do teu projeto)

Estes exercícios não têm o código pronto: usa o que aprendeste hoje.

E1 · Contador de clientes

Por baixo da tabela, mostra o texto «Total de clientes: N», em que N é o número de clientes da lista. O número tem de se atualizar sempre que guardas um cliente.

💡 Dica: cria um <p id="total-clientes"></p> no HTML. Que propriedade de um array diz quantos elementos ele tem? (Viste-a na Parte A.) Em que função deves escrever o texto para que se atualize sempre?

E2 · Tabela vazia com mensagem

Quando ainda não há clientes, em vez de uma tabela vazia, mostra uma linha com o texto «Ainda não há clientes.»

💡 Dica: na função desenharTabela(), depois do ciclo, como sabes que o html ficou vazio? Uma célula pode ocupar várias colunas com <td colspan="6">.

⭐ Desafio · Estatísticas das vendas

No treino.js, mostra na Consola a média das vendas da semana e a maior venda.

💡 Dica: a média é o total a dividir pelo número de vendas. Para a maior: começa com a primeira venda e, dentro de um ciclo, se encontrares uma maior, guarda-a.

📦 O que mostrar ao professor

⏱️ Se sobrar tempo

🤖 Pedir ajuda à IA (opcional)

Se tiveres um erro que não percebes, podes pedir a uma IA gratuita (Claude, ChatGPT…) que te explique o erro, sem te dar a solução. Copia este pedido, troca o texto entre [ ] e cola-o na IA:

📖 Palavras novas

Array (lista)
Variável que guarda vários valores por ordem, ex.: [120, 80, 250].
Índice (posição)
Número que indica o lugar de um elemento no array. O primeiro é o 0.
Ciclo (for, for...of)
Instrução que repete um bloco de código várias vezes.
push
Acrescenta um elemento ao fim de um array.
.length
Diz quantos elementos tem um array (ou quantas letras tem um texto).
Objeto
Conjunto de pares nome: valor entre { }, ex.: { nome: 'Ana', estado: 'Lead' }.
innerHTML
O HTML que está dentro de um elemento. Se lhe dermos um valor, substitui o que lá estava.