Editar e apagar clientes

Hoje cada linha da tabela ganha dois botões: ✏️ para alterar os dados de um cliente e 🗑️ para o apagar. Na linguagem das bases de dados, vais atualizar e remover registos.

🎯 No fim desta aula vais conseguir

🧰 Antes de começar

  1. Abre a pasta meu-crm no VS Code e o index.html com o Live Server.
  2. Confirma que tens pelo menos 3 clientes guardados e que continuam lá depois de F5 (aula 8). Se não tiveres, cria-os agora: hoje vais precisar de clientes para editar e apagar.

😕 Faltaste à aula 8 ou o teu projeto não funciona? Descarrega o ponto de controlo da aula 8, descompacta-o e trabalha a partir dele. (Os pontos de controlo trazem o código, mas não os clientes: os clientes ficam guardados no teu browser.)

Parte A — Preparar o HTML (≈ 10 min)

1 O campo escondido e a coluna Ações

Para editar um cliente, vamos usar o mesmo formulário de criar. Mas como é que o botão Guardar sabe se está a criar um cliente novo ou a alterar um que já existe?

Resposta: com um campo escondido (<input type="hidden">). É uma caixa do formulário que o utilizador não vê, mas o JavaScript pode ler e escrever. Funciona como um post-it colado no formulário:

A tabela também precisa de uma coluna nova para os botões. Acrescenta o cabeçalho:

💡 Se o teu cabeçalho ainda tem a coluna <th>Cidade</th> do E1 da aula 2 e as colunas ficam desalinhadas, apaga por agora só essa linha do <thead> (vais voltar a precisar dela na aula 12).

Parte B — Procurar, apagar e editar (≈ 45 min)

2 As funções de procurar, apagar e editar

Este bloco tem quatro funções. Lê a explicação de cada uma antes de colar:

🤔 Prevê: a lista tem 3 clientes e procuras o id do segundo. Que número devolve posicaoDoCliente? E se procurares um id que não existe?

3 Os botões em cada linha

A nova linhaCliente() acrescenta uma célula com dois botões. Repara no onclick="editarCliente(${cliente.id})": quando a linha é criada, o ${cliente.id} é trocado pelo número verdadeiro do cliente. Assim, cada botão leva uma «etiqueta» com o número do seu cliente, por exemplo editarCliente(1759480001000).

⚠️ Atenção: este bloco substitui a função antiga. No app.js, seleciona a função linhaCliente inteira (desde function linhaCliente até à } que a fecha, depois do `;), apaga-a e cola esta no mesmo sítio. Dentro da função nova há um comentário <!-- AULA 13: COLAR AQUI O BOTÃO VER -->: deixa-o ficar, vais precisar dele.

Grava e volta ao CRM. Experimenta já o botão 🗑️ num cliente (clica em OK).

✅ Deves ver: cada linha tem os botões ✏️ e 🗑️ na coluna Ações. O 🗑️ pergunta se tens a certeza e, se confirmares, o cliente desaparece (e não volta com F5).

🤔 Prevê: clica agora em ✏️ num cliente, muda-lhe o telefone e clica em Guardar. O que acontece? Experimenta e conta os clientes da tabela. Porque é que isto aconteceu? (Dica: o que faz a função guardarCliente que tens agora?)

4 O Guardar que cria ou atualiza

No passo anterior, editar criou um cliente repetido, porque o guardarCliente só sabe fazer push (acrescentar). A nova versão primeiro olha para o campo escondido:

No fim, limpa o campo escondido «à mão», porque o reset() do formulário não limpa os campos escondidos.

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

💡 Fizeste o botão Limpar na aula 6? O reset() não limpa o campo escondido. Acrescenta à tua função limparFormulario(), logo a seguir ao reset(), a linha document.getElementById('cliente-id').value = ''; Senão, se carregares em Limpar a meio de uma edição, o próximo Guardar estraga o cliente que estavas a editar.

💡 Antes de testar, apaga com o 🗑️ o cliente repetido que criaste no passo 3.

5 Testar

  1. Clica em ✏️ num cliente, muda-lhe o telefone e o estado e clica em Guardar.
  2. Carrega em F5: a alteração tem de continuar lá.
  3. Clica em 🗑️ num cliente e escolhe Cancelar: não pode acontecer nada. Depois clica outra vez e escolhe OK.
  4. Cria um cliente novo, para confirmares que criar ainda funciona.

✅ Deves ver: ao editar, a linha do cliente muda no mesmo sítio e o número de clientes não aumenta. Aparece a mensagem azul «A editar…» quando clicas em ✏️ e a verde «guardado com sucesso» quando gravas.

😕 Não funciona?
  • Abre a Consola (F12). posicaoDoCliente is not defined ou editarCliente is not defined → falta o passo 2 (ou não gravaste).
  • Cannot set properties of null (setting 'value') ao clicar em ✏️ → falta o campo escondido do passo 1, ou o id não está escrito exatamente cliente-id.
  • Editar continua a criar um cliente repetido → ficaram duas funções guardarCliente. Procura com Ctrl+F e apaga a antiga (a que não tem idEmEdicao).
  • Os botões aparecem por baixo do cabeçalho errado → falta o <th>Ações</th> ou sobrou um <th> a mais (por exemplo, Cidade).
  • A tabela ficou vazia e aparece um erro com Unexpected token → a função linhaCliente ficou cortada (falta a crase ` ou a }). Volta a copiar o bloco inteiro.

