Professor Marco Antonio Andrade

Tutorial: desenvolvendo um app para cálculo de IMC com JavaScript

03/09/2019 - 14 mins de leitura

Faça o fork do repositório contendo os arquivos necessários para este tutorial.

Vamos importar o arquivo assets/js/functions.js em nosso documento HTML:

<script src="assets/js/functions.js"></script>

Agora abra o arquivo assets/js/functions.js para programar o aplicativo para cálculo de IMC.

Mapeando os componentes do formulário

Para manipular os dados dos campos dos formulários vamos mapea-los:

let nome = document.querySelector("#nome");
let peso = document.querySelector("#peso");
let altura = document.querySelector("#altura");

Adicionando um listerner no botão para calcular o IMC

A ideia é que após o botão calcular seja clicado, e com os dados dos campos do formulário, o cálculo de IMC ocorra:

document.querySelector("#btn-calcular").addEventListener("click", (event) => {
  console.log("Cliquei no botão");
});

Você vai perceber que ao clicar no botão o formulário é submetido. Assim, devemos utilizar a função preventDefault() para que o formulário não seja submetido:

document.querySelector("#btn-calcular").addEventListener("click", (event) => {
  event.preventDefault();
  // Após testar remova essa impressão no console
  console.log("Cliquei no botão");
});

Criando uma função para calcular o IMC

Vamos criar uma função para calcular o IMC:

function calcularIMC(peso, altura){
  return peso / (altura * altura);
}

Vamos utilizar a função para cálculo de IMC no event listerner do botão:

document.querySelector("#btn-calcular").addEventListener("click", (event) => {
  event.preventDefault();
  let imc = calcularIMC(peso.value, altura.value);
  // Após testar remova essa impressão no console
  console.log(imc);
});

Para definir a quantidade de casas decimais utilizamos o método toFixed():

  console.log(imc.toFixed(2));

Adicionando os dados na tabela

Primeiro vamos mapear a tabela:

let tabela = document.querySelector('.table');

E então criar uma função para adicionar dados na tabela:

function addTabela(nome, peso, altura, imc){
  
  let colunaNome = document.createElement('td');
  colunaNome.innerHTML = nome;

  let colunaPeso = document.createElement('td');
  colunaPeso.innerHTML = peso;

  let colunaAltura = document.createElement('td');
  colunaAltura.innerHTML = altura;

  let colunaIMC = document.createElement('td');
  colunaIMC.innerHTML = imc;

  let colunaDeletar = document.createElement('td');
  let btnDeletar = document.createElement('button');
  btnDeletar.innerHTML = '<img src="assets/images/delete.svg" alt="Deletar IMC">';
  btnDeletar.classList.add('btn');
  btnDeletar.classList.add('btn-danger');  
  colunaDeletar.appendChild(btnDeletar);

  let linha = document.createElement('tr');
  linha.appendChild(colunaNome);
  linha.appendChild(colunaPeso);
  linha.appendChild(colunaAltura);
  linha.appendChild(colunaIMC);
  linha.appendChild(colunaDeletar);

  tabela.appendChild(linha);
}

Modificando o event listerner do botão para cálculo de IMC para que, além de calcular o IMC, adicione os dados na tabela:

document.querySelector("#btn-calcular").addEventListener("click", (event) => {
  event.preventDefault();
  let imc = calcularIMC(peso.value, altura.value);
  addTabela(nome.value, peso.value, altura.value, imc.toFixed(2));
});

Limpando o form

Após adicionar os dados na tabela precisamos limpar o formulário para receber novos dados:

function limparFormulario(){
  nome.value = '';
  peso.value = '';
  altura.value = '';
  // Também vamos setar o focus para o campo nome
  nome.focus();
}

Modificando o event listerner do botão para cálculo de IMC para que, além de calcular o IMC, limpe o formulário:

document.querySelector("#btn-calcular").addEventListener("click", (event) => {
  event.preventDefault();
  let imc = calcularIMC(peso.value, altura.value);
  addTabela(nome.value, peso.value, altura.value, imc.toFixed(2));
  limparFormulario();
});

