275 bytes BMI Calculator

madsstoumann

Mads Stoumann

Posted on January 4, 2021

275 bytes BMI Calculator

You don't always need a large frontend framework for interactive components.

As an example, I've made a BMI Calculator, which is only 275 bytes, minified and gzipped.

I always wrap smaller, interactive components, in either a <form> or a <fieldset>-tag.
Depending on the component, I add a single eventListener, either onchange or oninput.

This is a "catch all" for any input within the <form> or <fieldset>. If I need to know the specific element that changed, it's in the event.target.

Let's dissect the calculator. The <form> has two <input type="range"> (height, weight) and three <output>-tags (height info, weight info, bmi result).

Excerpt:

<input type="range" name="h" min="150" max="230" step="0.5" value="180" />
<output name="ho"><output>
Enter fullscreen mode Exit fullscreen mode

The un-minified JavaScript-code looks like this:

function B() {
  const groups = [[0,18.49], [18.5,24.99], [25,29.99], [30,34.99], [35,39.99], [40,100]];
  const height = this.h.valueAsNumber;
  const weight = this.w.valueAsNumber;
  const bmi = parseFloat(weight / ((height / 100) ** 2)).toFixed(2);
  const index = groups.findIndex(arr => arr[0] <= bmi && bmi < arr[1]);
  let inches = (height*0.393700787).toFixed(0);
  this.ho.value = `${height} cm / ${Math.floor(inches / 12)}' ${inches %= 12}"`;
  this.wo.value = `${weight} kg / ${(weight*2.2046).toFixed(2)} lb`;
  this.g[index].checked = true;
  this.r.value = bmi;
}
Enter fullscreen mode Exit fullscreen mode

groups is an array of BMI-ranges, corresponding to the six BMI-groups (underweight, normal weight etc.).

height and weight are references to the range-input values.

bmi is the formula for calculating a BMI using height and weight.

index finds the index of the BMI-group, in which range the current bmi is found. This value is later used to set the current BMI-group (a radio-button-group):

this.g[index].checked = true;
Enter fullscreen mode Exit fullscreen mode

An <output>-tag can either be set using .innerText or .value. I prefer the latter, and that's how the labels are set, as an example:

this.r.value = bmi;
Enter fullscreen mode Exit fullscreen mode

And the result:

The code itself is 381 bytes, gzipped approx. 275 bytes. However, if your modules are so small, there's no benefit in gzipping them, as the "un-gzipping" will take longer than the benefit of the smaller file-size.

Thanks for reading, and happy coding!

💖 💪 🙅 🚩
madsstoumann
Mads Stoumann

Posted on January 4, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related