I have:
- A number of checkboxes
- A button to submit
- A JSON string object.
- A function to check which checkboxes are checked, and return their values in an alert or console.log with an evenlistener on my submit-button.
- An output DIV
How can I pare the values I get from the function that checks which checkboxes are checked to the values in the JSON string object, and echo them into the output DIV? Say I check the "Cheese" and "Garlic" boxes, and expect to receive the following output:
- Recipe1: Cheese, Tomato, Garlic
- Recipe2: Cheese, Potato, Mayo, Beef, Garlic, Butter
The HTML:
<form action="" method="">
<input type="checkbox" value="Cheese">Cheese<br>
<input type="checkbox" value="Tomato">Tomato<br>
<input type="checkbox" value="Garlic">Garlic<br>
<input type="checkbox" value="Bacon">Bacon<br>
<input type="checkbox" value="Paprika">Paprika<br>
<input type="checkbox" value="Onion">Onion<br>
<input type="checkbox" value="Potato">Potato<br>
<input type="checkbox" value="Mayo">Mayo<br>
<input type="checkbox" value="Beef">Beef<br>
<input type="checkbox" value="Garlic">Garlic<br>
<input type="checkbox" value="Butter">Butter<br>
<input type="button" value="Get recipes" id="getRecipesButton">
</form>
<div id="output">The results end up here</div>
The JS:
//Recipes JSON-string:
var recipes = [
{
name:"recipe1",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Tomato"},
{ingredient:"Garlic"}
]
},
{
name:"recipe2",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Bacon"},
{ingredient:"Paprika"},
{ingredient:"Onion"}
]
},
{
name:"recipe3",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Potato"},
{ingredient:"Mayo"},
{ingredient:"Beef"},
{ingredient:"Garlic"},
{ingredient:"Butter"}
]
}
];
//Test to retrieve single, specific entries:
// console.log(recipes[1].ingredients[0].ingredient);
//Test to get/return the checked values of the checkboxes:
function selectedBoxes(form) {
let selectedBoxesArr = [];
let inputFields = form.getElementsByTagName('input');
let inputFieldsNumber = inputFields.length;
for(let i=0; i<inputFieldsNumber; i++) {
if(
inputFields[i].type == 'checkbox' &&
inputFields[i].checked == true
) selectedBoxesArr.push(inputFields[i].value);
}
return selectedBoxesArr;
}
var getRecipesButton = document.getElementById('getRecipesButton');
getRecipesButton.addEventListener("click", function(){
let selectedCheckBoxes = selectedBoxes(this.form);
alert(selectedCheckBoxes);
});
>>Fiddle
I have:
- A number of checkboxes
- A button to submit
- A JSON string object.
- A function to check which checkboxes are checked, and return their values in an alert or console.log with an evenlistener on my submit-button.
- An output DIV
How can I pare the values I get from the function that checks which checkboxes are checked to the values in the JSON string object, and echo them into the output DIV? Say I check the "Cheese" and "Garlic" boxes, and expect to receive the following output:
- Recipe1: Cheese, Tomato, Garlic
- Recipe2: Cheese, Potato, Mayo, Beef, Garlic, Butter
The HTML:
<form action="" method="">
<input type="checkbox" value="Cheese">Cheese<br>
<input type="checkbox" value="Tomato">Tomato<br>
<input type="checkbox" value="Garlic">Garlic<br>
<input type="checkbox" value="Bacon">Bacon<br>
<input type="checkbox" value="Paprika">Paprika<br>
<input type="checkbox" value="Onion">Onion<br>
<input type="checkbox" value="Potato">Potato<br>
<input type="checkbox" value="Mayo">Mayo<br>
<input type="checkbox" value="Beef">Beef<br>
<input type="checkbox" value="Garlic">Garlic<br>
<input type="checkbox" value="Butter">Butter<br>
<input type="button" value="Get recipes" id="getRecipesButton">
</form>
<div id="output">The results end up here</div>
The JS:
//Recipes JSON-string:
var recipes = [
{
name:"recipe1",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Tomato"},
{ingredient:"Garlic"}
]
},
{
name:"recipe2",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Bacon"},
{ingredient:"Paprika"},
{ingredient:"Onion"}
]
},
{
name:"recipe3",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Potato"},
{ingredient:"Mayo"},
{ingredient:"Beef"},
{ingredient:"Garlic"},
{ingredient:"Butter"}
]
}
];
//Test to retrieve single, specific entries:
// console.log(recipes[1].ingredients[0].ingredient);
//Test to get/return the checked values of the checkboxes:
function selectedBoxes(form) {
let selectedBoxesArr = [];
let inputFields = form.getElementsByTagName('input');
let inputFieldsNumber = inputFields.length;
for(let i=0; i<inputFieldsNumber; i++) {
if(
inputFields[i].type == 'checkbox' &&
inputFields[i].checked == true
) selectedBoxesArr.push(inputFields[i].value);
}
return selectedBoxesArr;
}
var getRecipesButton = document.getElementById('getRecipesButton');
getRecipesButton.addEventListener("click", function(){
let selectedCheckBoxes = selectedBoxes(this.form);
alert(selectedCheckBoxes);
});
>>Fiddle
Share Improve this question asked Feb 9, 2019 at 21:44 Streching my petenceStreching my petence 3812 gold badges6 silver badges23 bronze badges5 Answers
Reset to default 2You can filter your array of recipes to only the recipes that includes all the select ingredients, like this:
let filtered = recipes.filter((recipe) => {
return selectedCheckBoxes.every((selected) => {
return recipe.ingredients.some((ingredient) => {
return ingredient['ingredient'] === selected;
});
});
});
So, for each one of the recipes we check if every selected ingredient is contained in the recipe. In this case:
- filter(): Filters out any recipe that does not contain every selected ingredient;
- every(): Checks if every select ingredient is in the current recipe being evaluated by filter();
- some(): Checks if some of the recipe's ingredients is equal to the current select ingredient being evaluated by every().
I edited your fiddle so you can see it working: https://jsfiddle/byce6vwu/1/
Edit
You can convert the returned array to html like this (i also changed the output div to an ul:
let outputRecipes = '';
filtered.forEach((recipe) => {
let stringIngredients = recipe.ingredients.map((val) => {
return val.ingredient;
}).join(',');
outputRecipes += `<li>${recipe.name}: ${stringIngredients}</li>`;
});
document.getElementById('output').innerHTML = outputRecipes;
I've edited the fiddle: https://jsfiddle/ys0qofgm/
So, for each ingredient in the array, we convert the ingredient object: {ingredient: "Cheese"}
to only a string "Cheese" and join all the elements of the array using a ma as the separator. Then create a li element for each recipe, and put the recipe string inside of it.
What do you think about this quick suggestion, I know it's not very elegant:
HTML (replace with this)
<ul id="output">The results end up here</ul>
JS
var getRecipesButton = document.getElementById('getRecipesButton');
getRecipesButton.addEventListener("click", function(){
let selectedCheckBoxes = selectedBoxes(this.form);
document.getElementById("output").innerHTML = "";
var res = [];
recipes.forEach(function(r,k){
r['ingredients'].forEach(function(i,idx){
if(selectedCheckBoxes.includes(i.ingredient)) {
res.push(r);
}
});
});
// remove duplicate then display the recipe with the ingredient
res.filter(function(item, index){
return res.indexOf(item) >= index;
}).forEach(function(r){
var ingredient = r.ingredients.map(function(r) { return r.ingredient}).join(", ");
var name = r.name + " : "+ingredient ;
var ul = document.getElementById("output");
var li = document.createElement('li');
li.appendChild(document.createTextNode(name));
ul.appendChild(li);
});
});
Here a working version: https://jsfiddle/8esvh65p/
This code will do what you want. It iterates over each ingredient, checking the set of recipes and their ingredients to check if that recipe includes that ingredient. Only recipes which include all the selected ingredients are returned:
//Recipes JSON-string:
var recipes = [
{
name:"recipe1",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Tomato"},
{ingredient:"Garlic"}
]
},
{
name:"recipe2",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Bacon"},
{ingredient:"Paprika"},
{ingredient:"Onion"}
]
},
{
name:"recipe3",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Potato"},
{ingredient:"Mayo"},
{ingredient:"Beef"},
{ingredient:"Garlic"},
{ingredient:"Butter"}
]
}
];
//Test to retrieve single, specific entries:
// console.log(recipes[1].ingredients[0].ingredient);
//Test to get/return the checked values of the checkboxes:
function selectedBoxes(form) {
let selectedBoxesArr = [];
let inputFields = form.getElementsByTagName('input');
let inputFieldsNumber = inputFields.length;
for(let i=0; i<inputFieldsNumber; i++) {
if(
inputFields[i].type == 'checkbox' &&
inputFields[i].checked == true
) selectedBoxesArr.push(inputFields[i].value);
}
return selectedBoxesArr;
}
var getRecipesButton = document.getElementById('getRecipesButton');
getRecipesButton.addEventListener("click", function(){
let selectedCheckBoxes = selectedBoxes(this.form);
let output = document.getElementById('output');
let myRecipes = recipes.filter(r =>
selectedCheckBoxes.every(s =>
r.ingredients.some(i => i.ingredient == s)
)
);
output.innerHTML = myRecipes.map(v => v.name + ': ' + v.ingredients.map(i => i.ingredient).join(', ')).join('<br>');
});
<form action="" method="">
<input type="checkbox" value="Cheese">Cheese<br>
<input type="checkbox" value="Tomato">Tomato<br>
<input type="checkbox" value="Garlic">Garlic<br>
<input type="checkbox" value="Bacon">Bacon<br>
<input type="checkbox" value="Paprika">Paprika<br>
<input type="checkbox" value="Onion">Onion<br>
<input type="checkbox" value="Potato">Potato<br>
<input type="checkbox" value="Mayo">Mayo<br>
<input type="checkbox" value="Beef">Beef<br>
<input type="checkbox" value="Garlic">Garlic<br>
<input type="checkbox" value="Butter">Butter<br>
<input type="button" value="Get recipes" id="getRecipesButton">
</form>
<div id="output">The results end up here</div>
Here is a way you can set the values based on your current structure. Keep in mind, it is not clear what recipe you would like to apply at any given time, so the code below will apply the first recipe to the form.
//Recipes JSON-string:
var recipes = [{
name: "recipe1",
ingredients: [{
ingredient: "Cheese"
},
{
ingredient: "Tomato"
},
{
ingredient: "Garlic"
}
]
},
{
name: "recipe2",
ingredients: [{
ingredient: "Cheese"
},
{
ingredient: "Bacon"
},
{
ingredient: "Paprika"
},
{
ingredient: "Onion"
}
]
},
{
name: "recipe3",
ingredients: [{
ingredient: "Cheese"
},
{
ingredient: "Potato"
},
{
ingredient: "Mayo"
},
{
ingredient: "Beef"
},
{
ingredient: "Garlic"
},
{
ingredient: "Butter"
}
]
}
];
var getRecipesButton = document.getElementById('getRecipesButton');
getRecipesButton.addEventListener("click", function() {
for (let ingredient of recipes[0].ingredients) {
document.querySelector(`input[value='${ingredient.ingredient}']`).setAttribute('checked', true);
}
});
<form action="" method="">
<input type="checkbox" value="Cheese">Cheese<br>
<input type="checkbox" value="Tomato">Tomato<br>
<input type="checkbox" value="Garlic">Garlic<br>
<input type="checkbox" value="Bacon">Bacon<br>
<input type="checkbox" value="Paprika">Paprika<br>
<input type="checkbox" value="Onion">Onion<br>
<input type="checkbox" value="Potato">Potato<br>
<input type="checkbox" value="Mayo">Mayo<br>
<input type="checkbox" value="Beef">Beef<br>
<input type="checkbox" value="Garlic">Garlic<br>
<input type="checkbox" value="Butter">Butter<br>
<input type="button" value="Get recipes" id="getRecipesButton">
</form>
<div id="output">The results end up here</div>
Feel free to ment if you have any questions
I edited your code and made it smaller and also added getRecipe
that will return the recipes.
//Recipes JSON-string:
var recipes = [
{
name:"recipe1",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Tomato"},
{ingredient:"Garlic"}
]
},
{
name:"recipe2",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Bacon"},
{ingredient:"Paprika"},
{ingredient:"Onion"}
]
},
{
name:"recipe3",
ingredients:
[
{ingredient:"Cheese"},
{ingredient:"Potato"},
{ingredient:"Mayo"},
{ingredient:"Beef"},
{ingredient:"Garlic"},
{ingredient:"Butter"}
]
}
];
function selectedBoxes(form) {
let selectedBoxesArr = [];
let inputFields = form.getElementsByTagName('input');
// get all checked input values
var checked = [...inputFields].filter((item) => item.checked == true
).map((item) => item.value)
return checked;
}
// Validate the checked ingredients and get the recipes
function getRecipe(ingredients){
var recipe = [];
recipes.forEach((item)=> {
var found= false;
for(var ingredient in ingredients){
var y = ingredients[ingredient]
found= item.ingredients.filter((x) => x.ingredient.indexOf(y) != -1).length>0;
if (!found)
break;
}
if(found)
recipe.push(item.name +":"+ item.ingredients.map((x)=> x.ingredient).join(", "));
});
return recipe;
}
var getRecipesButton = document.getElementById('getRecipesButton');
getRecipesButton.addEventListener("click", function(){
let selectedCheckBoxes = selectedBoxes(this.form);
console.log(getRecipe(selectedCheckBoxes))
});
<form action="" method="">
<input type="checkbox" value="Cheese">Cheese<br>
<input type="checkbox" value="Tomato">Tomato<br>
<input type="checkbox" value="Garlic">Garlic<br>
<input type="checkbox" value="Bacon">Bacon<br>
<input type="checkbox" value="Paprika">Paprika<br>
<input type="checkbox" value="Onion">Onion<br>
<input type="checkbox" value="Potato">Potato<br>
<input type="checkbox" value="Mayo">Mayo<br>
<input type="checkbox" value="Beef">Beef<br>
<input type="checkbox" value="Garlic">Garlic<br>
<input type="checkbox" value="Butter">Butter<br>
<input type="button" value="Get recipes" id="getRecipesButton">
</form>
<div id="output">The results end up here</div>