Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 431
TheNoobUser Avatar asked Nov 21 '18 10:11

TheNoobUser


2 Answers

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(const obj of prices[this.value]) {
  options += '<option value="' +obj.value +'">' +obj.desc +'</option>';
}
price.innerHTML = options;
...
like image 103
Nick Parsons Avatar answered Nov 09 '22 07:11

Nick Parsons


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>
like image 1
Shushan Avatar answered Nov 09 '22 06:11

Shushan