简体   繁体   中英

Change bootstrap multiselect values based on another select options, using jquery

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.

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())
    })
  });

在此处输入图像描述

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 stack overflow 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM