You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
5.7 KiB
JavaScript

const cookbook = document.getElementById("cookbook");
const cookbookInfo = document.getElementById("cookbookInfo");
const ingredientsContainer = document.getElementById("ingredients-container");
const activeAllButton = document.getElementById("active-all");
let selectedIngredients = new Set();
let ingredientsList = []; // list of unique ingredients
let tagList;
let recipesList;
fetch("./cms.json")
.then((response) => {
return response.json();
})
.then((data) => {
populateContents(data);
recipesInfo(data.recipes);
ingredientsTag();
showAllTags();
showSelectedRecipes();
});
function populateContents(data) {
data.recipes.forEach((recipe) => addRecipe(recipe));
recipesList = [...document.getElementsByClassName("recipe")];
}
function addRecipe(recipe) {
let card = document.createElement("div");
card.classList.add("recipe");
// INFO
let info = document.createElement("div");
info.classList.add("info");
card.appendChild(info);
let title = document.createElement("h2");
title.classList.add("title");
title.innerHTML = recipe.title; //si prende recipe come contenitore e ci butta dentro title
info.appendChild(title); //aggiungi title alle info
let description = document.createElement("div");
description.classList.add("description");
description.innerHTML = recipe.description;
info.appendChild(description);
let chef = document.createElement("div");
chef.classList.add("chef");
chef.innerHTML = recipe.chef;
info.appendChild(chef);
// INGREDIENTS
let ingredients = document.createElement("div");
ingredients.classList.add("ingredients");
let ingredientsTitle = document.createElement("h3");
ingredientsTitle.innerHTML = "Ingredients";
ingredients.appendChild(ingredientsTitle);
let ingredientsList = document.createElement("ul");
recipe.ingredients.forEach((item) => {
let ingredient = document.createElement("li");
ingredient.innerHTML = item;
ingredientsList.appendChild(ingredient);
item = item.replaceAll(" ", "-");
card.classList.add(item);
});
ingredients.appendChild(ingredientsList);
card.appendChild(ingredients);
// INSTRUCTIONS
let instructions = document.createElement("div");
instructions.classList.add("instructions");
let instructionsTitle = document.createElement("h3");
instructionsTitle.innerHTML = "Instructions";
instructions.appendChild(instructionsTitle);
let instructionsList = document.createElement("ol");
recipe.instructions.forEach((item) => {
let instruction = document.createElement("li");
instruction.innerHTML = item;
instructionsList.appendChild(instruction);
});
instructions.appendChild(instructionsList);
card.appendChild(instructions);
cookbook.appendChild(card);
}
function recipesInfo(recipes) {
let ingredients = [];
recipes.forEach((recipe) => (ingredients = [...ingredients, ...recipe.ingredients]));
let unique = [...new Set(ingredients)];
ingredientsList = Array.from(unique);
cookbookInfo.innerHTML = `There are ${recipes.length} recipes in the cookbook, with a total of ${unique.length} different ingredients`;
}
// Create tags from the ingredients list of the recipes
function ingredientsTag() {
ingredientsList.forEach((ingredient) => {
let tag = document.createElement("li");
tag.classList.add("tag");
tag.setAttribute("data-tag", ingredient);
tag.setAttribute("tabindex", 0);
tag.innerHTML = ingredient;
ingredientsContainer.appendChild(tag);
});
tagList = document.querySelectorAll("[data-tag]");
}
let allActive = true;
function conditionalToggle(element) {
if (allActive) {
tagList.forEach((tag) => {
selectedIngredients.delete(tag.getAttribute("data-tag"));
tag.classList.remove("active");
tag.setAttribute("aria-expanded", "false");
});
activeAllButton.classList.remove("active");
allActive = false;
}
// conditional toggle ecc
if (element.classList.contains("active")) {
element.classList.remove("active");
element.setAttribute("aria-expanded", "false");
selectedIngredients.delete(element.getAttribute("data-tag"));
} else {
element.classList.add("active");
element.setAttribute("aria-expanded", "true");
selectedIngredients.add(element.getAttribute("data-tag"));
}
// final check
allActive = tagList.length == selectedIngredients.size;
if (allActive) {
activeAllButton.classList.add("active");
activeAllButton.setAttribute("aria-expanded", "true");
}
}
function showAllTags() {
tagList.forEach((tag) => {
selectedIngredients.add(tag.getAttribute("data-tag"));
tag.classList.add("active");
tag.setAttribute("aria-expanded", "true");
});
allActive = true;
showSelectedRecipes();
}
function showSelectedRecipes() {
recipesList.forEach((recipe) => {
recipe.classList.remove("active");
});
selectedIngredients.forEach((ingredient) => {
//filter function
let selectedRecipes = recipesList.filter((el) => {
ingredient = ingredient.replaceAll(" ", "-");
return el.classList.contains(ingredient);
});
selectedRecipes.forEach((recipe) => {
recipe.classList.add("active");
});
});
allActiveCheck();
}
function allActiveCheck() {
if (tagList.length === selectedIngredients.size) {
allActive = true;
tagList.forEach((tag) => tag.classList.add("all"));
// categoriesContainer.firstElementChild.classList.add("active");
} else {
allActive = false;
tagList.forEach((tag) => tag.classList.remove("all"));
// categoriesContainer.firstElementChild.classList.remove("active");
}
}
// Event Listeners
ingredientsContainer.addEventListener("click", (e) => {
//if click is on a tag/LIst element, then execute conditional toggle
if (e.target.tagName === "LI") {
conditionalToggle(e.target);
showSelectedRecipes();
}
});
activeAllButton.addEventListener("click", (e) => {
activeAllButton.classList.add("active");
activeAllButton.setAttribute("aria-expanded", "true");
showAllTags();
});