JavaScript 3: funções e o botão Guardar

Hoje voltamos ao CRM! Vais juntar o código em funções e criar o botão Guardar, que lê o formulário, valida os dados e mostra uma mensagem verde ou vermelha.

🎯 No fim desta aula vais conseguir

🧰 Antes de começar

  1. Abre a pasta meu-crm no VS Code (File → Open Folder…).
  2. Hoje trabalhamos no CRM: abre o index.html com o Live Server (botão direito → Open with Live Server) e abre a Consola (F12).
  3. Vais mexer em dois ficheiros: o index.html e o app.js.

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

Parte A — Ligar o JavaScript ao CRM (≈ 10 min)

1 Ligar os scripts

Tal como o <link> liga o CSS (aula 3), a etiqueta <script src="…"> liga um ficheiro JavaScript à página. O CRM vai usar dois:

A ordem importa: o browser lê os ficheiros de cima para baixo, e o app.js vai usar coisas que estão no dados.js. É como numa receita: primeiro compras os ingredientes, depois cozinhas. Por isso o dados.js vem primeiro.

E porque é que ficam no fim do <body>? Porque o JavaScript vai procurar os campos do formulário: se corresse antes de o browser ler o formulário, não os encontraria.

✅ Deves ver: nada de diferente no ecrã (ainda não há código para correr) e nenhum erro vermelho na Consola.

😕 Aparece um erro vermelho na Consola
  • GET … 404 (Not Found) → o nome do ficheiro não coincide. Confirma que está escrito dados.js e app.js, em minúsculas, e que os ficheiros estão na pasta meu-crm.
  • Confirma que colaste os scripts no index.html, antes do </body>, e não no app.js.

Parte B — Funções (≈ 25 min)

2 As funções validarCliente e mostrarMensagem

Uma função é um bloco de código com um nome, que só corre quando a chamamos. Pensa numa máquina de café:

Escrever a função é como escrever uma receita: ainda não se cozinhou nada. Só quando a chamas pelo nome, com os valores entre parênteses (validarCliente('Ana', '', '')), é que ela corre.

Neste bloco há duas funções:

Abre o app.js e cola o bloco por baixo do comentário AULA 6: COLAR AQUI:

Grava e vai à Consola do CRM. Vamos chamar as funções à mão para as testar:

🤔 Prevê antes de carregar Enter: o que devolve cada uma destas chamadas? Escreve, depois experimenta uma a uma na Consola.

  1. validarCliente('', '', '')
  2. validarCliente('Ana', 'ana.gmail.com', '')
  3. validarCliente('Ana', '', '1234')
  4. validarCliente('Ana', '[email protected]', '123456789')
  5. mostrarMensagem('Olá, turma!', 'sucesso')

✅ Deves ver: (1) 'O nome é obrigatório.'; (2) 'O email não é válido (falta o @).'; (3) 'O NIF tem de ter exatamente 9 algarismos.'; (4) '' — texto vazio, ou seja, está tudo bem; (5) a frase Olá, turma! aparece a verde por baixo do formulário.

😕 validarCliente is not defined
  • Estás na Consola do CRM (index.html) e não na do treino.html?
  • Gravaste o app.js? Os scripts do passo 1 estão no index.html?
  • Se aparecer outro erro vermelho antes (por exemplo Unexpected token), há um erro de escrita no app.js que impede o ficheiro todo de funcionar. Volta a copiar o bloco.

Parte C — O botão Guardar (≈ 25 min)

3 A função guardarCliente

Esta é a função que vai correr quando se carregar em Guardar. Lê-se assim:

  1. document.getElementById('nome').value → «vai buscar ao documento o campo com o id nome e dá-me o que lá está escrito». Lembras-te dos id da aula 2? É para isto que servem!
  2. .trim() → corta os espaços a mais no início e no fim (' Ana ' passa a 'Ana').
  3. Chama validarCliente e guarda a resposta na variável erro.
  4. Se houver erro (erro !== ''), mostra-o a vermelho e faz return;, que sai da função logo ali: o resto não corre.
  5. Se não houver erro, mostra a mensagem verde de sucesso.

Por agora o cliente ainda não fica guardado em lado nenhum: na aula 7 vamos pô-lo numa lista e na tabela, e na aula 8 guardá-lo a sério.

💡 Cola-o por baixo da chaveta } que fecha a função mostrarMensagem, e não dentro dela. Uma função dentro de outra deixa de ser encontrada pelo botão.

4 O botão

Falta o botão. O atributo onclick="guardarCliente()" quer dizer: «quando clicarem neste botão, chama a função guardarCliente». A isto chama-se um evento: o programa reage a uma ação do utilizador.

E o type="button"? Um botão dentro de um <form>, por omissão, “envia” o formulário e recarrega a página (apagando tudo). Com type="button", ele só faz o que nós mandamos.

No index.html, dentro de <div class="botoes">, por baixo do comentário AULA 6: COLAR AQUI O BOTÃO GUARDAR:

