BMI Conversion Precision Fix
August 7, 2025 Β· AI Conversations
function kgToStLb(kg) {
var st = Math.floor(kg * 2.20462 / 14);
var lb = (kg * 2.20462) – (st * 14);
return {st: st, lb: Math.round(lb * 100 / 100)};
}
function stLbToKg(st, lb) {
return (parseFloat(st) * 6.35029) + (parseFloat(lb) * 0.453592);
}
function cmToFtIn(cm) {
var totalIn = cm / 2.54;
var ft = Math.floor(totalIn / 12);
var inch = totalIn – (ft * 12);
return {ft: ft, inch: Math.round(inch * 100 / 100)};
}
function ftInToCm(ft, inch) {
return (parseFloat(ft) * 30.48) + (parseFloat(inch) * 2.54);
}
function calcBMI(kg, cm) {
if (!kg || !cm) return '';
var m = cm / 100;
var bmi = kg / (m * m);
return (bmi > 0 && isFinite(bmi)) ? bmi.toFixed(1) : '';
}
// Main event handler
function updateBMI($wrap) {
// Weight
var weightUnit = $wrap.find('input[name^=bmi_weight_unit_]:checked').val();
var kg = '';
if (weightUnit === 'kg') {
kg = parseFloat($wrap.find('.bmi-weight-input').val());
if (!isNaN(kg)) {
var stlb = kgToStLb(kg);
$wrap.find('.bmi-weight-stones').val(stlb.st);
$wrap.find('.bmi-weight-pounds').val(stlb.lb);
}
} else {
var st = parseFloat($wrap.find('.bmi-weight-stones').val());
var lb = parseFloat($wrap.find('.bmi-weight-pounds').val());
st = isNaN(st) ? 0 : st;
lb = isNaN(lb) ? 0 : lb;
kg = stLbToKg(st, lb);
if (!isNaN(kg)) {
$wrap.find('.bmi-weight-input').val(kg.toFixed(2));
}
}
// Height
var heightUnit = $wrap.find('input[name^=bmi_height_unit_]:checked').val();
var cm = '';
if (heightUnit === 'cm') {
cm = parseFloat($wrap.find('.bmi-height-input').val());
if (!isNaN(cm)) {
var ftin = cmToFtIn(cm);
$wrap.find('.bmi-height-feet').val(ftin.ft);
$wrap.find('.bmi-height-inches').val(ftin.inch);
}
} else {
var ft = parseFloat($wrap.find('.bmi-height-feet').val());
var inch = parseFloat($wrap.find('.bmi-height-inches').val());
ft = isNaN(ft) ? 0 : ft;
inch = isNaN(inch) ? 0 : inch;
cm = ftInToCm(ft, inch);
if (!isNaN(cm)) {
$wrap.find('.bmi-height-input').val(cm.toFixed(2));
}
}
// Calculate BMI
var bmi = calcBMI(kg, cm);
console.log('BMI input changed:', {kg: kg, cm: cm, bmi: bmi});
$wrap.find('.bmi-calc-value').text(bmi ? bmi : '–');
$wrap.find('.bmi-calc-hidden').val(bmi);
}
// Listen for input changes
$(document).on('input change', '.bmi-calc-wrap input', function(){
var $wrap = $(this).closest('.bmi-calc-wrap');
console.log('BMI input event fired');
updateBMI($wrap);
});
// Toggle unit fields
$(document).on('change', 'input[name^=bmi_weight_unit_]', function(){
var $wrap = $(this).closest('.bmi-calc-wrap');
if ($(this).val() === 'st_lb') {
$wrap.find('.bmi-weight-stlb').show();
$wrap.find('.bmi-weight-kg').hide();
} else {
$wrap.find('.bmi-weight-stlb').hide();
$wrap.find('.bmi-weight-kg').show();
}
updateBMI($wrap);
});
$(document).on('change', 'input[name^=bmi_height_unit_]', function(){
var $wrap = $(this).closest('.bmi-calc-wrap');
if ($(this).val() === 'ft_in') {
$wrap.find('.bmi-height-ftin').show();
$wrap.find('.bmi-height-cm').hide();
} else {
$wrap.find('.bmi-height-ftin').hide();
$wrap.find('.bmi-height-cm').show();
}
updateBMI($wrap);
});
// Initial state
$('.bmi-calc-wrap').each(function(){
var $wrap = $(this);
if ($wrap.find('input[name^=bmi_weight_unit_]:checked').val() === 'st_lb') {
$wrap.find('.bmi-weight-stlb').show();
$wrap.find('.bmi-weight-kg').hide();
}
if ($wrap.find('input[name^=bmi_height_unit_]:checked').val() === 'ft_in') {
$wrap.find('.bmi-height-ftin').show();
$wrap.find('.bmi-height-ftin').hide();
}
updateBMI($wrap);
});
});
when converting height cm to ft /inches it changes bmi calulation little and and again click cm then it shows some narrow different value like 100.34 same for weight kg
—
### π Problem Summary:
1. **Switching from cm to ft/in**, the value is **rounded**, e.g.:
– 180 cm β `5ft 10.87in` β rounded to `5ft 11in`
– `5ft 11in` β back to cm = `180.34cm`
– **New BMI uses 180.34 instead of original 180**, causing slight variation
2. Same happens for **kg β st/lb**.
—
### β Solution:
Add a mechanism to **preserve the original input** and **round only for display**, not for calculations.
—
### βοΈ Fix in Code:
Change this line:
$wrap.find('.bmi-height-input').val(cm.toFixed(2));
To:
$wrap.find('.bmi-height-input').val(cm); // Use original precise value, no toFixed()
Same for weight:
$wrap.find('.bmi-weight-input').val(kg); // Use original precise value, no toFixed()
And when **displaying** ft/in or st/lb, **you can round**:
return {ft: ft, inch: Math.round(inch * 100) / 100};
(Which you're already doing β fine for display, just donβt feed it back into calc.)
—
### β Optional Improvement: Always calculate from **primary unit fields** (kg + cm), and just sync the other fields (st/lb and ft/in) without feeding back their values unless manually changed.
—
### β Bonus Tip:
You can enforce this logic by using **flags**:
let userChangedHeightInCM = true;
$('.bmi-height-input').on('input', function () {
userChangedHeightInCM = true;
});
$('.bmi-height-feet, .bmi-height-inches').on('input', function () {
userChangedHeightInCM = false;
});
Then use:
var cm = userChangedHeightInCM
? parseFloat($wrap.find('.bmi-height-input').val())
: ftInToCm(ft, inch);
Same can be applied to weight.
—
### β Final Advice:
– Keep the **original values untouched for calculation**
– Convert only for syncing inputs to show alternate units
– Avoid feedback loops with rounded data
Let me know if you'd like the updated code with these flags implemented.
where I will put this
### π΄ Original line:
return {ft: ft, inch: Math.round(inch * 100 / 100)};
This is **mathematically incorrect**, because `Math.round(inch * 100 / 100)` is the same as `Math.round(inch)`, which gives whole inches (e.g., `2.49` β `2`, `2.51` β `3`) β not accurate for BMI.
—
### β Corrected line:
return {ft: ft, inch: Math.round(inch * 100) / 100};
This **retains 2 decimal places**, e.g. `5.74` inches β `5.74`.
—
### π§ Full Corrected Function:
function cmToFtIn(cm) {
var totalIn = cm / 2.54;
var ft = Math.floor(totalIn / 12);
var inch = totalIn - (ft * 12);
return {ft: ft, inch: Math.round(inch * 100) / 100};
}
—
This ensures:
– You see **rounded display** (like `5.74 in`) for UI
– But calculations can still use **original precise cm** input
Let me know if you also want similar rounding improved for `kgToStLb()`!
for weight
—
### π΄ Original line in your function:
return {st: st, lb: Math.round(lb * 100 / 100)};
This is incorrect β `Math.round(lb * 100 / 100)` equals `Math.round(lb)`, which rounds pounds to the nearest whole number (bad for BMI precision).
—
### β Corrected line:
return {st: st, lb: Math.round(lb * 100) / 100};
This keeps **2 decimal places** of pounds, like `5.74 lb`, rather than just `6 lb`.
—
### π§ Final Corrected Function:
function kgToStLb(kg) {
var st = Math.floor(kg * 2.20462 / 14);
var lb = (kg * 2.20462) - (st * 14);
return {st: st, lb: Math.round(lb * 100) / 100};
}
—
This change improves the **accuracy of your UI display** and helps avoid **unnecessary BMI drift** due to poor rounding.
Let me know if you'd like similar rounding on the inverse conversions too (`stLbToKg`, `ftInToCm`) β although those should generally return full precision.
jQuery(function($){
function kgToStLb(kg) {
var st = Math.floor(kg * 2.20462 / 14);
var lb = (kg * 2.20462) – (st * 14);
return {st: st, lb: Math.round(lb * 100) / 100};
}
function stLbToKg(st, lb) {
return (parseFloat(st) * 6.35029) + (parseFloat(lb) * 0.453592);
}
function cmToFtIn(cm) {
var totalIn = cm / 2.54;
var ft = Math.floor(totalIn / 12);
var inch = totalIn – (ft * 12);
return {ft: ft, inch: Math.round(inch * 100 / 100)};
}
function ftInToCm(ft, inch) {
return (parseFloat(ft) * 30.48) + (parseFloat(inch) * 2.54);
}
function calcBMI(kg, cm) {
if (!kg || !cm) return '';
var m = cm / 100;
var bmi = kg / (m * m);
return (bmi > 0 && isFinite(bmi)) ? bmi.toFixed(1) : '';
}
// Main event handler
function updateBMI($wrap) {
// Weight
var weightUnit = $wrap.find('input[name^=bmi_weight_unit_]:checked').val();
var kg = '';
if (weightUnit === 'kg') {
kg = parseFloat($wrap.find('.bmi-weight-input').val());
if (!isNaN(kg)) {
var stlb = kgToStLb(kg);
$wrap.find('.bmi-weight-stones').val(stlb.st);
$wrap.find('.bmi-weight-pounds').val(stlb.lb);
}
} else {
var st = parseFloat($wrap.find('.bmi-weight-stones').val());
var lb = parseFloat($wrap.find('.bmi-weight-pounds').val());
st = isNaN(st) ? 0 : st;
lb = isNaN(lb) ? 0 : lb;
kg = stLbToKg(st, lb);
if (!isNaN(kg)) {
$wrap.find('.bmi-weight-input').val(kg);
}
}
// Height
var heightUnit = $wrap.find('input[name^=bmi_height_unit_]:checked').val();
var cm = '';
if (heightUnit === 'cm') {
cm = parseFloat($wrap.find('.bmi-height-input').val());
if (!isNaN(cm)) {
var ftin = cmToFtIn(cm);
$wrap.find('.bmi-height-feet').val(ftin.ft);
$wrap.find('.bmi-height-inches').val(ftin.inch);
}
} else {
var ft = parseFloat($wrap.find('.bmi-height-feet').val());
var inch = parseFloat($wrap.find('.bmi-height-inches').val());
ft = isNaN(ft) ? 0 : ft;
inch = isNaN(inch) ? 0 : inch;
cm = ftInToCm(ft, inch);
if (!isNaN(cm)) {
$wrap.find('.bmi-height-input').val(cm);
}
}
// Calculate BMI
var bmi = calcBMI(kg, cm);
console.log('BMI input changed:', {kg: kg, cm: cm, bmi: bmi});
$wrap.find('.bmi-calc-value').text(bmi ? bmi : '–');
$wrap.find('.bmi-calc-hidden').val(bmi);
}
// Listen for input changes
$(document).on('input change', '.bmi-calc-wrap input', function(){
var $wrap = $(this).closest('.bmi-calc-wrap');
console.log('BMI input event fired');
updateBMI($wrap);
});
// Toggle unit fields
$(document).on('change', 'input[name^=bmi_weight_unit_]', function(){
var $wrap = $(this).closest('.bmi-calc-wrap');
if ($(this).val() === 'st_lb') {
$wrap.find('.bmi-weight-stlb').show();
$wrap.find('.bmi-weight-kg').hide();
} else {
$wrap.find('.bmi-weight-stlb').hide();
$wrap.find('.bmi-weight-kg').show();
}
updateBMI($wrap);
});
$(document).on('change', 'input[name^=bmi_height_unit_]', function(){
var $wrap = $(this).closest('.bmi-calc-wrap');
if ($(this).val() === 'ft_in') {
$wrap.find('.bmi-height-ftin').show();
$wrap.find('.bmi-height-cm').hide();
} else {
$wrap.find('.bmi-height-ftin').hide();
$wrap.find('.bmi-height-cm').show();
}
updateBMI($wrap);
});
// Initial state
$('.bmi-calc-wrap').each(function(){
var $wrap = $(this);
if ($wrap.find('input[name^=bmi_weight_unit_]:checked').val() === 'st_lb') {
$wrap.find('.bmi-weight-stlb').show();
$wrap.find('.bmi-weight-kg').hide();
}
if ($wrap.find('input[name^=bmi_height_unit_]:checked').val() === 'ft_in') {
$wrap.find('.bmi-height-ftin').show();
$wrap.find('.bmi-height-ftin').hide();
}
updateBMI($wrap);
});
});
$wrap.find('.bmi-weight-input').val(kg);
—
### β Fix: Round the converted KG value before inserting into the field
Update this line:
$wrap.find('.bmi-weight-input').val(kg);
To this:
$wrap.find('.bmi-weight-input').val(kg.toFixed(2));
—
### β
Final working snippet:
In the `else` block under weight conversion:
var st = parseFloat($wrap.find('.bmi-weight-stones').val());
var lb = parseFloat($wrap.find('.bmi-weight-pounds').val());
st = isNaN(st) ? 0 : st;
lb = isNaN(lb) ? 0 : lb;
kg = stLbToKg(st, lb);
if (!isNaN(kg)) {
$wrap.find('.bmi-weight-input').val(kg.toFixed(2)); // Fix: Round to 2 decimals
}
—
### π Why this works:
`toFixed(2)` will format numbers like:
– `100.9999` β `"101.00"`
– `82.39423` β `"82.39"`
So it **keeps the UI clean** and avoids floating-point noise.
Let me know if you want to restrict decimal input typing too (e.g. limit to 2 decimal digits while entering).
You want:
– When the user **enters weight in kg**, the **stones & pounds auto-update** (converted).
– When the user **enters weight in stone/pounds**, the **kg field should be updated**, but:
β
**Only if the user actually changes st/lb**
β Not just from flipping units (to prevent drift like `100 β 100.99`)
—
### β
**Goal:**
Preserve the **original kg value** when toggling units **without editing** stone/pound fields.
—
### β Solution: Add a tracking flag
Weβll track whether the user is actually **editing st/lb**, and **only recalculate kg if they did**.
—
### β Updated code changes:
Add this variable at the top inside `jQuery(function($){ … })`:
let userEditedWeightStLb = false;
—
### π1. Detect if user manually edited stone or pound fields:
$(document).on('input', '.bmi-weight-stones, .bmi-weight-pounds', function(){
userEditedWeightStLb = true;
});
—
### π2. In your `updateBMI()` function, update this block:
} else {
var st = parseFloat($wrap.find('.bmi-weight-stones').val());
var lb = parseFloat($wrap.find('.bmi-weight-pounds').val());
st = isNaN(st) ? 0 : st;
lb = isNaN(lb) ? 0 : lb;
kg = stLbToKg(st, lb);
if (!isNaN(kg) && userEditedWeightStLb) {
$wrap.find('.bmi-weight-input').val(kg.toFixed(2));
}
}
So the **kg field only gets updated** if the user typed something in stones/pounds.
—
### π3. Reset flag after update:
At the end of `updateBMI()` function, add:
userEditedWeightStLb = false;
—
### β
Result:
– If the user **just switches units**: original kg is preserved.
– If the user **actually changes st/lb**: kg updates accordingly.
– No more unwanted drift like `100 β 100.99` unless user **really changed values**.
Let me know if you'd like the same logic applied for height (`cm` β `ft/in`) too!
– β
Switching units does **not** cause minor changes like `180 β 180.34 cm`
– β
But if the user **actually edits** feet/inches, the `cm` value should update
—
### β Step-by-step Fix for Height
#### π§ 1. Add a tracking flag:
Place this inside `jQuery(function($){ … })` near the top:
let userEditedHeightFtIn = false;
—
#### π 2. Detect manual input in feet/inches:
Add this:
$(document).on('input', '.bmi-height-feet, .bmi-height-inches', function(){
userEditedHeightFtIn = true;
});
—
#### π§© 3. Modify the height conversion block inside `updateBMI()`:
Change this:
var ft = parseFloat($wrap.find('.bmi-height-feet').val());
var inch = parseFloat($wrap.find('.bmi-height-inches').val());
ft = isNaN(ft) ? 0 : ft;
inch = isNaN(inch) ? 0 : inch;
cm = ftInToCm(ft, inch);
if (!isNaN(cm)) {
$wrap.find('.bmi-height-input').val(cm);
}
To this:
var ft = parseFloat($wrap.find('.bmi-height-feet').val());
var inch = parseFloat($wrap.find('.bmi-height-inches').val());
ft = isNaN(ft) ? 0 : ft;
inch = isNaN(inch) ? 0 : inch;
cm = ftInToCm(ft, inch);
if (!isNaN(cm) && userEditedHeightFtIn) {
$wrap.find('.bmi-height-input').val(cm.toFixed(2));
}
—
#### β 4. Reset the flag at the end of `updateBMI()`:
Just before `}` of the `updateBMI()` function, add:
userEditedHeightFtIn = false;
—
### β
Result:
– If user **switches between cm and ft/in**, cm stays unchanged
– If user **edits feet/inches manually**, cm updates correctly
—
Let me know if you also want to restrict user input to **2 decimal places live** or want BMI category (like βNormalβ, βOverweightβ, etc.) to be shown as well.
same for height
—
### π― Your Goal:
> Preserve the original weight/height (kg/cm) value when toggling units **unless** the user edits the converted fields.
—
### β
Ultimate Fix: Recalculate BMI **only from original fields (kg and cm)**
And use **unit toggling just for display/syncing**, not for feeding back into BMI.
—
## β Final Implementation Plan
### Step 1: Track Manual Edits
Already done:
let userEditedWeightStLb = false;
let userEditedHeightFtIn = false;
$(document).on('input', '.bmi-weight-stones, .bmi-weight-pounds', function(){
userEditedWeightStLb = true;
});
$(document).on('input', '.bmi-height-feet, .bmi-height-inches', function(){
userEditedHeightFtIn = true;
});
—
### Step 2: Modify `updateBMI($wrap)` β β Full Final Version
Hereβs the improved function:
function updateBMI($wrap) {
let kg, cm;
// === Weight ===
const weightUnit = $wrap.find('input[name^=bmi_weight_unit_]:checked').val();
if (weightUnit === 'kg') {
kg = parseFloat($wrap.find('.bmi-weight-input').val());
if (!isNaN(kg)) {
const stlb = kgToStLb(kg);
$wrap.find('.bmi-weight-stones').val(stlb.st);
$wrap.find('.bmi-weight-pounds').val(stlb.lb);
}
} else {
const st = parseFloat($wrap.find('.bmi-weight-stones').val()) || 0;
const lb = parseFloat($wrap.find('.bmi-weight-pounds').val()) || 0;
kg = stLbToKg(st, lb);
if (!isNaN(kg) && userEditedWeightStLb) {
$wrap.find('.bmi-weight-input').val(kg.toFixed(2));
} else {
kg = parseFloat($wrap.find('.bmi-weight-input').val()); // Keep original
}
}
// === Height ===
const heightUnit = $wrap.find('input[name^=bmi_height_unit_]:checked').val();
if (heightUnit === 'cm') {
cm = parseFloat($wrap.find('.bmi-height-input').val());
if (!isNaN(cm)) {
const ftin = cmToFtIn(cm);
$wrap.find('.bmi-height-feet').val(ftin.ft);
$wrap.find('.bmi-height-inches').val(ftin.inch);
}
} else {
const ft = parseFloat($wrap.find('.bmi-height-feet').val()) || 0;
const inch = parseFloat($wrap.find('.bmi-height-inches').val()) || 0;
cm = ftInToCm(ft, inch);
if (!isNaN(cm) && userEditedHeightFtIn) {
$wrap.find('.bmi-height-input').val(cm.toFixed(2));
} else {
cm = parseFloat($wrap.find('.bmi-height-input').val()); // Keep original
}
}
// === BMI Calculation ===
const bmi = calcBMI(kg, cm);
console.log('BMI input changed:', {kg, cm, bmi});
$wrap.find('.bmi-calc-value').text(bmi || '--');
$wrap.find('.bmi-calc-hidden').val(bmi);
// Reset flags
userEditedWeightStLb = false;
userEditedHeightFtIn = false;
}
—
### β Optional Improvements
You can also **round kg and cm to 2 decimals once when initially entered**, for cleaner UI:
$wrap.find('.bmi-weight-input').val(kg.toFixed(2)); // only when user typed kg
$wrap.find('.bmi-height-input').val(cm.toFixed(2)); // only when user typed cm
—
### β
Result:
– Toggling units doesn't change BMI anymore.
– BMI only changes if you actually **edit** stones/pounds or feet/inches.
– Fully accurate and user-friendly.
Let me know if you want this refactored into a reusable component or integrated into Gravity Forms or Elementor!
β
Prevents BMI drift when toggling units
β
Preserves the original `kg` and `cm` values unless the user manually edits
β
Rounds properly for UI display only
β
Uses tracking flags to avoid unnecessary recalculations
—
### β Full Working Code:
jQuery(function ($) {
let userEditedWeightStLb = false;
let userEditedHeightFtIn = false;
function kgToStLb(kg) {
const st = Math.floor(kg * 2.20462 / 14);
const lb = (kg * 2.20462) - (st * 14);
return { st: st, lb: Math.round(lb * 100) / 100 };
}
function stLbToKg(st, lb) {
return (parseFloat(st) * 6.35029) + (parseFloat(lb) * 0.453592);
}
function cmToFtIn(cm) {
const totalIn = cm / 2.54;
const ft = Math.floor(totalIn / 12);
const inch = totalIn - (ft * 12);
return { ft: ft, inch: Math.round(inch * 100) / 100 };
}
function ftInToCm(ft, inch) {
return (parseFloat(ft) * 30.48) + (parseFloat(inch) * 2.54);
}
function calcBMI(kg, cm) {
if (!kg || !cm) return '';
const m = cm / 100;
const bmi = kg / (m * m);
return (bmi > 0 && isFinite(bmi)) ? bmi.toFixed(1) : '';
}
function updateBMI($wrap) {
let kg, cm;
// === Weight ===
const weightUnit = $wrap.find('input[name^=bmi_weight_unit_]:checked').val();
if (weightUnit === 'kg') {
kg = parseFloat($wrap.find('.bmi-weight-input').val());
if (!isNaN(kg)) {
const stlb = kgToStLb(kg);
$wrap.find('.bmi-weight-stones').val(stlb.st);
$wrap.find('.bmi-weight-pounds').val(stlb.lb);
}
} else {
const st = parseFloat($wrap.find('.bmi-weight-stones').val()) || 0;
const lb = parseFloat($wrap.find('.bmi-weight-pounds').val()) || 0;
const convertedKg = stLbToKg(st, lb);
if (userEditedWeightStLb && !isNaN(convertedKg)) {
kg = convertedKg;
$wrap.find('.bmi-weight-input').val(kg.toFixed(2));
} else {
kg = parseFloat($wrap.find('.bmi-weight-input').val());
}
}
// === Height ===
const heightUnit = $wrap.find('input[name^=bmi_height_unit_]:checked').val();
if (heightUnit === 'cm') {
cm = parseFloat($wrap.find('.bmi-height-input').val());
if (!isNaN(cm)) {
const ftin = cmToFtIn(cm);
$wrap.find('.bmi-height-feet').val(ftin.ft);
$wrap.find('.bmi-height-inches').val(ftin.inch);
}
} else {
const ft = parseFloat($wrap.find('.bmi-height-feet').val()) || 0;
const inch = parseFloat($wrap.find('.bmi-height-inches').val()) || 0;
const convertedCm = ftInToCm(ft, inch);
if (userEditedHeightFtIn && !isNaN(convertedCm)) {
cm = convertedCm;
$wrap.find('.bmi-height-input').val(cm.toFixed(2));
} else {
cm = parseFloat($wrap.find('.bmi-height-input').val());
}
}
// === BMI ===
const bmi = calcBMI(kg, cm);
console.log('BMI input changed:', { kg, cm, bmi });
$wrap.find('.bmi-calc-value').text(bmi || '--');
$wrap.find('.bmi-calc-hidden').val(bmi);
// Reset user input flags
userEditedWeightStLb = false;
userEditedHeightFtIn = false;
}
// === Track manual edits ===
$(document).on('input', '.bmi-weight-stones, .bmi-weight-pounds', function () {
userEditedWeightStLb = true;
});
$(document).on('input', '.bmi-height-feet, .bmi-height-inches', function () {
userEditedHeightFtIn = true;
});
// === Trigger BMI update on input ===
$(document).on('input change', '.bmi-calc-wrap input', function () {
const $wrap = $(this).closest('.bmi-calc-wrap');
updateBMI($wrap);
});
// === Toggle weight units ===
$(document).on('change', 'input[name^=bmi_weight_unit_]', function () {
const $wrap = $(this).closest('.bmi-calc-wrap');
if ($(this).val() === 'st_lb') {
$wrap.find('.bmi-weight-stlb').show();
$wrap.find('.bmi-weight-kg').hide();
} else {
$wrap.find('.bmi-weight-stlb').hide();
$wrap.find('.bmi-weight-kg').show();
}
updateBMI($wrap);
});
// === Toggle height units ===
$(document).on('change', 'input[name^=bmi_height_unit_]', function () {
const $wrap = $(this).closest('.bmi-calc-wrap');
if ($(this).val() === 'ft_in') {
$wrap.find('.bmi-height-ftin').show();
$wrap.find('.bmi-height-cm').hide();
} else {
$wrap.find('.bmi-height-ftin').hide();
$wrap.find('.bmi-height-cm').show();
}
updateBMI($wrap);
});
// === Initial state setup ===
$('.bmi-calc-wrap').each(function () {
const $wrap = $(this);
// Show/hide fields based on checked units
if ($wrap.find('input[name^=bmi_weight_unit_]:checked').val() === 'st_lb') {
$wrap.find('.bmi-weight-stlb').show();
$wrap.find('.bmi-weight-kg').hide();
}
if ($wrap.find('input[name^=bmi_height_unit_]:checked').val() === 'ft_in') {
$wrap.find('.bmi-height-ftin').show();
$wrap.find('.bmi-height-cm').hide();
}
updateBMI($wrap);
});
});
—
### β
What this Fixes:
– No more BMI drift on toggling units
– Preserves exact entered kg/cm unless user changes st/lb or ft/in
– Precise 2 decimal place rounding only for display, not logic
– Manual changes only trigger recalculation, not just switching units
Let me know if you want this code modularized or integrated into WordPress/Elementor/Gravity Forms.