Criando uma função para persistir os dados no LocalStorage

Os dados adicionados na tabela são descartados quando fechamos a aba ou o navegador. Assim, vamos utilizar o LocalStorage para persistir esses dados. Vamos criar uma função que faça essa persistência:

function addLocalStorage(nome, peso, altura, imc){

  let pessoa = {
    "nome": nome,
    "peso": peso,
    "altura": altura,
    "imc": imc
  }

  if (localStorage.getItem("listaIMC")){
    
    let listaIMC = JSON.parse(localStorage.getItem("listaIMC"));
    listaIMC.push(pessoa);
    localStorage.setItem("listaIMC", JSON.stringify(listaIMC));
  
  } else {

    let listaIMC = [];
    listaIMC.push(pessoa);
    localStorage.setItem("listaIMC", JSON.stringify(listaIMC));
  }
}

Vamos modificar o event listerner do botão para calcular o IMC, limpar o formulário e adicionar os dados no LocalStorage. Perceba que não vamos mais adicionar os dados diretamente na tabela:

document.querySelector("#btn-calcular").addEventListener("click", (event) => {
  event.preventDefault();
  let imc = calcularIMC(peso.value, altura.value);
  addLocalStorage(nome.value, peso.value, altura.value, imc);
  // addTabela(nome.value, peso.value, altura.value, imc);
  limparFormulario();
});

Para testar se os dados estão sendo persistidos no LocalStorage abra o inspetor do navegador e vá na aba Application. Abra LocalStorage.

Criando uma função para carregar os dados do LocalStorage na tabela:

Agora que temos uma função para adicionar no LocaStorage vamos criar uma função para carregar os dados do LocalStorage e montar nossa tabela:

function carregarLocalStorage(){
  
  limparTabela();

  if (localStorage.getItem("listaIMC")){
    
    let listaIMC = JSON.parse(localStorage.getItem("listaIMC"));
    listaIMC.forEach((pessoa, indice) => {
      addTabela(pessoa.nome, pessoa.peso, pessoa.altura, pessoa.imc, indice);
    });
  }
}

Como declaramos uma função para limpar os dados da tabela precisamos codifica-la:

function limparTabela(){
  let qtdLinhas = tabela.rows.length;
  for (let i = qtdLinhas - 1; i > 0; i--){
    tabela.deleteRow(i);
  }
}

Vamos modificar o event listerner do botão para calcular o IMC, limpar o formulário, adicionar os dados no LocalStorage, bem como, carregar os dados do LocalStorage para a tabela:

document.querySelector("#btn-calcular").addEventListener("click", (event) => {
  event.preventDefault();
  let imc = calcularIMC(peso.value, altura.value);
  addLocalStorage(nome.value, peso.value, altura.value, imc);
  carregarLocalStorage();
  limparFormulario();
});

Também precisamos executar a função carregarLocalStorage() quando a página for (re)carregada. No final do arquivo index.html chame a função:

<script>
  carregarLocalStorage();
</script>

Deletando dados

Vamos criar uma função para que, ao clicar no botão de deleção, os dados sejam deletados do LocalStorage:

function deletarLinha(index){
  
  let pessoas = JSON.parse(localStorage.getItem("listaIMC"));
  pessoas.splice(index, 1);
  localStorage.setItem("listaIMC", JSON.stringify(pessoas));
  carregarLocalStorage();
}

Também devemos colocar um event listerner em cada botão de deleção. Para isso vamos modificar a função addTabela():

