Add North American calorie unit support (kcal/kg, kcal/cup, kcal/can)
This commit is contained in:
parent
46b3560a68
commit
bb04a4d63f
@ -978,10 +978,21 @@
|
||||
</div>
|
||||
<div class="dog-calc-collapsible-content">
|
||||
<div class="dog-calc-collapsible-inner">
|
||||
<div class="dog-calc-form-group">
|
||||
<label for="foodEnergy" id="foodEnergyLabel">Food Energy Content (kcal/100g):</label>
|
||||
<input type="number" id="foodEnergy" min="1" step="1" placeholder="Enter kcal per 100g" aria-describedby="foodEnergyHelp">
|
||||
<div id="foodEnergyError" class="dog-calc-error dog-calc-hidden">Please enter a valid energy content (minimum 1 kcal/100g)</div>
|
||||
<div class="dog-calc-input-group">
|
||||
<div class="dog-calc-form-group">
|
||||
<label for="foodEnergy" id="foodEnergyLabel">Food Energy Content:</label>
|
||||
<input type="number" id="foodEnergy" min="1" step="1" placeholder="Enter energy content" aria-describedby="foodEnergyHelp">
|
||||
<div id="foodEnergyError" class="dog-calc-error dog-calc-hidden">Please enter a valid energy content</div>
|
||||
</div>
|
||||
<div class="dog-calc-form-group">
|
||||
<label for="energyUnit">Unit:</label>
|
||||
<select id="energyUnit" class="dog-calc-unit-select" aria-describedby="energyUnitHelp">
|
||||
<option value="kcal100g">kcal/100g</option>
|
||||
<option value="kcalkg">kcal/kg</option>
|
||||
<option value="kcalcup">kcal/cup</option>
|
||||
<option value="kcalcan">kcal/can</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dog-calc-results" id="dailyFoodResults" style="display: none;">
|
||||
@ -1188,6 +1199,9 @@
|
||||
foodEnergyInput.addEventListener('input', () => this.updateFoodCalculations());
|
||||
foodEnergyInput.addEventListener('blur', () => this.validateFoodEnergy());
|
||||
}
|
||||
|
||||
const energyUnitSelect = this.container.querySelector('#energyUnit');
|
||||
if (energyUnitSelect) energyUnitSelect.addEventListener('change', () => this.updateFoodCalculations());
|
||||
|
||||
if (daysInput) {
|
||||
daysInput.addEventListener('input', () => this.updateFoodCalculations());
|
||||
@ -1264,9 +1278,7 @@
|
||||
const metricLabel = this.container.querySelector('#metricLabel');
|
||||
const imperialLabel = this.container.querySelector('#imperialLabel');
|
||||
const weightLabel = this.container.querySelector('#weightLabel');
|
||||
const foodEnergyLabel = this.container.querySelector('#foodEnergyLabel');
|
||||
const weightInput = this.container.querySelector('#weight');
|
||||
const foodEnergyInput = this.container.querySelector('#foodEnergy');
|
||||
const unitSelect = this.container.querySelector('#unit');
|
||||
|
||||
if (metricLabel && imperialLabel) {
|
||||
@ -1281,12 +1293,6 @@
|
||||
weightInput.min = "0.2";
|
||||
weightInput.step = "0.1";
|
||||
}
|
||||
if (foodEnergyLabel) foodEnergyLabel.textContent = "Food Energy Content (kcal/oz):";
|
||||
if (foodEnergyInput) {
|
||||
foodEnergyInput.placeholder = "Enter kcal per oz";
|
||||
foodEnergyInput.min = "0.03";
|
||||
foodEnergyInput.step = "0.01";
|
||||
}
|
||||
if (unitSelect) {
|
||||
unitSelect.innerHTML = `
|
||||
<option value="oz">ounces (oz)</option>
|
||||
@ -1302,12 +1308,6 @@
|
||||
weightInput.min = "0.1";
|
||||
weightInput.step = "0.1";
|
||||
}
|
||||
if (foodEnergyLabel) foodEnergyLabel.textContent = "Food Energy Content (kcal/100g):";
|
||||
if (foodEnergyInput) {
|
||||
foodEnergyInput.placeholder = "Enter kcal per 100g";
|
||||
foodEnergyInput.min = "1";
|
||||
foodEnergyInput.step = "1";
|
||||
}
|
||||
if (unitSelect) {
|
||||
unitSelect.innerHTML = `
|
||||
<option value="g">grams (g)</option>
|
||||
@ -1321,7 +1321,6 @@
|
||||
|
||||
convertExistingValues() {
|
||||
const weightInput = this.container.querySelector('#weight');
|
||||
const foodEnergyInput = this.container.querySelector('#foodEnergy');
|
||||
|
||||
if (weightInput && weightInput.value) {
|
||||
const currentWeight = parseFloat(weightInput.value);
|
||||
@ -1333,17 +1332,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foodEnergyInput && foodEnergyInput.value) {
|
||||
const currentEnergy = parseFloat(foodEnergyInput.value);
|
||||
if (!isNaN(currentEnergy)) {
|
||||
if (this.isImperial) {
|
||||
foodEnergyInput.value = this.formatNumber(currentEnergy / 3.52739, 2);
|
||||
} else {
|
||||
foodEnergyInput.value = this.formatNumber(currentEnergy * 3.52739, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getWeightInKg() {
|
||||
@ -1358,12 +1346,27 @@
|
||||
|
||||
getFoodEnergyPer100g() {
|
||||
const foodEnergyInput = this.container.querySelector('#foodEnergy');
|
||||
if (!foodEnergyInput || !foodEnergyInput.value) return null;
|
||||
const energyUnitSelect = this.container.querySelector('#energyUnit');
|
||||
if (!foodEnergyInput || !foodEnergyInput.value || !energyUnitSelect) return null;
|
||||
|
||||
const energy = parseFloat(foodEnergyInput.value);
|
||||
if (isNaN(energy)) return null;
|
||||
|
||||
return this.isImperial ? energy * 3.52739 : energy;
|
||||
const unit = energyUnitSelect.value;
|
||||
|
||||
// Convert all units to kcal/100g for internal calculations
|
||||
switch (unit) {
|
||||
case 'kcal100g':
|
||||
return energy;
|
||||
case 'kcalkg':
|
||||
return energy / 10; // 1 kg = 10 × 100g
|
||||
case 'kcalcup':
|
||||
return energy / 1.2; // Assume 1 cup ≈ 120g for dry dog food
|
||||
case 'kcalcan':
|
||||
return energy / 4.5; // Assume 1 can ≈ 450g for wet dog food
|
||||
default:
|
||||
return energy;
|
||||
}
|
||||
}
|
||||
|
||||
calculateRER(weightKg) {
|
||||
@ -1418,8 +1421,34 @@
|
||||
}
|
||||
|
||||
validateFoodEnergy() {
|
||||
const energy = this.container.querySelector('#foodEnergy')?.value;
|
||||
if (energy && !this.validateInput(energy, 1)) {
|
||||
const energyInput = this.container.querySelector('#foodEnergy');
|
||||
const energyUnitSelect = this.container.querySelector('#energyUnit');
|
||||
|
||||
if (!energyInput || !energyInput.value) {
|
||||
this.showError('foodEnergyError', false);
|
||||
return;
|
||||
}
|
||||
|
||||
const energy = parseFloat(energyInput.value);
|
||||
const unit = energyUnitSelect?.value || 'kcal100g';
|
||||
|
||||
let minValue = 1;
|
||||
switch (unit) {
|
||||
case 'kcal100g':
|
||||
minValue = 1;
|
||||
break;
|
||||
case 'kcalkg':
|
||||
minValue = 10;
|
||||
break;
|
||||
case 'kcalcup':
|
||||
minValue = 50;
|
||||
break;
|
||||
case 'kcalcan':
|
||||
minValue = 100;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!this.validateInput(energy, minValue)) {
|
||||
this.showError('foodEnergyError', true);
|
||||
} else {
|
||||
this.showError('foodEnergyError', false);
|
||||
@ -1496,7 +1525,7 @@
|
||||
this.showError('foodEnergyError', false);
|
||||
this.showError('daysError', false);
|
||||
|
||||
if (!energyPer100g || energyPer100g < 1) {
|
||||
if (!energyPer100g || energyPer100g < 0.1) {
|
||||
const foodEnergyInput = this.container.querySelector('#foodEnergy');
|
||||
if (foodEnergyInput && foodEnergyInput.value) this.showError('foodEnergyError', true);
|
||||
dailyFoodResults.style.display = 'none';
|
||||
|
||||
99
iframe.html
99
iframe.html
@ -958,10 +958,21 @@
|
||||
</div>
|
||||
<div class="dog-calculator-collapsible-content">
|
||||
<div class="dog-calculator-collapsible-inner">
|
||||
<div class="dog-calculator-form-group">
|
||||
<label for="foodEnergy" id="foodEnergyLabel">Food Energy Content (kcal/100g):</label>
|
||||
<input type="number" id="foodEnergy" min="1" step="1" placeholder="Enter kcal per 100g" aria-describedby="foodEnergyHelp">
|
||||
<div id="foodEnergyError" class="dog-calculator-error dog-calculator-hidden">Please enter a valid energy content (minimum 1 kcal/100g)</div>
|
||||
<div class="dog-calculator-input-group">
|
||||
<div class="dog-calculator-form-group">
|
||||
<label for="foodEnergy" id="foodEnergyLabel">Food Energy Content:</label>
|
||||
<input type="number" id="foodEnergy" min="1" step="1" placeholder="Enter energy content" aria-describedby="foodEnergyHelp">
|
||||
<div id="foodEnergyError" class="dog-calculator-error dog-calculator-hidden">Please enter a valid energy content</div>
|
||||
</div>
|
||||
<div class="dog-calculator-form-group">
|
||||
<label for="energyUnit">Unit:</label>
|
||||
<select id="energyUnit" class="dog-calculator-unit-select" aria-describedby="energyUnitHelp">
|
||||
<option value="kcal100g">kcal/100g</option>
|
||||
<option value="kcalkg">kcal/kg</option>
|
||||
<option value="kcalcup">kcal/cup</option>
|
||||
<option value="kcalcan">kcal/can</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dog-calculator-results" id="dailyFoodResults" style="display: none;">
|
||||
@ -1126,6 +1137,9 @@
|
||||
foodEnergyInput.addEventListener('input', () => this.updateFoodCalculations());
|
||||
foodEnergyInput.addEventListener('blur', () => this.validateFoodEnergy());
|
||||
}
|
||||
|
||||
const energyUnitSelect = document.getElementById('energyUnit');
|
||||
if (energyUnitSelect) energyUnitSelect.addEventListener('change', () => this.updateFoodCalculations());
|
||||
|
||||
if (daysInput) {
|
||||
daysInput.addEventListener('input', () => this.updateFoodCalculations());
|
||||
@ -1197,9 +1211,7 @@
|
||||
const metricLabel = document.getElementById('metricLabel');
|
||||
const imperialLabel = document.getElementById('imperialLabel');
|
||||
const weightLabel = document.getElementById('weightLabel');
|
||||
const foodEnergyLabel = document.getElementById('foodEnergyLabel');
|
||||
const weightInput = document.getElementById('weight');
|
||||
const foodEnergyInput = document.getElementById('foodEnergy');
|
||||
const unitSelect = document.getElementById('unit');
|
||||
|
||||
if (metricLabel && imperialLabel) {
|
||||
@ -1214,12 +1226,6 @@
|
||||
weightInput.min = "0.2";
|
||||
weightInput.step = "0.1";
|
||||
}
|
||||
if (foodEnergyLabel) foodEnergyLabel.textContent = "Food Energy Content (kcal/oz):";
|
||||
if (foodEnergyInput) {
|
||||
foodEnergyInput.placeholder = "Enter kcal per oz";
|
||||
foodEnergyInput.min = "0.03";
|
||||
foodEnergyInput.step = "0.01";
|
||||
}
|
||||
if (unitSelect) {
|
||||
unitSelect.innerHTML = '<option value="oz">ounces (oz)</option>' +
|
||||
'<option value="lb">pounds (lb)</option>' +
|
||||
@ -1233,12 +1239,6 @@
|
||||
weightInput.min = "0.1";
|
||||
weightInput.step = "0.1";
|
||||
}
|
||||
if (foodEnergyLabel) foodEnergyLabel.textContent = "Food Energy Content (kcal/100g):";
|
||||
if (foodEnergyInput) {
|
||||
foodEnergyInput.placeholder = "Enter kcal per 100g";
|
||||
foodEnergyInput.min = "1";
|
||||
foodEnergyInput.step = "1";
|
||||
}
|
||||
if (unitSelect) {
|
||||
unitSelect.innerHTML = '<option value="g">grams (g)</option>' +
|
||||
'<option value="kg">kilograms (kg)</option>' +
|
||||
@ -1250,7 +1250,6 @@
|
||||
|
||||
convertExistingValues() {
|
||||
const weightInput = document.getElementById('weight');
|
||||
const foodEnergyInput = document.getElementById('foodEnergy');
|
||||
|
||||
if (weightInput && weightInput.value) {
|
||||
const currentWeight = parseFloat(weightInput.value);
|
||||
@ -1262,17 +1261,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foodEnergyInput && foodEnergyInput.value) {
|
||||
const currentEnergy = parseFloat(foodEnergyInput.value);
|
||||
if (!isNaN(currentEnergy)) {
|
||||
if (this.isImperial) {
|
||||
foodEnergyInput.value = this.formatNumber(currentEnergy / 3.52739, 2);
|
||||
} else {
|
||||
foodEnergyInput.value = this.formatNumber(currentEnergy * 3.52739, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getWeightInKg() {
|
||||
@ -1287,12 +1275,27 @@
|
||||
|
||||
getFoodEnergyPer100g() {
|
||||
const foodEnergyInput = document.getElementById('foodEnergy');
|
||||
if (!foodEnergyInput || !foodEnergyInput.value) return null;
|
||||
const energyUnitSelect = document.getElementById('energyUnit');
|
||||
if (!foodEnergyInput || !foodEnergyInput.value || !energyUnitSelect) return null;
|
||||
|
||||
const energy = parseFloat(foodEnergyInput.value);
|
||||
if (isNaN(energy)) return null;
|
||||
|
||||
return this.isImperial ? energy * 3.52739 : energy;
|
||||
const unit = energyUnitSelect.value;
|
||||
|
||||
// Convert all units to kcal/100g for internal calculations
|
||||
switch (unit) {
|
||||
case 'kcal100g':
|
||||
return energy;
|
||||
case 'kcalkg':
|
||||
return energy / 10; // 1 kg = 10 × 100g
|
||||
case 'kcalcup':
|
||||
return energy / 1.2; // Assume 1 cup ≈ 120g for dry dog food
|
||||
case 'kcalcan':
|
||||
return energy / 4.5; // Assume 1 can ≈ 450g for wet dog food
|
||||
default:
|
||||
return energy;
|
||||
}
|
||||
}
|
||||
|
||||
calculateRER(weightKg) {
|
||||
@ -1351,8 +1354,34 @@
|
||||
}
|
||||
|
||||
validateFoodEnergy() {
|
||||
const energyPer100g = this.getFoodEnergyPer100g();
|
||||
if (energyPer100g !== null && energyPer100g < 1) {
|
||||
const energyInput = document.getElementById('foodEnergy');
|
||||
const energyUnitSelect = document.getElementById('energyUnit');
|
||||
|
||||
if (!energyInput || !energyInput.value) {
|
||||
this.showError('foodEnergyError', false);
|
||||
return;
|
||||
}
|
||||
|
||||
const energy = parseFloat(energyInput.value);
|
||||
const unit = energyUnitSelect?.value || 'kcal100g';
|
||||
|
||||
let minValue = 1;
|
||||
switch (unit) {
|
||||
case 'kcal100g':
|
||||
minValue = 1;
|
||||
break;
|
||||
case 'kcalkg':
|
||||
minValue = 10;
|
||||
break;
|
||||
case 'kcalcup':
|
||||
minValue = 50;
|
||||
break;
|
||||
case 'kcalcan':
|
||||
minValue = 100;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!this.validateInput(energy, minValue)) {
|
||||
this.showError('foodEnergyError', true);
|
||||
} else {
|
||||
this.showError('foodEnergyError', false);
|
||||
@ -1430,7 +1459,7 @@
|
||||
this.showError('foodEnergyError', false);
|
||||
this.showError('daysError', false);
|
||||
|
||||
if (!energyPer100g || energyPer100g < 1) {
|
||||
if (!energyPer100g || energyPer100g < 0.1) {
|
||||
const foodEnergyInput = document.getElementById('foodEnergy');
|
||||
if (foodEnergyInput && foodEnergyInput.value) this.showError('foodEnergyError', true);
|
||||
dailyFoodResults.style.display = 'none';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user