const foodSearch = document.querySelector("#food-search"); const searchEntries = document.querySelector("#search-entries"); const foodMenu = document.querySelector("#food-menu"); const summary = document.querySelector("#summary"); const summaryKcal = document.querySelector("#summary .summary-kcal"); updateSummary(); initFoodList(); foodSearch.addEventListener("input", onFoodSearched); if (foodSearch.value != "") onFoodSearched(); function initFoodList() { const dataList = document.querySelector("#food-list"); for (let food of foods) { const option = document.createElement("option"); option.setAttribute("value", food.name); dataList.appendChild(option); } } function onFoodSearched() { const food = foodSearch.value; const foodLC = food.toLowerCase(); if (food == "") { createSearchEntries([]); return; } const foodsCopy = structuredClone(foods); foodsCopy.sort((a, b) => { const aNameLC = a.name.toLowerCase(); const bNameLC = b.name.toLowerCase(); const ainc = aNameLC.includes(foodLC); const binc = bNameLC.includes(foodLC); if (ainc && binc) { return 0; } else if (ainc) { return -1; } else if (binc) { return 1; } const distA = levenshtein(foodLC, aNameLC); const distB = levenshtein(foodLC, bNameLC); return distA - distB; }) const maxDist = 10; let maxAmount = 10; let amount = 0; for (let f of foodsCopy) { const fnameLC = f.name.toLowerCase(); if (fnameLC.includes(foodLC)) { amount++; maxAmount++; continue; } const dist = levenshtein(foodLC, fnameLC); if (dist >= maxDist) break; amount++; } createSearchEntries(foodsCopy.slice(0, Math.min(amount, maxAmount, 30))); } async function createSearchEntries(foods) { const nodes = []; for (let food of foods) { const node = await JST.load("search-entry"); node.querySelector(".search-entry-name").textContent = food.name; node.querySelector(".search-entry").addEventListener("click", () => addMenuItem(food)); nodes.push(node); } searchEntries.replaceChildren(...nodes); } async function addMenuItem(food) { const alreadyAddedMenuItem = document.querySelector(`#food-menu .menu-item[data-food-name="${food.name}"]`); if (alreadyAddedMenuItem !== null) { alreadyAddedMenuItem.style.animation = "highlight 0.25s linear"; setTimeout(() => alreadyAddedMenuItem.style.animation = "", 250); return; } const node = await JST.load("menu-item"); const nodeRoot = node.querySelector(".menu-item"); const itemAmount = node.querySelector(".menu-item-amount"); const kcalAmount = node.querySelector(".menu-item-kcal-for-amount"); const score = node.querySelector(".menu-item-score"); nodeRoot.setAttribute("data-food-name", food.name); node.querySelector(".menu-item-name").textContent = food.name; node.querySelector(".menu-item-kcal").textContent = `${food.kcal} kcal/100${food.unit}`; node.querySelector(".menu-item-unit").textContent = food.unit; score.textContent = food.density.toFixed(1); score.classList.add(getScoreColor(food.density, food.unit)); node.querySelector(".menu-item-info-unit").textContent = `Nährwerte pro 100${food.unit}`; node.querySelector(".menu-item-info-energy-value").textContent = `${food.kcal}kcal`; node.querySelector(".menu-item-info-fat-value").textContent = `${food.fat}g`; node.querySelector(".menu-item-info-carbs-value").textContent = `${food.carbs}g`; node.querySelector(".menu-item-info-sugar-value").textContent = `${food.sugar}g`; node.querySelector(".menu-item-info-proteins-value").textContent = `${food.proteins}g`; node.querySelector(".menu-item-info-alc-value").textContent = `${food.alc}%`; node.querySelector(".delete-menu-item").addEventListener("click", () => { foodMenu.removeChild(nodeRoot); updateSummary(); }); const updateKcalAmount = () => { if (!/[0-9]+/.test(itemAmount.value)) { console.log("no match"); return; } const amount = parseInt(itemAmount.value); kcalAmount.textContent = parseInt(Math.round(food.kcal / 100 * amount)); updateSummary(); } itemAmount.value = 100; itemAmount.addEventListener("input", updateKcalAmount); updateKcalAmount(); foodMenu.appendChild(node); updateSummary(); } function updateSummary() { let sum = 0; for (let menuItem of foodMenu.querySelectorAll(".menu-item")) { sum += parseInt(menuItem.querySelector(".menu-item-kcal-for-amount").textContent); } summaryKcal.textContent = sum; summary.style.display = sum > 0 ? "block" : "none"; } function getScoreColor(density, unit) { switch (unit) { case "g": { if (density >= 2.4) { return "red" } else if (density >= 1.7) { return "orange" } else { return "green"; } } case "ml": { if (density >= 0.3) { return "red" } else { return "green"; } } } }