✅ Deves ver: um botão Guardar com a cor principal da tua empresa por baixo do formulário.

5 Testar

Grava os dois ficheiros e experimenta no CRM:

Faz isto e carrega em GuardarDeves ver
Deixa tudo vazio🔴 O nome é obrigatório.
Nome «Ana Silva» e email «ana.gmail.com»🔴 O email não é válido (falta o @).
Email certo e NIF «12345678» (8 algarismos)🔴 O NIF tem de ter exatamente 9 algarismos.
NIF «123456789»🟢 Cliente Ana Silva guardado com sucesso!

🤔 Pensa: o cliente aparece na tabela depois da mensagem verde? Porquê? (Lê outra vez o último parágrafo do passo 3.)

😕 Não funciona? Abre a Consola (F12)
  • guardarCliente is not defined → o app.js não está ligado (passo 1), tem um erro de escrita (vê se há outro erro vermelho antes deste), ou colaste o guardarCliente dentro de outra função.
  • Cannot read properties of null (reading 'value') → um id não coincide: o JavaScript procura 'nome', 'email' e 'nif' e um dos campos do index.html tem outro id (atenção às maiúsculas!).
  • Cannot set properties of null (setting 'textContent') → falta o <p id="mensagem"> no index.html.
  • Não acontece nada e não há erros → confirma que escreveste onclick="guardarCliente()", com os parênteses.
  • A página “pisca” e os campos ficam vazios → falta o type="button" no botão.

🔎 Investiga

  1. Na Consola, escreve mostrarMensagem('Olá!', 'erro'). De que cor fica? E com 'info'? Onde é que estão definidas estas cores?
  2. Na função guardarCliente, apaga o .trim() da linha do nome e grava. Escreve só espaços no Nome e carrega em Guardar. O que acontece? Porque é que isso é mau para o CRM? (Volta a pôr o .trim().)
  3. Ainda no guardarCliente, põe // no início da linha return; (fica um comentário) e tenta guardar com o nome vazio. O que aparece? Porquê? Para que serve, então, o return; sozinho? (Tira o //.)

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

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

E1 · O botão Limpar

Ao lado do botão Guardar, cria um botão Limpar que apaga tudo o que está escrito no formulário e a mensagem que estiver por baixo dele.

💡 Dica: cria uma função nova no app.js (por exemplo, limparFormulario) e chama-a no onclick do botão novo. Os formulários têm uma função reset() que os limpa: que id tem o formulário no index.html? Para apagar a mensagem, podes reutilizar a mostrarMensagem com um texto vazio. Não te esqueças do type="button"! Para o botão ficar cinzento, usa a classe secundario, que já existe no style.css.

E2 · A mensagem desaparece sozinha

Faz com que as mensagens (verdes e vermelhas) desapareçam sozinhas passados 3 segundos.

💡 Dica: aqui vai uma “receita” pronta. Este código espera 3000 milésimos de segundo (3 segundos) e só depois corre o que está dentro das chavetas:

💡 Em que função deve ficar, para funcionar com todas as mensagens? E o que tens de pôr lá dentro para a caixa da mensagem ficar sem texto?

⭐ Desafio · Validar também o telefone

Faz com que a função validarCliente também verifique o telefone, com a regra do E1 da aula 5 (9 algarismos, a começar por 9 ou por 2), mas só se estiver preenchido (como o email e o NIF). Se estiver mal, o Guardar mostra uma mensagem de erro à tua escolha.

💡 Dica: a função precisa de receber mais um parâmetro, telefone. Depois, no guardarCliente, tens de ler o campo do telefone (qual é o id?) e passá-lo na chamada de validarCliente.

⚠️ Para a aula 7: na próxima aula, a função guardarCliente vai ser substituída por uma versão nova. Se fizeres este desafio, vais ter de voltar a acrescentar o telefone na chamada de validarCliente (na aula 7 será cliente.telefone). Se te esqueceres, ao carregar em Guardar pode aparecer na Consola o erro Cannot read properties of undefined (reading 'length').

📦 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

<script src="…">
Liga um ficheiro JavaScript à página.
Função
Bloco de código com nome, que só corre quando é chamado: function validarCliente(…) { … }.
Parâmetro
Valor que a função recebe entre parênteses (os “ingredientes”).
return
Devolve o resultado da função e termina-a naquele momento.
Chamar uma função
Mandá-la correr, escrevendo o nome e os valores: mostrarMensagem('Olá!', 'info').
document.getElementById('…')
Vai buscar à página o elemento com aquele id.
.value
O que está escrito num campo do formulário.
.trim()
Corta os espaços no início e no fim de um texto.
textContent
O texto que está dentro de um elemento.
Evento (onclick)
Ação do utilizador (como um clique) a que o programa reage.
setTimeout
Corre um pedaço de código depois de esperar algum tempo (em milésimos de segundo).