0

I have a simple form created using HTML and JS. There are 3 select elements that the options of the second and the third select elements are based on the first select option. The HTML code is below.

<div class="d-flex flex-column">
    <label>City</label>
    <select name="city" class="city" id="city-selection">
        <option selected="selected" value="">Select City</option>
        <option value="City 1">City 1</option>
        <option value="City 2">City 2</option>
        <option value="City 3">City 3</option>
        <option value="City 4">City 4</option>
        <option value="City 5">City 5</option>
        <option value="City 6">City 6</option>
        <option value="City 7">City 7</option>
    </select>
</div>
<div class="d-flex flex-column">
    <label>Hotel</label>
    <select name="hotel" class="hotel" id="hotel-selection">
        <option selected="selected" value="">Select Hotel</option>
    </select>
</div>
<div class="d-flex flex-column">
    <label>Tours</label>
    <select name="tour" class="tour" id="tour-selection" multiple="multiple">
        <option selected="selected" value="">Select Tours</option>
</select>
</div>

The first(#city-selection) and the second(#hotel-selection) select elements are just normal ones. But I changed the third(#tour-selecton) select element as a Bootstrap multi-select element. So the JS part is below.

//City 1 options
var city1Hotels = '<option selected="selected" value="">Select Hotel</option><option value="City 1 Hotel 1">City 1 Hotel 1</option>';

//City 2 options
var city2Hotels = '<option selected="selected" value="">Select Hotel</option><option value="City 2 Hotel 1">City 2 Hotel 1</option>';
var city2Tours = '<option selected="selected" value="">Select Tours</option><option value="City 2 Tour 1">City 2 Tour 1</option><option value="City 2 Tour 2">City 2 Tour 2</option>';

var cityS = $("select#city-selection");
var hotelS = $("select#hotel-selection");
var tourS = $("select#tour-selection");

//changing second and third select elements options based on first select element
$(document).ready(function(){
    cityS.on('change',function(){
        if($(this).val()=="City 1"){
            hotelS.html(city1Hotels); //for hotel results based on a city

        }
        else if($(this).val()=="City 2"){
            hotelS.html(city2Hotels); //for hotel results based on a city
            tourS.html(city2Tours); //for tour results based on a city           
        }
    });
});

//set multiselect on third select element
$(function() {
    "use strict";
    $(document).ready(function() {
        $('#tour-selection').multiselect({
            includeSelectAllOption: false,});
    });  
});

The Issue


When I select a city from #city-selection, the #hotel-selection show results properly based on the city entries. But when it comes to #tour-selection, it doesn't show me tours when I selected a city. However, if I remove the multi-select function it shows me all the tours based on the cities. But then the user can select only one option. So it's not my intention and I think the issue with the multi-select. Currently, I have used if-else to change decisions based on the cities. If someone can help me, I'll be much appreciated it!


For More information:


I used this documentation to add bootstrap multi-select. https://davidstutz.github.io/bootstrap-multiselect/
When I add custom options to the third(#tour-selection) select element using HTML to check it, the multi-select feature works properly. But decision-based selection still not working.
1
  • Make sure to make the correct answer Commented May 7, 2022 at 9:22

2 Answers 2

0

I have edited your javascript code using an array of objects to set the data for cities, hotels, and tours to make them dynamically render options

Html

  <div class="d-flex flex-column">
    <label>City</label>
    <select name="city" class="city" id="city-selection">
      <option selected="selected" value="">Select City</option>
    </select>
  </div>
  <div class="d-flex flex-column">
    <label>Hotel</label>
    <select name="hotel" class="hotel" id="hotel-selection">
      <option selected="selected" value="">Select Hotel</option>
    </select>
  </div>
  <div class="d-flex flex-column">
    <label>Tours</label>
    <select name="tour" class="tour" id="tour-selection" multiple="multiple">
      <option selected="selected" value="">Select Tours</option>
    </select>
  </div>

Javascript

  //City Options
  var cities = ["city-1", "city-2"];
  // Hotel options based on cities
  var hotels = [
    {
      city: "city-1",
      hotels: ["hotel-1", "hotel-2"],
    },
    {
      city: "city-2",
      hotels: ["hotel-1", "hotel-2"],
    },
  ];
  // Tour options based on Cities
  var tours = [
    {
      city: "city-1",
      tours: ["tour-1", "tour-2"],
    },
    {
      city: "city-2",
      tours: ["tour-1", "tour-2"],
    },
  ];

  var citySelect = $("select#city-selection");
  var hotelSelect = $("select#hotel-selection");
  var tourSelect = $("select#tour-selection");

  // render city options
  for (i in cities) {
    if (i == 0) {
      // first option with "Select City" as the selected option
      citySelect.html(
        `<option selected="selected" value="">Select City</option>`
      );
      citySelect.append(
        `<option value="${cities[i]}">${cities[i]}</option>`
      );
    } else {
      // the rest of the options
      citySelect.append(
        `<option value="${cities[i]}">${cities[i]}</option>`
      );
    }
  }

  // changing both hotel options and tour options based on selected city
  $(document).ready(function () {
    citySelect.on("change", function () {
      // render hotel options based on selected city
      for (i in hotels) {
        if ($(this).val() == hotels[i]["city"]) {
          console.log(hotels[i]["city"]);
          // first option
          hotelSelect.html(
            `<option selected="selected" value="">Select Hotels</option>`
          );
          hotels[i]["hotels"].forEach((hotel) => {
            hotelSelect.append(
              `<option value="${hotels[i]["city"]}-${hotel}">${hotels[i]["city"]}-${hotel}</option>`
            );
          });
        }
      }

      // render tour options based on selected city
      for (i in tours) {
        if ($(this).val() == tours[i]["city"]) {
          console.log(tours[i]["city"]);
          // first option
          tourSelect.html(
            `<option selected="selected" value="">Select tours</option>`
          );
          tours[i]["tours"].forEach((hotel) => {
            tourSelect.append(
              `<option value="${tours[i]["city"]}-${hotel}">${tours[i]["city"]}-${hotel}</option>`
            );
          });
        }
      }
    });

    tourSelect.on("change", function () {
      console.log($(this).val())
    })
  });

enter image description here

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your answer but still the tour options not showing when multi-select active. Otherwise, the code works perfectly.
I've added tourSelect.on("change", function () { console.log($(this).val()) }) multiple select works if you either hold Ctrl and click on the options or hold Shift to select multiple at a time. you can also drag one option to the other options to select them
Yeah, I saw that. But the user must be able to select tours as checkboxes. In my code somehow bootstrap multi-select blocks rendering appointed tour list by jquery code. I just need a solution for that issue. Thanks.
0

Finally I figure out I can't working with Bootstrap multi-select. That because of it won't let custom JS code replace it's current options in select elements. Otherwise bootstrap-multiselect is a great way to create checkboxes in select elements. There may be a way to override that. But I'm unable to find a way to do that. However I found a another method to fulfill my needs without using Bootstrap multi-select and select element. This answer contains several code lines of multiple stackoverflow answers.

Those answers are,

HTML

First I replace the select element with ul list element as shown in below code.

<div class="d-flex flex-column">
    <label>City</label>
    <select name="city" class="city" id="city-selection">
        <option selected="selected" value="">Select City</option>
        <option value="City 1">City 1</option>
        <option value="City 2">City 2</option>
        <option value="City 3">City 3</option>
        <option value="City 4">City 4</option>
        <option value="City 5">City 5</option>
        <option value="City 6">City 6</option>
        <option value="City 7">City 7</option>
    </select>
</div>
<div class="d-flex flex-column">
    <label>Hotel</label>
    <select name="hotel" class="hotel" id="hotel-selection">
        <option selected="selected" value="">Select Hotel</option>
    </select>
</div>
<div class="d-flex flex-column">
    <div id="list1" class="dropdown-check-list">
        <label>Select Tours</label>
        <span class="anchor">Select Tours</span>
        <ul class="tours" id="tour-list">
        </ul>
    </div>
</div>

CSS

CSS code for dropdown.

.dropdown-check-list {
    display: inline-block;
}

.dropdown-check-list .anchor {
    position: relative;
    cursor: pointer;
    display: inline-block;
    padding: 5px 50px 5px 10px;
    border: 1px solid #ccc;
}

.dropdown-check-list .anchor:after {
    position: absolute;
    content: "";
    border-left: 2px solid black;
    border-top: 2px solid black;
    padding: 5px;
    right: 10px;
    top: 20%;
    -moz-transform: rotate(-135deg);
    -ms-transform: rotate(-135deg);
    -o-transform: rotate(-135deg);
    -webkit-transform: rotate(-135deg);
    transform: rotate(-135deg);
}

.dropdown-check-list .anchor:active:after {
    right: 8px;
    top: 21%;
}

.dropdown-check-list ul.tours {
    padding: 2px;
    display: none;
    margin: 0;
    border: 1px solid #ccc;
    border-top: none;
}

.dropdown-check-list ul.tours li {
    list-style: none;
}

.dropdown-check-list.visible .anchor {
    color: #0094ff;
}

.dropdown-check-list.visible .tours {
    display: block;
}

JS and JQuery

var city1Tours = ["c1 Tour1","c1 Tour2"];
var city2Tours = ["c2 Tour1","c2 Tour2"];

var city1Hotels = '<option selected="selected" value="">Select Hotel</option><option value="City 1 Hotel 1">City 1 Hotel 1</option>';
var city2Hotels = '<option selected="selected" value="">Select Hotel</option><option value="City 2 Hotel 1">City 1 Hotel 1</option>';

//tour list dropdown js code
var checkList = document.getElementById('list1');
checkList.getElementsByClassName('anchor')[0].onclick = function(evt) {
if (checkList.classList.contains('visible'))
    checkList.classList.remove('visible');
else
    checkList.classList.add('visible');
}

//hotel selection based on user city decision js code
$(document).ready(function(){
    cityS.on('change',function(){
    if($(this).val()=="City 1"){
        hotelS.html(city1Hotels);
        //Tour selection based on the city
        $("#tour-list").empty();//This line clears current li contents
        $.each(city1Tours, function( key, value ) {
            $('#tour-list').append('<li>' + '<input type="checkbox" />' + value + '</li>');
        });

    }else if($(this).val()=="City 2"){
        hotelS.html(city2Hotels);
        //Tour selection based on the city
        $("#tour-list").empty();//This line clears current li contents
        $.each(city2Tours, function( key, value ) {
            $('#tour-list').append('<li>' + '<input type="checkbox" />' + value + '</li>');
        });
      }
   });
});

Hope this answer helps someone in future.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.