Growth chart age: three boxes (yr/mo/day), any combination

Replace single text input with three number fields — years, months,
days — that all combine into fractional months. Fill any subset:
leave years blank for a newborn, leave months blank for "2 years",
enter just days for a 10-day-old.

Live hint below ("= 2 yr 5 mo (29 mo total)") still shows the
interpreted total. Parser from prior commit retained on window
for reuse elsewhere.
This commit is contained in:
Daniel 2026-04-14 03:21:27 +02:00
parent c392e73cfe
commit df592d401b
2 changed files with 27 additions and 17 deletions

View file

@ -215,8 +215,12 @@
<select id="growth-sex"><option value="">Select</option><option value="male">Male</option><option value="female">Female</option></select>
</div>
<div class="calc-field" id="growth-age-field">
<label>Age</label>
<input type="text" id="growth-age" placeholder="e.g. 2y 5m, 29 months, 3 years, 15 days" autocomplete="off">
<label>Age <span style="font-weight:400;color:var(--g500);font-size:11px;">(fill any combination)</span></label>
<div style="display:flex;gap:6px;align-items:center;">
<input type="number" id="growth-age-yr" min="0" max="20" step="1" placeholder="yr" style="flex:1;min-width:0;">
<input type="number" id="growth-age-mo" min="0" max="240" step="1" placeholder="mo" style="flex:1;min-width:0;">
<input type="number" id="growth-age-d" min="0" max="365" step="1" placeholder="d" style="flex:1;min-width:0;">
</div>
<div id="growth-age-parsed" style="font-size:11px;color:var(--g500);margin-top:4px;min-height:14px;"></div>
</div>
<div class="calc-field" id="growth-ga-field" style="display:none;">

View file

@ -1151,9 +1151,12 @@
return;
}
var rawAge = (document.getElementById('growth-age').value || '').trim();
var age = parseAgeMonths(rawAge); // age in months, may be fractional
if (age == null || isNaN(age) || age < 0) { showToast('Enter age (e.g. 2y 5m, 29 months, 15 days)', 'error'); return; }
var yr = parseFloat((document.getElementById('growth-age-yr') || {}).value) || 0;
var mo = parseFloat((document.getElementById('growth-age-mo') || {}).value) || 0;
var dy = parseFloat((document.getElementById('growth-age-d') || {}).value) || 0;
var age = yr * 12 + mo + dy / 30.4375; // age in months, fractional OK
if (!age && yr === 0 && mo === 0 && dy === 0) { showToast('Enter age (years, months, or days)', 'error'); return; }
if (age < 0) { showToast('Age cannot be negative', 'error'); return; }
if (currentGrowthType === 'wfa') {
var wt = parseFloat(document.getElementById('growth-weight').value);
@ -1252,26 +1255,29 @@
});
document.getElementById('btn-clear-growth').addEventListener('click', function() {
['growth-sex', 'growth-age', 'growth-ga', 'growth-weight', 'growth-length', 'growth-hc'].forEach(function(id) {
['growth-sex', 'growth-age-yr', 'growth-age-mo', 'growth-age-d', 'growth-ga', 'growth-weight', 'growth-length', 'growth-hc'].forEach(function(id) {
var el = document.getElementById(id); if (el) el.value = '';
});
var hint = document.getElementById('growth-age-parsed'); if (hint) hint.textContent = '';
document.getElementById('growth-result').classList.add('hidden');
});
// Live feedback as user types the age
var ageEl = document.getElementById('growth-age');
// Live feedback as the age fields change
var ageHint = document.getElementById('growth-age-parsed');
if (ageEl && ageHint) {
ageEl.addEventListener('input', function() {
var v = ageEl.value.trim();
if (!v) { ageHint.textContent = ''; return; }
var m = parseAgeMonths(v);
if (m == null || isNaN(m) || m < 0) { ageHint.textContent = 'Unrecognized format'; ageHint.style.color = '#ef4444'; return; }
ageHint.style.color = 'var(--g500)';
ageHint.textContent = formatParsedAge(m);
});
function updateAgeHint() {
if (!ageHint) return;
var yr = parseFloat((document.getElementById('growth-age-yr') || {}).value) || 0;
var mo = parseFloat((document.getElementById('growth-age-mo') || {}).value) || 0;
var dy = parseFloat((document.getElementById('growth-age-d') || {}).value) || 0;
if (!yr && !mo && !dy) { ageHint.textContent = ''; return; }
var total = yr * 12 + mo + dy / 30.4375;
ageHint.style.color = 'var(--g500)';
ageHint.textContent = formatParsedAge(total);
}
['growth-age-yr', 'growth-age-mo', 'growth-age-d'].forEach(function(id) {
var el = document.getElementById(id);
if (el) el.addEventListener('input', updateAgeHint);
});
// ═══════════════════════════════════════════════════════════
// BILIRUBIN — AAP 2022 Phototherapy + Bhutani Nomogram