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:
- The second select (the filtered list of streets) appear to have the first street of the selected city chosen, even though I'm using valueAllowUnset: true. This is not reflected in the view model
- When actually choosing a street in the second select and then choosing a different city in the first select, the second select updates properly to reflect the changes in the list, but the view model does not, thereby still retaining the previously selected value (even though it's not in the list anymore). Even If I remove valueAllowUnset: true from the second select, the issue still remains.
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);
valueAllowUnset
. Just set the model value toundefined
instead of''
. – Stoned