Заполнение раскрывающегося списка на основе другого раскрывающегося списка в той же HTML-форме - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть HTML-форма с кучей параметров внутри, и я хотел бы изменить значения внутри этих параметров на основе предыдущего выбора пользователя: допустим, у меня есть что-то вроде этого:

<select name="fruit">
    <option value="apple">Apple</option>
    <option value="banana">Banana</option>
    <option value="peach">Peach</option>
</select>

На основена том, что пользователь выбирает там, я хотел бы иметь еще один выпадающий список после этого, отображающий различные значения.Примерно так, если пользователь выберет «Apple» в первом выпадающем списке:

<select name="price">
    <option value="3">Apple 1kg 3€</option>
    <option value="5">Apple 2kg 5€</option>
    <option value="7">Apple 3kg 7€</option>
</select>

Примерно так, если он выберет «Банан»:

<select name="price">
    <option value="4">Banana 1kg 4€</option>
    <option value="7">Banana 2kg 7€</option>
    <option value="10">Banana 3kg 10€</option>
</select>

Значение и текст нужныизменить в зависимости от первого выпадающего списка, потому что бананы имеют цену, отличную от яблок и так далее.Я прочитал несколько веток об этом, но я не смог понять, что мне нужно, чтобы это произошло.Я никогда раньше не касался ajax и из того, что я могу прочитать здесь: Изменение значения раскрывающегося списка в зависимости от значения другого раскрывающегося списка Мне нужны некоторые базовые сведения об этом.Возможно ли это сделать только с помощью JavaScript?

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

Вот прикрепленное решение, использующее событие создания и обмена элементов с JQuery

// First we initialize a variable with the fruits and their prices per kg
fruitPrices = {'apple':[3, 5, 6], 'banana':[4, 7, 10]}

// Listen to changes in selected fruit
$('#fruit-selector').on('change', function(element) {
  // Clearing the price selector and getting the selected fruit
  $('#price-selector').empty()
  chosenFruit = this.value;
  
  // For each price in the fruitPrices for this fruit
  for (fruitIndex in fruitPrices[chosenFruit]) {
      // Get the price and create an option element for it
      price = fruitPrices[chosenFruit][fruitIndex];
      price_option = '<option>{0} {1}kg {2}$<option>'.replace('{0}', chosenFruit).replace('{1}', fruitIndex + 1).replace('{2}', price);
      // Add the option to the price selector
      $('#price-selector').append(price_option)
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id='fruit-selector' name="fruit">
    <option value="apple">Apple</option>
    <option value="banana">Banana</option>
    <option value="peach">Peach</option>
</select>

<select id='price-selector' name="price">

</select>
0 голосов
/ 21 ноября 2018

console.clear();

(function() {

  var fruitsField = document.querySelector('[name=fruits]')
  var amountField = document.querySelector('[name=amount]')
  var json = {};


  onReady(loadJson);
  fruitsField.addEventListener('change', populateAmount)


  function onReady(callback) {
    if (
      document.readyState === "complete" ||
      (document.readyState !== "loading" && !document.documentElement.doScroll)
    ) {
      callback();
    } else {
      document.addEventListener("DOMContentLoaded", callback);
    }  
  }

  function getSelectedFruit() {
    return fruitsField.value;
  }

  function populateFruits() {
    clearOptions(fruitsField)
    fruits = json.fruits
    for (var i in fruits) {
      addOption(fruitsField, i, fruits[i])
    }
  }

  function populateAmount() {
    clearOptions(amountField)
    var fruit = getSelectedFruit()
    fruits = json.fruits
    prices = json.prices[fruit]
    for (var i in prices) {
      addOption(amountField, i, fruits[fruit] + " " + i + "kg " + prices[i] + "€")
    }
  }

  
  // Load a json resource and start the fruit process
  function loadJson() {
    fetch('//api.jsonbin.io/b/5bf5645b746e9b593ec0e8b5')
    .then(function(response) {
      return response.json()
    })
    .then(function(response) {
      json = response
      populateFruits()
    })
    .catch(function(err) {
      console.error(err);
    })
  }


  // function loadJson() {
  //   var j = '{"fruits":{"apple":"Apples","banana":"Bananas","peach":"Peaches"},"prices":{"apple":{"1":3,"2":5,"3":7},"banana":{"1":4,"2":7,"3":10},"peach":{"1":5,"2":9,"3":13}}}'
  //   json = JSON.parse(j)
  //   populateFruits()
  // }

  function addOption(select, value, text) {
    var option = document.createElement('option')
    option.setAttribute('value', value)
    option.textContent = text
    select.appendChild(option)
  }

  function clearOptions(select) {
    var children = select.children
    var childrenToRemove = [];
    for (var i = 1; i < children.length; i++) {
      childrenToRemove.push(children[i])
    }
    for (var i = 0; i < childrenToRemove.length; i++) {
      select.removeChild(childrenToRemove[i])
    }
  }

}())
<form>
  <select name="fruits" size="4">
    <option value="0">Select Fruit</option>
  </select>
  <select name="amount" size="4">
    <option value="0" >Select Amount</option>
  </select>
</form>
0 голосов
/ 21 ноября 2018

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

Используя value из выбранной опции, вы можете перейти к получению связанных раскрывающихся значений от объекта, называемого prices (это вернет массив).Получив этот массив, вы можете пройти по нему и «построить» строку HTML, используя .reduce() для размещения в качестве параметров для тега price select.Создав эту строку, вы можете добавить ее в тег select, используя .innerHTML, который «преобразует» вашу строку HTML в объекты DOM (реальные элементы, а не просто текст):

let prices = {"apple":[{value:3,desc:"Apple 1kg 3&euro;"},{value:5,desc:"Apple 2kg 5&euro;"},{value:7,desc:"Apple 3kg 7&euro;"}],
             "banana":[{value:3,desc:"Banana 2kg 3.5&euro;"},{value:5,desc:"Banana 4kg 7&euro;"},{value:7,desc:"Banana 5kg 11&euro;"}],
             "peach":[{value:3,desc:"Peach 1.5kg 3&euro;"},{value:5,desc:"Peach 3kg 6&euro;"},{value:7,desc:"Peach 4kg 7&euro;"}]}

document.getElementsByName('fruit')[0].addEventListener('change', function(e) {
  document.getElementsByName('price')[0].innerHTML = prices[this.value].reduce((acc, elem) => `${acc}<option value="${elem.value}">${elem.desc}</option>`, "");
});
<select name="fruit">
  <option value="apple">Apple</option>
  <option value="banana">Banana</option>
  <option value="peach">Peach</option>
</select>
<br />
<select name="price">
  <option value="3">Apple 1kg 3€</option>
  <option value="5">Apple 2kg 5€</option>
  <option value="7">Apple 3kg 7€</option>
</select>

Если вам неудобно использовать .reduce(), вместо этого вы можете использовать обычный цикл for:

document.getElementsByName('fruit')[0].addEventListener('change', function(e) {  
  let options = "";
  for(obj of prices[this.value]) {
    options += '<option value="' +obj.value +'">' +obj.desc +'</option>';
  }
  document.getElementsByName('price')[0].innerHTML = options;
});
...