Javascript,将复选框与JSON匹配



我有:

  • 许多复选框
  • 要提交的按钮
  • JSON字符串对象
  • 一个函数,用于检查选中了哪些复选框,并在警报或console.log中返回它们的值,在我的提交按钮上有一个evenlistener
  • 输出DIV

如何将从检查复选框的函数中获得的值与JSON字符串对象中的值进行比较,并将其回显到输出DIV中?假设我检查了"奶酪"one_answers"大蒜"框,并期望收到以下输出:

  • 食谱1:奶酪、番茄、大蒜
  • 食谱2:奶酪、土豆、梅奥、牛肉、大蒜、黄油

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>

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

您可以将您的食谱数组筛选为仅包含所有选定成分的食谱,如下所示:

let filtered = recipes.filter((recipe) => {
return selectedCheckBoxes.every((selected) => {
return recipe.ingredients.some((ingredient) => {
return ingredient['ingredient'] === selected;
});
});
});

因此,对于每一个食谱,我们都会检查食谱中是否包含每个选定的成分。在这种情况下:

  • filter():过滤掉任何不包含所有选定成分的配方
  • every():检查每个选择的成分是否都在filter()评估的当前配方中
  • some():检查配方中的某些成分是否等于every()正在评估的当前选择成分

我编辑了你的小提琴,这样你就可以看到它在工作:https://jsfiddle.net/byce6vwu/1/

编辑

您可以像这样将返回的数组转换为html(我还将输出div更改为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;

我编辑了小提琴:https://jsfiddle.net/ys0qofgm/

因此,对于数组中的每个成分,我们将成分对象{ingredient: "Cheese"}转换为仅一个字符串"Cheese">,并使用逗号作为分隔符连接数组中的所有元素。然后为每个配方创建一个li元素,并将配方字符串放入其中。

你觉得这个快速建议怎么样,我知道它不是很优雅:

HTML(替换为此)

<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);
});
});

这里是一个工作版本:https://jsfiddle.net/8esvh65p/

此代码将执行您想要的操作。它迭代每个成分,检查食谱集及其成分,以检查该食谱是否包括该成分。只有包含所有所选成分的配方才会返回:

//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>

以下是一种可以根据当前结构设置值的方法。请记住,在任何给定的时间都不清楚你想应用什么配方,所以下面的代码将第一个配方应用到表单中。

//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>

如果您有任何问题,请随时发表评论

我编辑了您的代码,使其更小,还添加了将返回配方的getRecipe

//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>

最新更新