Fixes and improvements
This commit is contained in:
parent
73c4648978
commit
374d067cf4
61
iframe.html
61
iframe.html
@ -2202,7 +2202,8 @@ const CALCULATOR_CONFIG = {
|
|||||||
energyUnit: 'kcal100g',
|
energyUnit: 'kcal100g',
|
||||||
percentage: 0,
|
percentage: 0,
|
||||||
isLocked: false,
|
isLocked: false,
|
||||||
chartType: null
|
chartType: null,
|
||||||
|
splitByMeals: false
|
||||||
};
|
};
|
||||||
this.foodSources.push(treats);
|
this.foodSources.push(treats);
|
||||||
this.renderFoodSource(treats);
|
this.renderFoodSource(treats);
|
||||||
@ -2654,6 +2655,11 @@ const CALCULATOR_CONFIG = {
|
|||||||
const container = document.getElementById('foodSources');
|
const container = document.getElementById('foodSources');
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
|
const isChart = foodSource.chartType === 'gc' || foodSource.chartType === 'kibble';
|
||||||
|
const energyReadonlyAttr = isChart ? 'readonly' : '';
|
||||||
|
const energyTitle = isChart ? 'Chart-based food: kcal locked' : 'Enter energy content';
|
||||||
|
const unitDisabledAttr = isChart ? 'disabled' : '';
|
||||||
|
|
||||||
const cardHTML = `
|
const cardHTML = `
|
||||||
<div class="dog-calculator-food-source-card" id="foodSource-${foodSource.id}">
|
<div class="dog-calculator-food-source-card" id="foodSource-${foodSource.id}">
|
||||||
<div class="dog-calculator-food-source-header">
|
<div class="dog-calculator-food-source-header">
|
||||||
@ -2664,11 +2670,11 @@ const CALCULATOR_CONFIG = {
|
|||||||
<div class="dog-calculator-input-group">
|
<div class="dog-calculator-input-group">
|
||||||
<div class="dog-calculator-form-group">
|
<div class="dog-calculator-form-group">
|
||||||
<label for="energy-${foodSource.id}">Energy Content:</label>
|
<label for="energy-${foodSource.id}">Energy Content:</label>
|
||||||
<input type="number" id="energy-${foodSource.id}" min="1" step="1" placeholder="Enter energy content" value="${foodSource.energy}">
|
<input type="number" id="energy-${foodSource.id}" ${energyReadonlyAttr} title="${energyTitle}" min="1" step="1" placeholder="Enter energy content" value="${foodSource.energy}">
|
||||||
</div>
|
</div>
|
||||||
<div class="dog-calculator-form-group">
|
<div class="dog-calculator-form-group">
|
||||||
<label for="energy-unit-${foodSource.id}">Unit:</label>
|
<label for="energy-unit-${foodSource.id}">Unit:</label>
|
||||||
<select id="energy-unit-${foodSource.id}" class="dog-calculator-unit-select">
|
<select id="energy-unit-${foodSource.id}" class="dog-calculator-unit-select" ${unitDisabledAttr} title="${isChart ? 'Chart-based food: unit locked' : 'Select energy unit'}">
|
||||||
<option value="kcal100g" ${foodSource.energyUnit === 'kcal100g' ? 'selected' : ''}>kcal/100g</option>
|
<option value="kcal100g" ${foodSource.energyUnit === 'kcal100g' ? 'selected' : ''}>kcal/100g</option>
|
||||||
<option value="kcalkg" ${foodSource.energyUnit === 'kcalkg' ? 'selected' : ''}>kcal/kg</option>
|
<option value="kcalkg" ${foodSource.energyUnit === 'kcalkg' ? 'selected' : ''}>kcal/kg</option>
|
||||||
<option value="kcalcup" ${foodSource.energyUnit === 'kcalcup' ? 'selected' : ''}>kcal/cup</option>
|
<option value="kcalcup" ${foodSource.energyUnit === 'kcalcup' ? 'selected' : ''}>kcal/cup</option>
|
||||||
@ -2729,7 +2735,7 @@ const CALCULATOR_CONFIG = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (energyInput) {
|
if (energyInput && !energyInput.hasAttribute('readonly')) {
|
||||||
energyInput.addEventListener('input', () => {
|
energyInput.addEventListener('input', () => {
|
||||||
this.updateFoodSourceData(id, 'energy', energyInput.value);
|
this.updateFoodSourceData(id, 'energy', energyInput.value);
|
||||||
// If kibble reference changed, recompute daily target
|
// If kibble reference changed, recompute daily target
|
||||||
@ -2753,7 +2759,7 @@ const CALCULATOR_CONFIG = {
|
|||||||
energyInput.addEventListener('blur', () => this.validateFoodSourceEnergy(id));
|
energyInput.addEventListener('blur', () => this.validateFoodSourceEnergy(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (energyUnitSelect) {
|
if (energyUnitSelect && !energyUnitSelect.hasAttribute('disabled')) {
|
||||||
energyUnitSelect.addEventListener('change', () => {
|
energyUnitSelect.addEventListener('change', () => {
|
||||||
this.updateFoodSourceData(id, 'energyUnit', energyUnitSelect.value);
|
this.updateFoodSourceData(id, 'energyUnit', energyUnitSelect.value);
|
||||||
if (id === this.kibbleRefId) {
|
if (id === this.kibbleRefId) {
|
||||||
@ -3365,7 +3371,7 @@ const CALCULATOR_CONFIG = {
|
|||||||
// Debug: log what unit is being used
|
// Debug: log what unit is being used
|
||||||
console.log('UpdateFoodCalculations - unit:', unit, 'unitLabel:', unitLabel);
|
console.log('UpdateFoodCalculations - unit:', unit, 'unitLabel:', unitLabel);
|
||||||
|
|
||||||
// Determine frequency suffix for display
|
// Determine frequency suffix for display (will adjust per-item below)
|
||||||
const frequencySuffix = this.showPerMeal ? '/meal' : '/day';
|
const frequencySuffix = this.showPerMeal ? '/meal' : '/day';
|
||||||
|
|
||||||
// Clear all food source errors first
|
// Clear all food source errors first
|
||||||
@ -3429,6 +3435,8 @@ const CALCULATOR_CONFIG = {
|
|||||||
const kcalPerPercent = chartedPercent > 0 ? (chartedKcal / chartedPercent) : null;
|
const kcalPerPercent = chartedPercent > 0 ? (chartedKcal / chartedPercent) : null;
|
||||||
|
|
||||||
// Second pass: finalize amounts
|
// Second pass: finalize amounts
|
||||||
|
let splitDailyTotal = 0;
|
||||||
|
let dailyOnlyTotal = 0;
|
||||||
firstPass.forEach(({ fs, energyPer100g, gramsPortion }) => {
|
firstPass.forEach(({ fs, energyPer100g, gramsPortion }) => {
|
||||||
let dailyGramsForThisFood = 0;
|
let dailyGramsForThisFood = 0;
|
||||||
let hasEnergyContent = !!(energyPer100g && energyPer100g > 0);
|
let hasEnergyContent = !!(energyPer100g && energyPer100g > 0);
|
||||||
@ -3447,12 +3455,14 @@ const CALCULATOR_CONFIG = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const displayGrams = this.showPerMeal ? dailyGramsForThisFood / this.mealsPerDay : dailyGramsForThisFood;
|
const isDailyOnly = fs.splitByMeals === false;
|
||||||
|
const displayGrams = (this.showPerMeal && !isDailyOnly) ? (dailyGramsForThisFood / this.mealsPerDay) : dailyGramsForThisFood;
|
||||||
|
|
||||||
foodBreakdowns.push({
|
foodBreakdowns.push({
|
||||||
name: fs.name,
|
name: fs.name,
|
||||||
percentage: fs.percentage,
|
percentage: fs.percentage,
|
||||||
dailyGrams: dailyGramsForThisFood,
|
dailyGrams: dailyGramsForThisFood,
|
||||||
|
isDailyOnly: isDailyOnly,
|
||||||
displayGrams: displayGrams,
|
displayGrams: displayGrams,
|
||||||
dailyCups: null,
|
dailyCups: null,
|
||||||
displayCups: null,
|
displayCups: null,
|
||||||
@ -3463,6 +3473,7 @@ const CALCULATOR_CONFIG = {
|
|||||||
foodSource: fs
|
foodSource: fs
|
||||||
});
|
});
|
||||||
totalDailyGrams += dailyGramsForThisFood;
|
totalDailyGrams += dailyGramsForThisFood;
|
||||||
|
if (isDailyOnly) dailyOnlyTotal += dailyGramsForThisFood; else splitDailyTotal += dailyGramsForThisFood;
|
||||||
if (dailyGramsForThisFood > 0) hasValidFoods = true;
|
if (dailyGramsForThisFood > 0) hasValidFoods = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3483,12 +3494,13 @@ const CALCULATOR_CONFIG = {
|
|||||||
const unitButtons = document.getElementById('unitButtons');
|
const unitButtons = document.getElementById('unitButtons');
|
||||||
if (unitButtons) unitButtons.style.display = 'none';
|
if (unitButtons) unitButtons.style.display = 'none';
|
||||||
|
|
||||||
// If we have any food sources without energy content, still show the breakdown section
|
// If we have any foods with >0% but missing energy, show warnings only for those
|
||||||
if (foodBreakdowns.length > 0) {
|
const visibleBreakdownsMissing = foodBreakdowns.filter(b => b.percentage > 0);
|
||||||
|
if (visibleBreakdownsMissing.length > 0) {
|
||||||
// Show food amounts section with warnings for missing energy content
|
// Show food amounts section with warnings for missing energy content
|
||||||
const unitLabel = unit === 'g' ? 'g' : unit === 'kg' ? 'kg' : unit === 'oz' ? 'oz' : 'lb';
|
const unitLabel = unit === 'g' ? 'g' : unit === 'kg' ? 'kg' : unit === 'oz' ? 'oz' : 'lb';
|
||||||
|
|
||||||
const foodAmountsHTML = foodBreakdowns.map(breakdown => {
|
const foodAmountsHTML = visibleBreakdownsMissing.map(breakdown => {
|
||||||
const lockIndicator = breakdown.isLocked ? '<span class="dog-calculator-lock-indicator">🔒</span>' : '';
|
const lockIndicator = breakdown.isLocked ? '<span class="dog-calculator-lock-indicator">🔒</span>' : '';
|
||||||
|
|
||||||
return `
|
return `
|
||||||
@ -3539,31 +3551,24 @@ const CALCULATOR_CONFIG = {
|
|||||||
const unitButtons = document.getElementById('unitButtons');
|
const unitButtons = document.getElementById('unitButtons');
|
||||||
if (unitButtons) unitButtons.style.display = 'flex';
|
if (unitButtons) unitButtons.style.display = 'flex';
|
||||||
|
|
||||||
// Update per-food breakdown
|
// Update per-food breakdown (show only items with >0%)
|
||||||
if (foodBreakdownList && foodBreakdowns.length > 1) {
|
const visibleBreakdowns = foodBreakdowns.filter(b => b.percentage > 0);
|
||||||
const breakdownHTML = foodBreakdowns.map(breakdown => {
|
if (foodBreakdownList && visibleBreakdowns.length > 0) {
|
||||||
|
const breakdownHTML = visibleBreakdowns.map(breakdown => {
|
||||||
let valueContent;
|
let valueContent;
|
||||||
|
// Choose per-item frequency suffix: daily-only items stay /day even in per-meal view
|
||||||
|
const itemSuffix = (this.showPerMeal && !breakdown.isDailyOnly) ? '/meal' : '/day';
|
||||||
if (breakdown.hasEnergyContent) {
|
if (breakdown.hasEnergyContent) {
|
||||||
if (unit === 'cups') {
|
if (unit === 'cups') {
|
||||||
// For cups, use the pre-calculated cups value if available
|
// For cups, use the pre-calculated cups value if available
|
||||||
if (breakdown.displayCups !== null) {
|
if (breakdown.displayCups !== null) {
|
||||||
if (breakdown.hasRange && breakdown.displayCupsMin !== breakdown.displayCupsMax) {
|
valueContent = `${this.formatNumber(breakdown.displayCups, decimals)} ${unitLabel}${itemSuffix}`;
|
||||||
valueContent = `${this.formatNumber(breakdown.displayCupsMin, decimals)}-${this.formatNumber(breakdown.displayCupsMax, decimals)} ${unitLabel}${frequencySuffix}`;
|
|
||||||
} else {
|
|
||||||
valueContent = `${this.formatNumber(breakdown.displayCups, decimals)} ${unitLabel}${frequencySuffix}`;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
valueContent = `<span class="dog-calculator-warning" title="Cups only available for foods with kcal/cup measurement">N/A</span>`;
|
valueContent = `<span class="dog-calculator-warning" title="Cups only available for foods with kcal/cup measurement">N/A</span>`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// For other units (g, kg, oz, lb)
|
// For other units (g, kg, oz, lb)
|
||||||
if (breakdown.hasRange && breakdown.displayGramsMin !== breakdown.displayGramsMax) {
|
valueContent = `${this.formatNumber(this.convertUnits(breakdown.displayGrams, unit), decimals)} ${unitLabel}${itemSuffix}`;
|
||||||
const minConverted = this.convertUnits(breakdown.displayGramsMin, unit);
|
|
||||||
const maxConverted = this.convertUnits(breakdown.displayGramsMax, unit);
|
|
||||||
valueContent = `${this.formatNumber(minConverted, decimals)}-${this.formatNumber(maxConverted, decimals)} ${unitLabel}${frequencySuffix}`;
|
|
||||||
} else {
|
|
||||||
valueContent = `${this.formatNumber(this.convertUnits(breakdown.displayGrams, unit), decimals)} ${unitLabel}${frequencySuffix}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
valueContent = `<span class="dog-calculator-warning" title="Enter energy content to calculate amount">⚠️</span>`;
|
valueContent = `<span class="dog-calculator-warning" title="Enter energy content to calculate amount">⚠️</span>`;
|
||||||
@ -3586,7 +3591,8 @@ const CALCULATOR_CONFIG = {
|
|||||||
// Generate individual food amount breakdown
|
// Generate individual food amount breakdown
|
||||||
|
|
||||||
// Update daily food value with correct units
|
// Update daily food value with correct units
|
||||||
const displayTotal = this.showPerMeal ? totalDailyGrams / this.mealsPerDay : totalDailyGrams;
|
// When per-meal view is enabled, split-only items divide by meals/day; daily-only items remain as daily totals
|
||||||
|
const displayTotal = this.showPerMeal ? (splitDailyTotal / this.mealsPerDay + dailyOnlyTotal) : (splitDailyTotal + dailyOnlyTotal);
|
||||||
let convertedTotal;
|
let convertedTotal;
|
||||||
let totalDisplayText;
|
let totalDisplayText;
|
||||||
|
|
||||||
@ -3653,7 +3659,8 @@ const CALCULATOR_CONFIG = {
|
|||||||
dailyFoodValue.textContent = totalDisplayText;
|
dailyFoodValue.textContent = totalDisplayText;
|
||||||
|
|
||||||
// Build HTML for individual food amounts
|
// Build HTML for individual food amounts
|
||||||
const foodAmountsHTML = foodBreakdowns.map(breakdown => {
|
const foodAmountsVisible = foodBreakdowns.filter(b => b.percentage > 0);
|
||||||
|
const foodAmountsHTML = foodAmountsVisible.map(breakdown => {
|
||||||
const lockIndicator = breakdown.isLocked ? '<span class="dog-calculator-lock-indicator">🔒</span>' : '';
|
const lockIndicator = breakdown.isLocked ? '<span class="dog-calculator-lock-indicator">🔒</span>' : '';
|
||||||
|
|
||||||
if (!breakdown.hasEnergyContent) {
|
if (!breakdown.hasEnergyContent) {
|
||||||
|
|||||||
@ -106,7 +106,8 @@
|
|||||||
energyUnit: 'kcal100g',
|
energyUnit: 'kcal100g',
|
||||||
percentage: 0,
|
percentage: 0,
|
||||||
isLocked: false,
|
isLocked: false,
|
||||||
chartType: null
|
chartType: null,
|
||||||
|
splitByMeals: false
|
||||||
};
|
};
|
||||||
this.foodSources.push(treats);
|
this.foodSources.push(treats);
|
||||||
this.renderFoodSource(treats);
|
this.renderFoodSource(treats);
|
||||||
@ -558,6 +559,11 @@
|
|||||||
const container = document.getElementById('foodSources');
|
const container = document.getElementById('foodSources');
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
|
const isChart = foodSource.chartType === 'gc' || foodSource.chartType === 'kibble';
|
||||||
|
const energyReadonlyAttr = isChart ? 'readonly' : '';
|
||||||
|
const energyTitle = isChart ? 'Chart-based food: kcal locked' : 'Enter energy content';
|
||||||
|
const unitDisabledAttr = isChart ? 'disabled' : '';
|
||||||
|
|
||||||
const cardHTML = `
|
const cardHTML = `
|
||||||
<div class="dog-calculator-food-source-card" id="foodSource-${foodSource.id}">
|
<div class="dog-calculator-food-source-card" id="foodSource-${foodSource.id}">
|
||||||
<div class="dog-calculator-food-source-header">
|
<div class="dog-calculator-food-source-header">
|
||||||
@ -568,11 +574,11 @@
|
|||||||
<div class="dog-calculator-input-group">
|
<div class="dog-calculator-input-group">
|
||||||
<div class="dog-calculator-form-group">
|
<div class="dog-calculator-form-group">
|
||||||
<label for="energy-${foodSource.id}">Energy Content:</label>
|
<label for="energy-${foodSource.id}">Energy Content:</label>
|
||||||
<input type="number" id="energy-${foodSource.id}" min="1" step="1" placeholder="Enter energy content" value="${foodSource.energy}">
|
<input type="number" id="energy-${foodSource.id}" ${energyReadonlyAttr} title="${energyTitle}" min="1" step="1" placeholder="Enter energy content" value="${foodSource.energy}">
|
||||||
</div>
|
</div>
|
||||||
<div class="dog-calculator-form-group">
|
<div class="dog-calculator-form-group">
|
||||||
<label for="energy-unit-${foodSource.id}">Unit:</label>
|
<label for="energy-unit-${foodSource.id}">Unit:</label>
|
||||||
<select id="energy-unit-${foodSource.id}" class="dog-calculator-unit-select">
|
<select id="energy-unit-${foodSource.id}" class="dog-calculator-unit-select" ${unitDisabledAttr} title="${isChart ? 'Chart-based food: unit locked' : 'Select energy unit'}">
|
||||||
<option value="kcal100g" ${foodSource.energyUnit === 'kcal100g' ? 'selected' : ''}>kcal/100g</option>
|
<option value="kcal100g" ${foodSource.energyUnit === 'kcal100g' ? 'selected' : ''}>kcal/100g</option>
|
||||||
<option value="kcalkg" ${foodSource.energyUnit === 'kcalkg' ? 'selected' : ''}>kcal/kg</option>
|
<option value="kcalkg" ${foodSource.energyUnit === 'kcalkg' ? 'selected' : ''}>kcal/kg</option>
|
||||||
<option value="kcalcup" ${foodSource.energyUnit === 'kcalcup' ? 'selected' : ''}>kcal/cup</option>
|
<option value="kcalcup" ${foodSource.energyUnit === 'kcalcup' ? 'selected' : ''}>kcal/cup</option>
|
||||||
@ -633,7 +639,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (energyInput) {
|
if (energyInput && !energyInput.hasAttribute('readonly')) {
|
||||||
energyInput.addEventListener('input', () => {
|
energyInput.addEventListener('input', () => {
|
||||||
this.updateFoodSourceData(id, 'energy', energyInput.value);
|
this.updateFoodSourceData(id, 'energy', energyInput.value);
|
||||||
// If kibble reference changed, recompute daily target
|
// If kibble reference changed, recompute daily target
|
||||||
@ -657,7 +663,7 @@
|
|||||||
energyInput.addEventListener('blur', () => this.validateFoodSourceEnergy(id));
|
energyInput.addEventListener('blur', () => this.validateFoodSourceEnergy(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (energyUnitSelect) {
|
if (energyUnitSelect && !energyUnitSelect.hasAttribute('disabled')) {
|
||||||
energyUnitSelect.addEventListener('change', () => {
|
energyUnitSelect.addEventListener('change', () => {
|
||||||
this.updateFoodSourceData(id, 'energyUnit', energyUnitSelect.value);
|
this.updateFoodSourceData(id, 'energyUnit', energyUnitSelect.value);
|
||||||
if (id === this.kibbleRefId) {
|
if (id === this.kibbleRefId) {
|
||||||
@ -1269,7 +1275,7 @@
|
|||||||
// Debug: log what unit is being used
|
// Debug: log what unit is being used
|
||||||
console.log('UpdateFoodCalculations - unit:', unit, 'unitLabel:', unitLabel);
|
console.log('UpdateFoodCalculations - unit:', unit, 'unitLabel:', unitLabel);
|
||||||
|
|
||||||
// Determine frequency suffix for display
|
// Determine frequency suffix for display (will adjust per-item below)
|
||||||
const frequencySuffix = this.showPerMeal ? '/meal' : '/day';
|
const frequencySuffix = this.showPerMeal ? '/meal' : '/day';
|
||||||
|
|
||||||
// Clear all food source errors first
|
// Clear all food source errors first
|
||||||
@ -1333,6 +1339,8 @@
|
|||||||
const kcalPerPercent = chartedPercent > 0 ? (chartedKcal / chartedPercent) : null;
|
const kcalPerPercent = chartedPercent > 0 ? (chartedKcal / chartedPercent) : null;
|
||||||
|
|
||||||
// Second pass: finalize amounts
|
// Second pass: finalize amounts
|
||||||
|
let splitDailyTotal = 0;
|
||||||
|
let dailyOnlyTotal = 0;
|
||||||
firstPass.forEach(({ fs, energyPer100g, gramsPortion }) => {
|
firstPass.forEach(({ fs, energyPer100g, gramsPortion }) => {
|
||||||
let dailyGramsForThisFood = 0;
|
let dailyGramsForThisFood = 0;
|
||||||
let hasEnergyContent = !!(energyPer100g && energyPer100g > 0);
|
let hasEnergyContent = !!(energyPer100g && energyPer100g > 0);
|
||||||
@ -1351,12 +1359,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const displayGrams = this.showPerMeal ? dailyGramsForThisFood / this.mealsPerDay : dailyGramsForThisFood;
|
const isDailyOnly = fs.splitByMeals === false;
|
||||||
|
const displayGrams = (this.showPerMeal && !isDailyOnly) ? (dailyGramsForThisFood / this.mealsPerDay) : dailyGramsForThisFood;
|
||||||
|
|
||||||
foodBreakdowns.push({
|
foodBreakdowns.push({
|
||||||
name: fs.name,
|
name: fs.name,
|
||||||
percentage: fs.percentage,
|
percentage: fs.percentage,
|
||||||
dailyGrams: dailyGramsForThisFood,
|
dailyGrams: dailyGramsForThisFood,
|
||||||
|
isDailyOnly: isDailyOnly,
|
||||||
displayGrams: displayGrams,
|
displayGrams: displayGrams,
|
||||||
dailyCups: null,
|
dailyCups: null,
|
||||||
displayCups: null,
|
displayCups: null,
|
||||||
@ -1367,6 +1377,7 @@
|
|||||||
foodSource: fs
|
foodSource: fs
|
||||||
});
|
});
|
||||||
totalDailyGrams += dailyGramsForThisFood;
|
totalDailyGrams += dailyGramsForThisFood;
|
||||||
|
if (isDailyOnly) dailyOnlyTotal += dailyGramsForThisFood; else splitDailyTotal += dailyGramsForThisFood;
|
||||||
if (dailyGramsForThisFood > 0) hasValidFoods = true;
|
if (dailyGramsForThisFood > 0) hasValidFoods = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1387,12 +1398,13 @@
|
|||||||
const unitButtons = document.getElementById('unitButtons');
|
const unitButtons = document.getElementById('unitButtons');
|
||||||
if (unitButtons) unitButtons.style.display = 'none';
|
if (unitButtons) unitButtons.style.display = 'none';
|
||||||
|
|
||||||
// If we have any food sources without energy content, still show the breakdown section
|
// If we have any foods with >0% but missing energy, show warnings only for those
|
||||||
if (foodBreakdowns.length > 0) {
|
const visibleBreakdownsMissing = foodBreakdowns.filter(b => b.percentage > 0);
|
||||||
|
if (visibleBreakdownsMissing.length > 0) {
|
||||||
// Show food amounts section with warnings for missing energy content
|
// Show food amounts section with warnings for missing energy content
|
||||||
const unitLabel = unit === 'g' ? 'g' : unit === 'kg' ? 'kg' : unit === 'oz' ? 'oz' : 'lb';
|
const unitLabel = unit === 'g' ? 'g' : unit === 'kg' ? 'kg' : unit === 'oz' ? 'oz' : 'lb';
|
||||||
|
|
||||||
const foodAmountsHTML = foodBreakdowns.map(breakdown => {
|
const foodAmountsHTML = visibleBreakdownsMissing.map(breakdown => {
|
||||||
const lockIndicator = breakdown.isLocked ? '<span class="dog-calculator-lock-indicator">🔒</span>' : '';
|
const lockIndicator = breakdown.isLocked ? '<span class="dog-calculator-lock-indicator">🔒</span>' : '';
|
||||||
|
|
||||||
return `
|
return `
|
||||||
@ -1443,31 +1455,24 @@
|
|||||||
const unitButtons = document.getElementById('unitButtons');
|
const unitButtons = document.getElementById('unitButtons');
|
||||||
if (unitButtons) unitButtons.style.display = 'flex';
|
if (unitButtons) unitButtons.style.display = 'flex';
|
||||||
|
|
||||||
// Update per-food breakdown
|
// Update per-food breakdown (show only items with >0%)
|
||||||
if (foodBreakdownList && foodBreakdowns.length > 1) {
|
const visibleBreakdowns = foodBreakdowns.filter(b => b.percentage > 0);
|
||||||
const breakdownHTML = foodBreakdowns.map(breakdown => {
|
if (foodBreakdownList && visibleBreakdowns.length > 0) {
|
||||||
|
const breakdownHTML = visibleBreakdowns.map(breakdown => {
|
||||||
let valueContent;
|
let valueContent;
|
||||||
|
// Choose per-item frequency suffix: daily-only items stay /day even in per-meal view
|
||||||
|
const itemSuffix = (this.showPerMeal && !breakdown.isDailyOnly) ? '/meal' : '/day';
|
||||||
if (breakdown.hasEnergyContent) {
|
if (breakdown.hasEnergyContent) {
|
||||||
if (unit === 'cups') {
|
if (unit === 'cups') {
|
||||||
// For cups, use the pre-calculated cups value if available
|
// For cups, use the pre-calculated cups value if available
|
||||||
if (breakdown.displayCups !== null) {
|
if (breakdown.displayCups !== null) {
|
||||||
if (breakdown.hasRange && breakdown.displayCupsMin !== breakdown.displayCupsMax) {
|
valueContent = `${this.formatNumber(breakdown.displayCups, decimals)} ${unitLabel}${itemSuffix}`;
|
||||||
valueContent = `${this.formatNumber(breakdown.displayCupsMin, decimals)}-${this.formatNumber(breakdown.displayCupsMax, decimals)} ${unitLabel}${frequencySuffix}`;
|
|
||||||
} else {
|
|
||||||
valueContent = `${this.formatNumber(breakdown.displayCups, decimals)} ${unitLabel}${frequencySuffix}`;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
valueContent = `<span class="dog-calculator-warning" title="Cups only available for foods with kcal/cup measurement">N/A</span>`;
|
valueContent = `<span class="dog-calculator-warning" title="Cups only available for foods with kcal/cup measurement">N/A</span>`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// For other units (g, kg, oz, lb)
|
// For other units (g, kg, oz, lb)
|
||||||
if (breakdown.hasRange && breakdown.displayGramsMin !== breakdown.displayGramsMax) {
|
valueContent = `${this.formatNumber(this.convertUnits(breakdown.displayGrams, unit), decimals)} ${unitLabel}${itemSuffix}`;
|
||||||
const minConverted = this.convertUnits(breakdown.displayGramsMin, unit);
|
|
||||||
const maxConverted = this.convertUnits(breakdown.displayGramsMax, unit);
|
|
||||||
valueContent = `${this.formatNumber(minConverted, decimals)}-${this.formatNumber(maxConverted, decimals)} ${unitLabel}${frequencySuffix}`;
|
|
||||||
} else {
|
|
||||||
valueContent = `${this.formatNumber(this.convertUnits(breakdown.displayGrams, unit), decimals)} ${unitLabel}${frequencySuffix}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
valueContent = `<span class="dog-calculator-warning" title="Enter energy content to calculate amount">⚠️</span>`;
|
valueContent = `<span class="dog-calculator-warning" title="Enter energy content to calculate amount">⚠️</span>`;
|
||||||
@ -1490,7 +1495,8 @@
|
|||||||
// Generate individual food amount breakdown
|
// Generate individual food amount breakdown
|
||||||
|
|
||||||
// Update daily food value with correct units
|
// Update daily food value with correct units
|
||||||
const displayTotal = this.showPerMeal ? totalDailyGrams / this.mealsPerDay : totalDailyGrams;
|
// When per-meal view is enabled, split-only items divide by meals/day; daily-only items remain as daily totals
|
||||||
|
const displayTotal = this.showPerMeal ? (splitDailyTotal / this.mealsPerDay + dailyOnlyTotal) : (splitDailyTotal + dailyOnlyTotal);
|
||||||
let convertedTotal;
|
let convertedTotal;
|
||||||
let totalDisplayText;
|
let totalDisplayText;
|
||||||
|
|
||||||
@ -1557,7 +1563,8 @@
|
|||||||
dailyFoodValue.textContent = totalDisplayText;
|
dailyFoodValue.textContent = totalDisplayText;
|
||||||
|
|
||||||
// Build HTML for individual food amounts
|
// Build HTML for individual food amounts
|
||||||
const foodAmountsHTML = foodBreakdowns.map(breakdown => {
|
const foodAmountsVisible = foodBreakdowns.filter(b => b.percentage > 0);
|
||||||
|
const foodAmountsHTML = foodAmountsVisible.map(breakdown => {
|
||||||
const lockIndicator = breakdown.isLocked ? '<span class="dog-calculator-lock-indicator">🔒</span>' : '';
|
const lockIndicator = breakdown.isLocked ? '<span class="dog-calculator-lock-indicator">🔒</span>' : '';
|
||||||
|
|
||||||
if (!breakdown.hasEnergyContent) {
|
if (!breakdown.hasEnergyContent) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user