For loop inside a select

Hello.

I need to put a for that I have done inside a select:

//Consulta a la API para obtener los tipos de recetas
//Forma de atacar al servicio REST
let xmlHttp = new XMLHttpRequest();
xmlHttp.open(
  "GET",
  "http://localhost/recetarioappweb/sistema/API/ingredientes.php",
  false
); // false for synchronous request
xmlHttp.send(null);
//console.log(xmlHttp.responseText);
 
//Convertimos en objeto
let resultadoIngredientes = JSON.parse(xmlHttp.responseText);
 
let html = "<label>Seleccione uno o varios ingredientes: </label> <br><br>";
 
for (let i = 0; i < resultadoIngredientes.length; i++) {
  html += `<div class='form-check form-check-inline'>
    <input class='form-check-input' type='checkbox' value='${resultadoIngredientes[i].id}' id='inlineCheckbox1' name='ingredientes[]'>
    <label class='form-check-label' for='inlineCheckbox1'>
      ${resultadoIngredientes[i].nombre}
    </label>
  </div>`;
}
 
document.getElementById("ingredientes").innerHTML += html;

Now the ingredients are with checkbox but I want to pass it to the select and inside the for.

But I need to display the ingredients in a select instead of a checkbox and a free text input for the quantity next to it. In addition, I also need to put an add button to add more ingredients.

If I press the button it will show me another select with another input next to it for the quantity.

The idea is to output something like this:

I have tried a thousand ways but it gives me an error, can someone help me?

Thank!!

Welcome to this forum.

Does this help?

Before considering the JS, I would start with your HTML and figure out what you need to populate.

For example

<section id='create-recipe'>
  <form id='add-ingredients'>
    <h1>Create Recipe</h1>
    <label for='recipe-name'>Recipe Name</label>
    <input type='text' name='recipe-name' id='recipe-name'>
    <h2>Add Ingredients</h2>
    <ul class='added-ingredients'>
      <li class='ingredient'>
        <fieldset>
          <div class='selection'>
            <label for='ingredient-01' class='sr-only'>First Ingredient</label>
            <select name='ingredient-01' id='ingredient-01'>
              <option value='paella-rice'>Paella Rice</option>
              <option value='tomatoes'>Tomatoes</option>
              <option value='onion'>Onion</option>
              <option value='chicken-stock'>Chicken Stock</option>
            </select>
          </div>
          <label for='quantity-01' class='sr-only'>Amount</label>
          <input type='text' class='quantity' name='quantity-01' id='quantity-01' placeholder='amount'>
        </fieldset>
      </li>
      <li class='ingredient'>
        <fieldset>
          <div class='selection'>
            <label for='ingredient-02' class='sr-only'>Second Ingredient</label>
            <select name='ingredient-02' id='ingredient-02'>
              <option value='paella-rice'>Paella Rice</option>
              <option value='tomatoes'>Tomatoes</option>
              <option value='onion'>Onion</option>
              <option value='chicken-stock'>Chicken Stock</option>
            </select>
          </div>
          <label for='quantity-02' class='sr-only'>Amount</label>
          <input type='text' class='quantity' name='quantity-02' id='quantity-02' placeholder='amount'>
        </fieldset>
      </li>
    </ul>
    <fieldset class='btn-group'>
      <button id='add-ingredient'>Add Ingredient</button>
      <button id='send-ingredients' type="submit">Send</button>
    </fieldset>
  </form>
</section>

Looking at your sample data, there appears to an ingredient id and an amount, no name. The name presumably comes from another table.

When you fetch the data, are you fetching by recipe?
e.g.
`http://localhost/recetarioappweb/sistema/API/ingredientes.php/${recipeName}`

If you change an option say from chicken to onion, are you expecting the amount to update as well. Is the amount an editable input box?

Regarding the JS I would consider using the fetch api and async/await

// standard async function for fetching json
const fetchJSON = async (url) => {
  try {
    const response = await fetch(url)
    
    if (!response.ok) {
      throw new Error(`HTTP error: ${response.status}`);
    }
    
    return await response.json()
  } catch (err) {
    console.error(err)
  }
}

const getRecipe = async (recipeName) => {
  try {
    // are you fetching a specific recipe?
    const recipe = await fetchJSON(
      `http://localhost/recetarioappweb/sistema/API/ingredientes.php/${recipeName}`
    )
    
    return recipe
  } catch(err) {
    console.error(err)
  }
}

const populateForm = async (recipeName) => {
  // destructure response
  const [name /* string */, ingredients /* array */] = await getRecipe(recipeName)
  
  ...
  }
}

You can also wrap your templates in functions. Something like this.

// returns a string option
const createOption = (ingredient) => (`
  <option value='${ingredient.name}'>${ingredient.name}</option>
`)

// ingredients.map(createOption) loops through the array
// passing each ingredient to createOption and builds an array
// of the returned values
const createOptions = (ingredients, id) => (`
    <li class='ingredient'>
        <fieldset>
          <div class='selection'>
            <label for='${id}' class='sr-only'>Second Ingredient</label>
            <select name='${id}' id='${id}'>
              ${ingredients.map(createOption).join('\n')}
            </select>
          </div>
          <label for='quantity-${id}' class='sr-only'>Amount</label>
        </fieldset>
    </li>
`)

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.