I have two select controls.
One is dependent on the other. For a simple example, let's assume the first displays a list of cities, while the other displays a list of streets in each city.
When the page initially loads, the select control displaying the streets is showing all the available streets. However, once the user chooses a city in the first select, the second select is filtered to display streets belonging to the selected city only.
This works OK when using the options binding, however, I need the ability to generate optgroups and options binding does not support it, so I have to use the foreach binding.
The result is that whenever a city is selected, two unintended consequences occur:
Is there any workaround to this issue? I really have to use the foreach binding instead of the options binding.
JSFiddle: https://jsfiddle.net/jfxovLna/13/
var ViewModel = function() {
var self = this;
var regionAndCityArray = [{
regionName: "Europe",
cities: [{
cityName: "London",
additionalUnimportantInformation: 100
}, {
cityName: "Paris",
additionalUnimportantInformation: 200
}]
}, {
regionName: "North America",
cities: [{
cityName: "New York",
additionalUnimportantInformation: 45
}]
}];
var cityAndStreetArray = [{
cityName: "London",
streets: [{
streetName: "Parker",
streetLength: 5
}, {
streetName: "Macklin",
streetLength: 10
}, ]
}, {
cityName: "New York",
streets: [{
streetName: "5th Avenue",
streetLength: 3
}, {
streetName: "Park Ave",
streetLength: 12
}]
}, {
cityName: "Paris",
streets: [{
streetName: "Rue de Turbigo",
streetLength: 11
}, {
streetName: "Rue aux Ours",
streetLength: 12
}]
}];
var getAvailableStreets = function() {
var availableStreets = cityAndStreetArray;
var selectedCity = self.selectedCity();
var selectedRegion = _.find(regionAndCityArray,
function(region) {
return _.find(region.cities,
function(city) {
return city.cityName === selectedCity;
});
});
if (selectedRegion == undefined) {
return availableStreets;
}
var filteredStreets = _.filter(cityAndStreetArray,
function(city) {
return city.cityName === selectedCity;
});
return filteredStreets;
}
self.availableCities = ko.observableArray(regionAndCityArray);
self.selectedCity = ko.observable();
self.availbleStreets = ko.computed(getAvailableStreets);
self.selectedStreet = ko.observable();
};
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
First, add an empty option to your select input.
<option value="">Select Street</option>
Now subscribe to the selectedCity property of your view model. Whenever it changes, programmatically set the selectedStreet to ''.
viewModel.selectedCity.subscribe(function() {
viewModel.selectedStreet('');
}, viewModel);
This way you can solve both your issues.
Made the changes in your fiddle and it works. tries to update it.
Here is a fiddle - https://jsfiddle.net/Shabi_669/w1vcjbjo/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With