Javascript,将复选框与 JSON 匹配

Javascript, match checkboxes with JSON

我有:

如何比较我从检查哪些复选框被选中的函数中获得的值与 JSON 字符串对象中的值,并将它们回显到输出 DIV 中?假设我选中 "Cheese" 和 "Garlic" 框,并期望收到以下输出:

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

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

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

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

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

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/

您可以将您的食谱数组过滤为仅包含所有 select 成分的食谱,如下所示:

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

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

  • filter(): 过滤掉任何不包含所有 selected 成分的食谱;
  • every(): 检查每个 select 成分是否在当前正在被 filter() 评估的配方中;
  • some(): 检查配方中的某些成分是否等于当前 select 正在被 every() 评估的成分。

我编辑了你的fiddle所以你可以看到它工作: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;

我编辑了fiddle:https://jsfiddle.net/ys0qofgm/

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

此代码将执行您想要的操作。它遍历每种成分,检查食谱集及其成分,以检查该食谱是否包含该成分。仅返回包含 所有 所选成分的食谱:

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

我编辑了你的代码并缩小了它,还添加了 getRecipe 这将 return 食谱。

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