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
- Criar um array (uma lista) e ler os seus elementos pela posição.
- Usar um ciclo
for...ofpara repetir uma tarefa para cada elemento. - Guardar cada cliente como um objeto e acrescentá-lo à lista com
push. - Desenhar a tabela de clientes automaticamente, a partir da lista.
🧰 Antes de começar
- Abre a pasta
meu-crmno VS Code (Ficheiro → Abrir Pasta…). - Abre o
index.htmlcom o Live Server (botão direito → Open with Live Server). - 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)
- Acrescenta
console.log(vendasDaSemana[4]);. Que valor aparece? E comvendasDaSemana[5]? Porquê? - No ciclo
for (let i = 0; i < produtos.length; i++), o que acontece se trocaresi + 1pori? - 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
- Grava todos os ficheiros e volta ao CRM no browser.
- Acrescenta 3 clientes diferentes (com estados diferentes).
- 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
undefinednuma coluna → um nome nolinhaClientenão coincide com o do objeto (ex.:cliente.Nomeem vez decliente.nome). - Aparece a mensagem verde mas a tabela não muda → ficaste com duas funções
guardarCliente. Apaga a antiga (a que não temclientes.push). - Nada acontece ao clicar → a linha
atualizarEcra();do arranque tem de estar no fim do ficheiro, e oindex.htmltem 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)
- Na Consola, escreve
clientese carrega Enter. O que vês? Quantos elementos tem a lista? - Escreve
clientes[0].nomena Consola. O que aparece? - 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
- Faz o desafio ⭐.
- No treino, cria um array com os nomes de 5 colegas e mostra-os por ordem alfabética com
nomes.sort(). - Muda o texto do botão Guardar para «Guardar cliente».
🤖 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.