🔎 Investiga

  1. Clica em ✏️ num cliente. Depois clica com o botão direito no formulário → Inspecionar e procura o <input type="hidden" id="cliente-id">. Que valor tem? E depois de clicares em Guardar?
  2. No 🗑️, clica em Cancelar. Que linha do apagarCliente faz com que nada aconteça?
  3. Na Consola, escreve clientes[0].id para veres o id do primeiro cliente. Depois escreve posicaoDoCliente(, cola esse número e fecha com ). O que aparece? E com posicaoDoCliente(123)?

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

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

E1 · Botão ⭐ «Passar a Cliente»

Em cada linha, acrescenta um botão ⭐ (com title="Passar a Cliente") que muda o estado desse cliente para Cliente. A mudança tem de aparecer logo na tabela e continuar depois de F5.

💡 Dica: copia a linha do botão ✏️ dentro de linhaCliente e muda o ícone e o nome da função para converterCliente. Depois cria a função converterCliente(id): usa procurarCliente(id) para obteres o registo, muda o seu .estado e, no fim, faz o mesmo que o apagarCliente faz depois de mexer na lista (gravar e redesenhar).

E2 · «Atualizar» em vez de «Guardar»

Quando estás a editar um cliente, o botão Guardar deve mostrar o texto «Atualizar». Depois de gravar, volta a mostrar «Guardar».

💡 Dica: o botão tem id="botao-guardar" (aula 6). A propriedade .textContent muda o texto de um elemento. Em que função começa a edição? Em que função acaba?

⭐ Desafio · Botão «Cancelar edição»

Cria um botão «Cancelar edição» ao lado do Guardar, que só aparece durante a edição. Ao clicar: limpa o formulário, sai do modo de edição, o botão Guardar volta a dizer «Guardar» e o próprio botão Cancelar esconde-se.

💡 Dica: o atributo hidden no HTML esconde um elemento; em JavaScript, .hidden = false mostra-o e .hidden = true esconde-o. Dá-lhe um id (por exemplo botao-cancelar). Lembra-te: o reset() não limpa o campo escondido!

📦 O que mostrar ao professor

⏱️ Se sobrar tempo

🤖 Pedir ajuda à IA (opcional)

Se não percebeste bem como se procura e apaga um elemento de uma lista, pede a uma IA gratuita que te explique com um exemplo, sem te dar código para o projeto:

📖 Palavras novas

Campo escondido (type="hidden")
Campo de formulário que o utilizador não vê, mas que o JavaScript pode ler e escrever.
Ciclo for com contador
for (let i = 0; i < lista.length; i++): repete para cada posição i da lista (0, 1, 2…).
-1
Valor que, por convenção, quer dizer «não encontrei» quando se procura uma posição.
null
Valor especial que quer dizer «nada», «não existe».
confirm
Mostra uma janela com OK e Cancelar e devolve true ou false.
splice(posição, 1)
Tira 1 elemento de uma lista, a partir daquela posição.
Number(texto)
Transforma um texto como '42' no número 42.
Atualizar / Remover
Alterar os dados de um registo que já existe / apagar um registo. Com criar e ler, formam as 4 operações básicas sobre dados (em inglês, CRUD).