代码之家  ›  专栏  ›  技术社区  ›  Streching my competence

javascript,将复选框与JSON匹配

  •  1
  • Streching my competence  · 技术社区  · 5 年前

    我有:

    • 多个复选框
    • 要提交的按钮
    • JSON字符串对象。
    • 一个函数,用于检查选中的复选框,并在alert或console.log中返回它们的值,其中evenlistener位于我的提交按钮上。
    • 输出div

    如何比较我从检查哪些复选框的函数中得到的值与JSON字符串对象中的值,并将它们回送到输出DIV中?假设我检查了“奶酪”和“大蒜”框,并期望收到以下输出:

    • 食谱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

    5 回复  |  直到 5 年前
        1
  •  1
  •   Pedro leal    5 年前

    您可以将您的一系列配方筛选为仅包含所有精选成分的配方,如:

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

    所以,对于每一个配方,我们检查 每一个 所选配料包含在配方中。在这种情况下:

    • 过滤器(): 过滤掉任何不包含所有选定成分的配方;
    • 每个(): 检查筛选()所评估的当前配方中是否有每个选定成分;
    • (): 检查配方的某些成分是否等于当前选择的每()评估的成分。

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

    编辑

    您可以像这样将返回的数组转换为HTML(我还将output 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"} 只有一个字符串 “奶酪” 并使用逗号作为分隔符联接数组的所有元素。然后创建一个 元素,并将配方字符串放入其中。

        2
  •  1
  •   Miroslav Glamuzina    5 年前

    下面是一种基于当前结构设置值的方法。请记住,您在任何给定时间都不清楚要应用什么配方,因此下面的代码将把第一个配方应用到表单中。

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

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

        3
  •  1
  •   mub    5 年前

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

    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/

        4
  •  1
  •   Nick    5 年前

    这段代码将满足您的需要。它迭代每种成分,检查一组配方及其成分,以检查该配方是否包含该成分。仅包括 全部的 所选成分返回:

    //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>
        5
  •  0
  •   Alen.Toma    5 年前

    我编辑了你的代码,把它改小了,还添加了 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>