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 >
<label>City</label>
<select name="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 >
<label>Hotel</label>
<select name="hotel" id="hotel-selection">
<option selected="selected" value="">Select Hotel</option>
</select>
</div>
<div >
<label>Tours</label>
<select name="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.
CodePudding user response:
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 >
<label>City</label>
<select name="city" id="city-selection">
<option selected="selected" value="">Select City</option>
</select>
</div>
<div >
<label>Hotel</label>
<select name="hotel" id="hotel-selection">
<option selected="selected" value="">Select Hotel</option>
</select>
</div>
<div >
<label>Tours</label>
<select name="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())
})
});
CodePudding user response:
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,
- How to create checkbox inside dropdown?
- How to replace all the <li> elements of an <ul> using JQuery?
HTML
First I replace the select element with ul list element as shown in below code.
<div >
<label>City</label>
<select name="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 >
<label>Hotel</label>
<select name="hotel" id="hotel-selection">
<option selected="selected" value="">Select Hotel</option>
</select>
</div>
<div >
<div id="list1" >
<label>Select Tours</label>
<span >Select Tours</span>
<ul 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.