Filling a dropdown list based on another dropdown list in the same html form

蹲街弑〆低调 提交于 2020-01-03 08:43:53

问题


I have an HTML form with a bunch of options inside and I'd like to change the values inside those options based on previous user selection: Let's say I have something like this:

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

Based on what the user select there I'd like to have another dropdown list after this one displaying differents values. Something like this if the user select "Apple" in the first dropdown list:

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

Something like this if he select "Banana":

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

The value and the text need to change based on the first dropdown list because bananas have a different price than apples and so on. I read a few threads about it but I wasn't really able to understand what I need to make this happen. I never touched ajax before and from what I can read here: Changing value of droplist based on the value of another dropdown list I need some basic stuff about it. Is it possible to do it just using JavaScript?


回答1:


You can achieve this using an object to hold the values and their associated dropdown's descriptions. In order to do this, you firstly need to add an event listener to your dropdown so that it will detect a change when you pick a new fruit. Using the change event listener, you can retrieve the value of the option which was selected using this.value.

Using the value from the option selected, you can proceed to get its associated dropdown's values from the object called prices (this will return an array). Once you've gotten this array, you can loop through it and "build" a string of HTML using .reduce() to place as the options for the price select tag. Once you've built this string, you can append it inside the select tag using .innerHTML which "converts" your HTML string to DOM objects (real elements rather than just text):

const 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;"}]}

const price = document.querySelector('[name=price]');
document.querySelector('[name=fruit]').addEventListener('change', function(e) {
  price.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>

If you don't feel comfortable using .reduce() you can use a regular for loop instead:

...  
let options = "";
for(obj of prices[this.value]) {
  options += '<option value="' +obj.value +'">' +obj.desc +'</option>';
}
price.innerHTML = options;
...



回答2:


Here is an attached solution using element creation and onchange event with 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>



回答3:


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>


来源:https://stackoverflow.com/questions/53410084/filling-a-dropdown-list-based-on-another-dropdown-list-in-the-same-html-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!