简体   繁体   English

Javascript,与JSON匹配复选框

[英]Javascript, match checkboxes with JSON

I have: 我有:

  • A number of checkboxes 一些复选框
  • A button to submit 要提交的按钮
  • A JSON string object. 一个JSON字符串对象。
  • 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. 一个函数,用于检查选中的复选框,并在我的提交按钮上使用evenlistener在alert或console.log中返回它们的值。
  • An output DIV 输出DIV

How can I compare 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? 如何比较从检查哪些复选框的函数到JSON字符串对象中的值得到的值,并将它们回显到输出DIV? Say I check the "Cheese" and "Garlic" boxes, and expect to receive the following output: 假设我检查“奶酪”和“大蒜”框,并期望收到以下输出:

  • Recipe1: Cheese, Tomato, Garlic 食谱1:奶酪,番茄,大蒜
  • Recipe2: Cheese, Potato, Mayo, Beef, Garlic, Butter 食谱2:奶酪,马铃薯,梅奥,牛肉,大蒜,黄油

The HTML: 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: 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 >>小提琴

What do you think about this quick suggestion, I know it's not very elegant: 你怎么看待这个快速的建议,我知道它不是很优雅:

HTML (replace with this) HTML(替换为此)

<ul id="output">The results end up here</ul>

JS 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.net/8esvh65p/ 这是一个工作版本: https//jsfiddle.net/8esvh65p/

You 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; filter():过滤掉任何不含所选成分的配方;
  • every(): Checks if every select ingredient is in the current recipe being evaluated by filter(); every():检查每个选择的成分是否在filter()评估的当前配方中;
  • some(): Checks if some of the recipe's ingredients is equal to the current select ingredient being evaluated by every(). some():检查一些配方的成分是否等于每个()评估的当前选择成分。

I edited your fiddle so you can see it working: https://jsfiddle.net/byce6vwu/1/ 我编辑了你的小提琴,所以你可以看到它的工作: https//jsfiddle.net/byce6vwu/1/

Edit 编辑

You can convert the returned array to html like this (i also changed the output div to an ul : 您可以将返回的数组转换为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;

I've edited the fiddle: https://jsfiddle.net/ys0qofgm/ 我编辑了小提琴: https//jsfiddle.net/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 comma as the separator. 因此,对于数组中的每个成分,我们将成分对象: {ingredient: "Cheese"}转换为字符串“Cheese”,并使用逗号作为分隔符连接数组的所有元素。 Then create a li element for each recipe, and put the recipe string inside of it. 然后为每个配方创建一个li元素,并将配方字符串放在其中。

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 comment if you have any questions 如果您有任何疑问,请随时发表评论

I edited your code and made it smaller and also added getRecipe that will return the recipes. 我编辑了你的代码并将其缩小了,并添加了将返回配方的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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM