129 lines
3.6 KiB
JavaScript
129 lines
3.6 KiB
JavaScript
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");
|
|
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;
|
|
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";
|
|
} |