patternjavascriptMinor
Calculating Body Mass Index (BMI)
Viewed 0 times
indexmassbmicalculatingbody
Problem
This is an HTML / JavaScript app for calculating someones body mass index.
The app does conversion of metric to standard measurements and standard to metric.
It outputs:
```
//Constants
var POUNDS_IN_STONE = 14;
var KGS_PER_POUND = 0.453592;
var INCHES_IN_FOOT = 12;
var CMS_PER_INCH = 2.54;
var CMS_PER_METRE = 100;
var INPUT_ERROR_MSG = "That was not a valid measurement unit. Please try again";
var IDEAL_BMI_LOWER = 18.5;
var IDEAL_BMI_UPPER = 25;
//Global Variables
var stoneField = document.forms["bmiForm"]["stone"];
var poundsField = document.forms["bmiForm"]["pounds"]
var kgsField = document.forms["bmiForm"]["kgs"];
var feetField = document.forms["bmiForm"]["feet"];
var inchesField = document.forms["bmiForm"]["inches"];
var cmsField = document.forms["bmiForm"]["cms"];
//Register Event handlers
document.getElementById("button").onclick = function() { outputBmi() };
stoneField.onchange = function() { updateForm( "stonefld" ) };
stoneField.onchange = function() { updateForm( "poundsfld" ) };
kgsField.onchange = function() { updateForm( "kgsfld" ) };
The app does conversion of metric to standard measurements and standard to metric.
It outputs:
- BMI
- weight category
- ideal weight range for given height
- percentage over/under ideal weight
index.html
BMI Calculator
#mainDisplay
{
padding:25px;
}
#form
{
width:250px;
}
#results
{
background-color:#E6E6E6;
width:450px;
}
below -->
BMI Calculator
Enter your weight
Stone
Pounds
OR
KGs
Enter your height
Feet
Inches
OR
CMs
formScript.js```
//Constants
var POUNDS_IN_STONE = 14;
var KGS_PER_POUND = 0.453592;
var INCHES_IN_FOOT = 12;
var CMS_PER_INCH = 2.54;
var CMS_PER_METRE = 100;
var INPUT_ERROR_MSG = "That was not a valid measurement unit. Please try again";
var IDEAL_BMI_LOWER = 18.5;
var IDEAL_BMI_UPPER = 25;
//Global Variables
var stoneField = document.forms["bmiForm"]["stone"];
var poundsField = document.forms["bmiForm"]["pounds"]
var kgsField = document.forms["bmiForm"]["kgs"];
var feetField = document.forms["bmiForm"]["feet"];
var inchesField = document.forms["bmiForm"]["inches"];
var cmsField = document.forms["bmiForm"]["cms"];
//Register Event handlers
document.getElementById("button").onclick = function() { outputBmi() };
stoneField.onchange = function() { updateForm( "stonefld" ) };
stoneField.onchange = function() { updateForm( "poundsfld" ) };
kgsField.onchange = function() { updateForm( "kgsfld" ) };
Solution
-
Constants; instead of creating a bunch of standalone keys I'd group them in a single object, like:
-
Globals; I would prefer using ids on the input fields (or even better, a jQuery selector) to retrieve them rather than going through
-
Globals; Even more than above, I'd prefer not having these globals at all. Instead you could retrieve them as needed in your functions (and/or pass them in as parameters).
-
Event Handlers; If you're just going to use the
Note that this allows you to easily pass the
-
Functions; I'd recommend the following style when writing functions:
-
Separation of logic and presentation; Instead of composing a big long HTML string in
Constants; instead of creating a bunch of standalone keys I'd group them in a single object, like:
var bmiConstants = {
POUNDS_IN_STONE: 14,
KGS_PER_POUND: 0.453592,
INCHES_IN_FOOT: 12,
CMS_PER_INCH: 2.54,
CMS_PER_METRE: 100,
INPUT_ERROR_MSG: "That was not a valid measurement unit. Please try again",
IDEAL_BMI_LOWER: 18.5,
IDEAL_BMI_UPPER: 25
};-
Globals; I would prefer using ids on the input fields (or even better, a jQuery selector) to retrieve them rather than going through
document.forms. Like:var stoneField = document.getElementById("stones");
var poundsField = document.getElementById("pounds");
//...-
Globals; Even more than above, I'd prefer not having these globals at all. Instead you could retrieve them as needed in your functions (and/or pass them in as parameters).
-
Event Handlers; If you're just going to use the
onclick and onchange attributes, there's no need to bind them programmatically. You can set them up in your markup instead, like:Note that this allows you to easily pass the
input field itself to updateForm(), instead of just an arbitrary key.-
Functions; I'd recommend the following style when writing functions:
function roundTwoDecimals(number) {
return Math.round(number * 100) / 100;
}-
Separation of logic and presentation; Instead of composing a big long HTML string in
outputBmi() I'd recommend having the basic structure of the output as part of your markup. For instance, contained within a div that is set to display: none initially. Then the only thing outputBmi() needs to do is update the parts that actually change and toggle the visibility of the div. That will result in less code and be more maintainable than trying to construct the entire HTML snippet programmatically.Code Snippets
var bmiConstants = {
POUNDS_IN_STONE: 14,
KGS_PER_POUND: 0.453592,
INCHES_IN_FOOT: 12,
CMS_PER_INCH: 2.54,
CMS_PER_METRE: 100,
INPUT_ERROR_MSG: "That was not a valid measurement unit. Please try again",
IDEAL_BMI_LOWER: 18.5,
IDEAL_BMI_UPPER: 25
};var stoneField = document.getElementById("stones");
var poundsField = document.getElementById("pounds");
//...<input type = "text" name = "stone" size = "1" maxlength = "2" onchange="updateForm(this);" />
<input type = "text" name = "pounds" size = "2" maxlength = "6" onchange="updateForm(this);" />
<!-- ... -->
<input id = "button" type="button" value = "Find out your BMI" onclick="outputBmi();" />function roundTwoDecimals(number) {
return Math.round(number * 100) / 100;
}Context
StackExchange Code Review Q#21581, answer score: 7
Revisions (0)
No revisions yet.