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
- Procurar um registo pela sua chave primária (
id) com um cicloforcom contador. - Remover um registo da lista com
splice, depois de pedir confirmação. - Atualizar um registo: passar os dados para o formulário, alterar e voltar a gravar.
- Usar um campo escondido para o programa saber se estás a criar ou a editar um cliente.
🧰 Antes de começar
- Abre a pasta
meu-crmno VS Code e oindex.htmlcom o Live Server. - 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:
- vazio → estás a criar um cliente novo;
- com um número (o
idde um cliente) → estás a editar esse cliente.
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:
posicaoDoCliente(id)— percorre a lista com um ciclofor (let i = 0; …; i++), como quem procura uma ficha num arquivador, uma a uma. Quando encontra o cliente com aqueleid, devolve a posição dele (i) e pára logo (oreturnsai da função). Se chegar ao fim sem o encontrar, devolve-1, que quer dizer «não existe» (não pode ser 0, porque o 0 é a primeira posição).procurarCliente(id)— usa a função anterior e devolve o registo inteiro (o objeto do cliente), ounull(«nada») se não existir.apagarCliente(id)— mostra uma janela «Tens a certeza…?» comconfirm. Se carregares em OK, tira o cliente da lista comsplice(posição, 1)(«tira 1 elemento a partir desta posição»), grava e redesenha.editarCliente(id)— copia cada campo do cliente para o formulário, escreve oidno campo escondido e põe o cursor no Nome.
🤔 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:
- se estiver vazio (
'') → fazpush, como antes; - se tiver um número → procura a posição desse cliente e troca o registo antigo pelo novo, mantendo o mesmo
ide a mesma data de criação. ONumber(...)é preciso porque os campos do formulário dão sempre texto ('1759480001000') e osidsão números.
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
- Clica em ✏️ num cliente, muda-lhe o telefone e o estado e clica em Guardar.
- Carrega em F5: a alteração tem de continuar lá.
- Clica em 🗑️ num cliente e escolhe Cancelar: não pode acontecer nada. Depois clica outra vez e escolhe OK.
- 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 definedoueditarCliente 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 oidnão está escrito exatamentecliente-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 temidEmEdicao). - 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çãolinhaClienteficou cortada (falta a crase`ou a}). Volta a copiar o bloco inteiro.
🔎 Investiga
- 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? - No 🗑️, clica em Cancelar. Que linha do
apagarClientefaz com que nada aconteça? - Na Consola, escreve
clientes[0].idpara veres oiddo primeiro cliente. Depois escreveposicaoDoCliente(, cola esse número e fecha com). O que aparece? E composicaoDoCliente(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
- Faz o desafio ⭐.
- Quando editas, a mensagem verde diz «guardado com sucesso». Consegues fazer com que diga «atualizado com sucesso» só quando é uma edição? (Dica: a variável
idEmEdicao.) - Muda a pergunta do
confirmdo 🗑️ para incluir também a empresa do cliente.
🤖 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
forcom contador for (let i = 0; i < lista.length; i++): repete para cada posiçãoida 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
trueoufalse. splice(posição, 1)- Tira 1 elemento de uma lista, a partir daquela posição.
Number(texto)- Transforma um texto como
'42'no número42. - 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).