function addTabela(nome, peso, altura, imc, indice){
  
  let colunaNome = document.createElement('td');
  colunaNome.innerHTML = nome;

  let colunaPeso = document.createElement('td');
  colunaPeso.innerHTML = peso;

  let colunaAltura = document.createElement('td');
  colunaAltura.innerHTML = altura;

  let colunaIMC = document.createElement('td');
  colunaIMC.innerHTML = imc.toFixed(2);

  let colunaDeletar = document.createElement('td');
  let btnDeletar = document.createElement('button');
  btnDeletar.innerHTML = '<img src="assets/images/delete.svg" alt="Deletar IMC">';
  btnDeletar.classList.add('btn');
  btnDeletar.classList.add('btn-danger');
  
  // Adicionando um event listerner
  btnDeletar.addEventListener("click", (event) => {
    event.preventDefault();
    deletarLinha(indice);
  });
  
  colunaDeletar.appendChild(btnDeletar);

  let linha = document.createElement('tr');
  linha.appendChild(colunaNome);
  linha.appendChild(colunaPeso);
  linha.appendChild(colunaAltura);
  linha.appendChild(colunaIMC);
  linha.appendChild(colunaDeletar);

  tabela.appendChild(linha);
}

Adicionando mensagens

Para adicionar mensagens para o usuário vamos mapear a div que vai recebe-las:

let mensagem = document.querySelector("#mensagem");

E implementar uma função para mostrar as mensagens:

function mostrarMensagem(msg, tipo){
  
  mensagem.innerHTML = msg;
  mensagem.classList.add("d-block");

  if (tipo == 'add'){
    mensagem.classList.add("alert-success");
  } else if (tipo == 'delete'){
    mensagem.classList.add("alert-danger");
  } else if (tipo == 'table'){
    mensagem.classList.add("alert-warning");
  }

  setTimeout(() => {
    mensagem.innerHTML = "";
    mensagem.classList.remove("alert-danger");
    mensagem.classList.remove("alert-success");
    mensagem.classList.remove("alert-warning");
    mensagem.classList.remove("d-none");
  }, 2000);
}

Vamos adicionar uma mensagem para avisar que um dado foi gravado no LocalStorage:

function addLocalStorage(nome, peso, altura, imc){

  let pessoa = {
    "nome": nome,
    "peso": peso,
    "altura": altura,
    "imc": imc
  }

  if (localStorage.getItem("listaIMC")){
    
    let listaIMC = JSON.parse(localStorage.getItem("listaIMC"));
    listaIMC.push(pessoa);
    localStorage.setItem("listaIMC", JSON.stringify(listaIMC));
  
  } else {

    let listaIMC = [];
    listaIMC.push(pessoa);
    localStorage.setItem("listaIMC", JSON.stringify(listaIMC));
  }

  // Utilizando a função para mostrar a mensagem que o dado foi gravado no LocalStorage
  mostrarMensagem("IMC cadastrado!", "add");
}

Também vamos adicionar uma mensagem para avisar que um dado foi deletado do LocaStorage:

function deletarLinha(index){
  
  let pessoas = JSON.parse(localStorage.getItem("listaIMC"));
  pessoas.splice(index, 1);
  localStorage.setItem("listaIMC", JSON.stringify(pessoas));
  carregarLocalStorage();

  // Utilizando a função para mostrar a mensagem que o dado foi removido do LocalStorage
  mostrarMensagem("IMC deletado!", "delete");
}

Por fim, vamos mostrar uma mensagem caso a tabela não tenha dados:

function carregarLocalStorage(){
  
  limparTabela();

  if (localStorage.getItem("listaIMC")){
    
    let listaIMC = JSON.parse(localStorage.getItem("listaIMC"));
    listaIMC.forEach((pessoa, indice) => {
      addTabela(pessoa.nome, pessoa.peso, pessoa.altura, pessoa.imc, indice);
    });

  } else {

    // Utilizando a função para mostrar que não há dados no LocalStorage
    mostrarMensagem("Nenhum IMC a ser exibido", "table");
  }
}
Este site usa cookies próprios e de terceiros para melhorar os seus serviços, elaborar informação estatística e mostrar conteúdos ou serviços personalizados através da análise da sua navegação. Para aceitar o seu uso, você pode clicar em Aceitar ou continuar navegando. Além disso, você pode configurar ou rejeitar o uso de cookies ajustando suas Configurações. Para obter mais informações sobre o uso de cookies e seus direitos, acesse nossa Política de Cookies