Recipe Calorie Calculator
Add Custom Ingredient
Select Ingredient
Chocolate (g)
Protein Powder (g)
Peanut Butter (g)
Oats (g)
Honey (g)
Nutrition Details
Total Meal
Weight
0 g
Calories
0 kcal
Protein
0 g
Carbohydrates
0 g
Sugar
0 g
Fat
0 g
Fiber
0 g
Per Serving
Weight
0 g
Calories
0 kcal
Protein
0 g
Carbohydrates
0 g
Sugar
0 g
Fat
0 g
Fiber
0 g
// Nutritional data per 100g (approximate, based on USDA averages)
let nutritionData = JSON.parse(localStorage.getItem('nutritionData')) || {
chocolate: { calories: 535, protein: 7.9, carbs: 59.1, sugar: 47.0, fat: 29.7, fiber: 3.4, name: 'Chocolate' },
protein_powder: { calories: 400, protein: 80, carbs: 5, sugar: 1.0, fat: 7, fiber: 0, name: 'Protein Powder' },
peanut_butter: { calories: 588, protein: 25, carbs: 20, sugar: 6.0, fat: 50, fiber: 6, name: 'Peanut Butter' },
oats: { calories: 379, protein: 13.2, carbs: 66.3, sugar: 1.0, fat: 6.9, fiber: 10.6, name: 'Oats' },
honey: { calories: 304, protein: 0.3, carbs: 82.4, sugar: 82.1, fat: 0, fiber: 0.2, name: 'Honey' }
};
// Helper to show error messages
const showError = (message, targetId = 'error-message') => {
const errorDiv = document.getElementById(targetId);
if (errorDiv) {
errorDiv.textContent = message;
errorDiv.classList.remove('hidden');
setTimeout(() => errorDiv.classList.add('hidden'), 3000);
}
};
// Update ingredient dropdowns with custom ingredients
const updateIngredientDropdowns = () => {
const selects = document.querySelectorAll('.ingredient-select');
selects.forEach(select => {
const currentValue = select.value;
select.innerHTML = 'Select Ingredient';
Object.keys(nutritionData).forEach(key => {
const option = document.createElement('option');
option.value = key;
option.textContent = nutritionData[key].name + ' (g)';
select.appendChild(option);
});
select.value = currentValue;
});
};
// Save nutritionData to localStorage
const saveNutritionData = () => {
localStorage.setItem('nutritionData', JSON.stringify(nutritionData));
};
// Add custom ingredient (from nutritional label)
const addCustomIngredientButton = document.getElementById('add-custom-ingredient');
if (addCustomIngredientButton) {
addCustomIngredientButton.addEventListener('click', () => {
const name = document.getElementById('custom-name').value.trim();
const servingSize = parseFloat(document.getElementById('custom-serving-size').value) || 0;
const calories = parseFloat(document.getElementById('custom-calories').value) || 0;
const protein = parseFloat(document.getElementById('custom-protein').value) || 0;
const carbs = parseFloat(document.getElementById('custom-carbs').value) || 0;
const sugar = parseFloat(document.getElementById('custom-sugar').value) || 0;
const fat = parseFloat(document.getElementById('custom-fat').value) || 0;
const fiber = parseFloat(document.getElementById('custom-fiber').value) || 0;
if (!name) {
showError('Please enter an ingredient name.', 'custom-error');
return;
}
if (servingSize <= 0) {
showError('Serving size must be greater than 0 grams.', 'custom-error');
return;
}
if (calories {
const ingredientList = document.getElementById('ingredient-list');
if (!ingredientList) {
showError('Error: Ingredient list container not found.');
return;
}
const newIngredient = document.createElement('div');
newIngredient.className = 'ingredient flex flex-col space-y-3';
newIngredient.innerHTML = `
Select Ingredient
`;
ingredientList.appendChild(newIngredient);
updateIngredientDropdowns();
});
}
// Remove ingredient
const ingredientList = document.getElementById('ingredient-list');
if (ingredientList) {
ingredientList.addEventListener('click', (e) => {
if (e.target.classList.contains('remove-ingredient')) {
if (document.querySelectorAll('.ingredient').length > 1) {
e.target.parentElement.parentElement.remove();
} else {
showError('At least one ingredient is required.');
}
}
});
}
// Calculate nutrition
const calculateButton = document.getElementById('calculate');
if (calculateButton) {
calculateButton.addEventListener('click', () => {
let totalWeight = 0, totalCalories = 0, totalProtein = 0, totalCarbs = 0, totalSugar = 0, totalFat = 0, totalFiber = 0;
const ingredients = document.querySelectorAll('.ingredient');
const servingsInput = document.getElementById('servings');
const servings = parseFloat(servingsInput.value) || 1;
if (ingredients.length === 0) {
showError('No ingredients added.');
return;
}
if (servings {
const select = ingredient.querySelector('.ingredient-select');
const quantityInput = ingredient.querySelector('.quantity');
if (!select || !quantityInput) {
showError('Error: Ingredient input elements missing.');
return;
}
const selectValue = select.value;
const quantity = parseFloat(quantityInput.value) || 0;
if (selectValue && quantity > 0) {
const data = nutritionData[selectValue];
if (data) {
const factor = quantity / 100;
totalWeight += quantity;
totalCalories += data.calories * factor;
totalProtein += data.protein * factor;
totalCarbs += data.carbs * factor;
totalSugar += data.sugar * factor;
totalFat += data.fat * factor;
totalFiber += data.fiber * factor;
validIngredients = true;
}
}
});
if (!validIngredients) {
showError('Please select at least one ingredient with a valid quantity.');
return;
}
const results = document.getElementById('results');
if (results) {
document.getElementById('total-weight').textContent = `${totalWeight.toFixed(1)} g`;
document.getElementById('total-calories').textContent = `${totalCalories.toFixed(1)} kcal`;
document.getElementById('total-protein').textContent = `${totalProtein.toFixed(1)} g`;
document.getElementById('total-carbs').textContent = `${totalCarbs.toFixed(1)} g`;
document.getElementById('total-sugar').textContent = `${totalSugar.toFixed(1)} g`;
document.getElementById('total-fat').textContent = `${totalFat.toFixed(1)} g`;
document.getElementById('total-fiber').textContent = `${totalFiber.toFixed(1)} g`;
document.getElementById('per-serving-weight').textContent = `${(totalWeight / servings).toFixed(1)} g`;
document.getElementById('per-serving-calories').textContent = `${(totalCalories / servings).toFixed(1)} kcal`;
document.getElementById('per-serving-protein').textContent = `${(totalProtein / servings).toFixed(1)} g`;
document.getElementById('per-serving-carbs').textContent = `${(totalCarbs / servings).toFixed(1)} g`;
document.getElementById('per-serving-sugar').textContent = `${(totalSugar / servings).toFixed(1)} g`;
document.getElementById('per-serving-fat').textContent = `${(totalFat / servings).toFixed(1)} g`;
document.getElementById('per-serving-fiber').textContent = `${(totalFiber / servings).toFixed(1)} g`;
results.classList.remove('hidden');
} else {
showError('Error: Results container not found.');
}
});
}
// Prevent non-numeric input
const numericInputs = document.querySelectorAll('input[type="number"]');
numericInputs.forEach(input => {
input.addEventListener('input', (e) => {
e.target.value = e.target.value.replace(/[^0-9.]/g, '');
if (e.target.value.split('.').length > 2) {
e.target.value = e.target.value.slice(0, -1);
}
});
});
// Initialize dropdowns
updateIngredientDropdowns();