TT

Javascript ile BMI Hesaplayıcı Nasıl Yapılır?

yazıldı3 dakika okuma süresi

Öncelikle belirtmeliyim ki ben kendi halinde bir çevre mühendisiyim ve üniversitede yalandan gördüğüm Matlab dışında herhangi bir yazılım geçmişim yok fakat merakım var. Madem merakın var neden öğrenmiyorsun diye düşünebilirsiniz, ona da cevap olarak çabuk sıkılıyorum diyebilirim. Uzun uzun bir şeyleri okuyup öğrenenemediğimden direkt olaya dalıp bir amaca hizmet eden ufak programları çeşitlendirerek öğrenmeyi yeğliyorum. Shell script olsun, Python olsun, bu site ve diğer tasarladığım sitelerdeki gibi HTML, CSS, JS olsun hepsi başkalarının kodlarını inceleyerek öğrendiğim şeyler oldu.

Bu BMI hesaplayıcısını yapmam 4 saatimi aldı; Stackoverflow, bloglar, kılavuzlar derken bir sürü açıklamanın ve kodun arasından birleştirip nihayet başardım. Ne kadar doğru bir yaklaşım olmuştur, daha basit yöntem var mıdır bilemem ama çalışıyor en azından. Artık bunu ihtiyaç olduğunda basit formülleri hesaplamak için kullanırım.

Artık başlayalım. Öncelikle bir form oluşturup kilo ve boy girecek inputlar ekliyoruz. Daha sonra da bir hesapla butonu ve sonuçların gösterileceği bir textarea ekliyoruz. Yapabilir miyim diye merakımdan bir de sonuç grafiği ekledim, o da sonucun aralığına göre belirli bir renkte çarpı işareti olarak görünüyor.

<div class="bmicalculator">
  <p class="title">BMI Hesaplayıcı</p>
 
  <form name="BMIform">
    <label for="height">Boy (cm)</label>
    <input type="text" name="height" placeholder="Santimetre olarak giriniz...">
    <label for="weight">Kilo (kg)</label>
    <input type="text" name="weight" placeholder="Kilogram olarak giriniz...">
  </form>
 
  <button id="submit" onclick="bmicalc()">Hesapla</button>
  <br>
  <div id="bmigraph">
    <span id="uw">&nbsp;</span>
    <span id="nr">&nbsp;</span>
    <span id="ow">&nbsp;</span>
    <span id="ob">&nbsp;</span>
  </div>
  <textarea id="result"></textarea>
</div>

CSS olmadan hiçbir şeye benzemediği için bir de stil hazırlamamız gerekiyor. Form içeriğini düzenlemek için grid kullandım, grafik alanı için de flex kullandım. Renkleri de Happy Hues'dan aldım.

.bmicalculator {
  width: 25rem;
  margin: 0 auto;
  background-color: #faeee7;
  padding: 1em;
  border: 5px solid #33272a;
  border-radius: 6px;
  box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);
}
.title {
  text-align: center;
  font-weight: bold;
  font-size: 1.2rem;
  margin-top: 0;
}
input[type="text"],
textarea {
  width: 100%;
  padding: 12px 20px;
  margin: 8px 0;
  display: inline-block;
  border: 3px solid #33272a;
  border-radius: 4px;
  box-sizing: border-box;
}
button {
  width: 100%;
  background-color: #ff8ba7;
  color: #33272a;
  font-weight: bold;
  padding: 14px 20px;
  margin: 8px 0;
  border: 3px solid #33272a;
  border-radius: 4px;
  cursor: pointer;
}
button:hover {
  background-color: #e57d96;
}
form {
  width: 100%;
  display: grid;
  grid-template-columns: 5.25rem 1fr;
  grid-template-rows: repeat(2, 3em);
  grid-row-gap: 4px;
  align-items: center;
}
form label {
  font-weight: bold;
}
form label:after {
  content: ":";
}
#bmigraph {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: center;
  border: 3px solid #33272a;
  border-radius: 4px;
}
#bmigraph > span {
  width: calc(100% / 4);
  padding: 0.5em 0;
  text-align: center;
  font-weight: bold;
  font-size: 2em;
  color: white;
}
#bmigraph > span:nth-child(1) {
  background-color: #3da9fc;
}
#bmigraph > span:nth-child(2) {
  background-color: #2cb67d;
}
#bmigraph > span:nth-child(3) {
  background-color: #ff8e3c;
}
#bmigraph > span:nth-child(4) {
  background-color: #f25f4c;
}

Gelelim javascript bölümüne. Bu kısım beni saatlerce uğraştırdı. Sayıları karşılaştırma konusunda sorun yaşadım; ben if (18.5 <= result <= 24.9) şeklinde karşılaştırmaya çalışırken if (18.5 <= result && result <= 24.9) şeklinde olması gerekiyormuş. Tabi buna gelene kadar acaba bunlardan bazıları float bazıları string olabilir mi diye düşünüp bir süre hepsini dönüştürmeye çalıştım falan derken oldukça zamanım gitti.

Bu sorunu çözdükten sonra keyfi olarak koyduğum grafik sorun çıkarmaya başladı; hesaplayıcıyı farklı değerlerle her çalıştırdığımda eski çarpı işareti silinmeden yenisini koyuyordu, en nihayetinde her yer işaretlenmiş görünüyordu. Bunun için de grafikteki her alanı önce temizleyip ondan sonra ilgili alana işaretleme yapacak şekilde ayarlayarak çözdüm.

function bmicalc() {
  // BMIform isimli formun height ve weight isimli inputlarından
  // alınan değerleri değişken olarak tanımla
  var height = document.BMIform.height.value;
  var weight = document.BMIform.weight.value;
  // sonucu ve yorumu ekleyeceğimiz result ve comment değişkenlerini tanımla
  var result;
  var comment;
 
  // BMI hesaplama formülü
  result = weight / ((height * height) / 10000);
  // Virgülden sonra iki basamak göster
  result = result.toFixed(2);
 
  // İleride grafiğe koyacağımız "X" işaretlerini boşluk (&nbsp;) ile değiştir
  // Böylelikle fonksiyon çalıştığında varsa önceki işaretler silinir
  var x = document.getElementById("bmigraph").getElementsByTagName("span");
  var i;
  for (i = 0; i < x.length; i++) {
    x[i].innerHTML = "&nbsp;";
  }
 
  // BMI formülü ile elde ettiğimiz sonucu değer aralıklarıyla kıyasla
  // Kıyaslamaya göre yorum ekle ve grafikte ilgili bölümü işaretle
  if (result < 18.5) {
    comment = "az";
    document.getElementById("uw").innerHTML = "X";
  } else if (18.5 <= result && result <= 24.9) {
    comment = "normal";
    document.getElementById("nr").innerHTML = "X";
  } else if (24.9 < result && result <= 29.9) {
    comment = "olması gerekenden fazla";
    document.getElementById("ow").innerHTML = "X";
  } else if (29.9 < result) {
    comment = "aşırı fazla";
    document.getElementById("ob").innerHTML = "X";
  }
 
  // Yukarıdaki tanımladığımız değişkenleri ve sonucu
  // result kimliğine sahip textarea bölümüne ekle
  document.getElementById("result").value =
    "BMI Sonucu: " + result + "\n" + "Kilonuz " + comment + ".";
}

🎉 Sonuç:

BMI Hesaplayıcı

Codepen üzerinden deneyebilirsiniz sonucu.

© 2024Taylan Tatlı