Javascript, сопоставьте флажки с JSON - PullRequest
0 голосов
/ 10 февраля 2019

У меня есть:

  • Количество флажков
  • Кнопка для отправки
  • строкового объекта JSON.
  • Функция, которая проверяет, какие флажки отмечены, и возвращает их значения в alert или console.log с помощью evenlistener на моей кнопке submit.
  • Вывод 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 ]

0 голосов
/ 10 февраля 2019

Я отредактировал ваш код и сделал его меньше, а также добавил 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>
0 голосов
/ 10 февраля 2019

Этот код будет делать то, что вы хотите.Он перебирает каждый ингредиент, проверяя набор рецептов и их ингредиенты, чтобы проверить, включает ли этот рецепт этот ингредиент.Только рецепты, которые включают все выбранные ингредиенты, возвращаются:

//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>
0 голосов
/ 10 февраля 2019

Что вы думаете об этом быстром предложении, я знаю, что оно не очень элегантно:

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/

0 голосов
/ 10 февраля 2019

Вы можете отфильтровать свой набор рецептов только по рецептам, включающим все выбранные ингредиенты, например:

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

Итак, для каждого из рецептов мы проверяем, если каждый выбранный ингредиент содержится в рецепте.В этом случае:

  • filter (): Отфильтровывает любой рецепт, не содержащий каждый выбранный ингредиент;
  • каждые (): Проверяет, находится ли каждый выбранный ингредиент в текущем рецепте, оцениваемом фильтром ();
  • some (): Проверяет, равен ли какой-либо из ингредиентов рецепта текущему выбранному ингредиенту, который оцениваетсяпо каждому ().

Я отредактировал вашу скрипку, чтобы вы могли видеть, как она работает: 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"} только в строку "Сыр" и соединяем все элементы массива, используя запятую в качестве разделителя. Затем создаем li элемент для каждого рецепта и поместите в него строку рецепта.

0 голосов
/ 10 февраля 2019

Вот способ, которым вы можете установить значения на основе вашей текущей структуры.Имейте в виду, что не ясно, какой рецепт вы хотели бы применить в любой момент времени, поэтому приведенный ниже код будет применять первый рецепт к форме.

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

Не стесняйтесь комментировать, если у вас есть какие-либо вопросы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...